Compare commits

..

129 Commits

Author SHA1 Message Date
github-actions[bot]
80929711be docs: auto-update documentation based on changes in next branch
This PR was automatically generated to update documentation based on recent changes.

  Original commit: Merge pull request #1212 from eyaltoledano/ralph/main/rebase\n\n\n

  Co-authored-by: Claude <claude-assistant@anthropic.com>
2025-09-17 20:13:28 +00:00
Ralph Khreish
1a3a528bf7 Merge pull request #1212 from eyaltoledano/ralph/main/rebase 2025-09-17 22:05:13 +02:00
Ralph Khreish
c164adc6ff chore: move to tsdown (#1211)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-17 22:00:37 +02:00
Ralph Khreish
9d61e0447d fix: UI list and show (#1210) 2025-09-17 22:00:37 +02:00
Ralph Khreish
ee11b735b3 chore: fix env variables (#1204)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-17 22:00:37 +02:00
losolosol
6d978228d9 feat: added vscode start task button (#1201)
Co-authored-by: Carlos Montoya <carlos@Carloss-MacBook-Pro.local>
Co-authored-by: Carlos Montoya <los@losmontoya.com>
2025-09-17 22:00:36 +02:00
Ralph Khreish
ea9341e7af chore: fix CI p2 2025-09-17 22:00:36 +02:00
Ralph Khreish
4296e383ea chore: fix CI 2025-09-17 22:00:36 +02:00
Ralph Khreish
97b2781709 feat: add tm show (#1199) 2025-09-17 22:00:36 +02:00
Ralph Khreish
96553e4a5f chore: fix CI with new typescript setup (#1194)
Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2025-09-17 22:00:36 +02:00
Ralph Khreish
7582219365 chore: fix format 2025-09-17 22:00:35 +02:00
Ralph Khreish
84baedc3d2 feat: implement tm list remote (#1185) 2025-09-17 22:00:35 +02:00
Ralph Khreish
78da39edff chore: address oauth PR concerns (#1184) 2025-09-17 22:00:35 +02:00
Ralph Khreish
4d1416b175 feat: add oauth with remote server (#1178) 2025-09-17 22:00:35 +02:00
Ralph Khreish
dc811eb45e feat: create tm-core and apps/cli (#1093)
- add typescript
- add npm workspaces
2025-09-17 22:00:34 +02:00
Ralph Khreish
3c41a113fe chore: move to tsdown (#1211)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-17 21:55:53 +02:00
Ralph Khreish
0e8c42c7cb fix: UI list and show (#1210) 2025-09-17 15:05:33 +02:00
Ralph Khreish
799d1d2cce chore: fix env variables (#1204)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-09-13 01:34:50 +02:00
losolosol
83af314879 feat: added vscode start task button (#1201)
Co-authored-by: Carlos Montoya <carlos@Carloss-MacBook-Pro.local>
Co-authored-by: Carlos Montoya <los@losmontoya.com>
2025-09-12 05:35:57 +02:00
Ralph Khreish
dd03374496 chore: fix CI p2 2025-09-11 18:44:40 -07:00
Ralph Khreish
4ab0affba7 chore: fix CI 2025-09-11 18:35:07 -07:00
Ralph Khreish
77e1ddc237 feat: add tm show (#1199) 2025-09-12 03:34:32 +02:00
Ralph Khreish
3eeb19590a chore: fix CI with new typescript setup (#1194)
Co-authored-by: Ralph Khreish <Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2025-09-09 23:35:47 +02:00
Ralph Khreish
587745046f chore: fix format 2025-09-09 03:32:48 +02:00
Ralph Khreish
c61c73f827 feat: implement tm list remote (#1185) 2025-09-09 03:32:48 +02:00
Ralph Khreish
15900d9fd5 chore: address oauth PR concerns (#1184) 2025-09-09 03:32:48 +02:00
Ralph Khreish
7cf4004038 feat: add oauth with remote server (#1178) 2025-09-09 03:32:48 +02:00
Ralph Khreish
0f3ab00f26 feat: create tm-core and apps/cli (#1093)
- add typescript
- add npm workspaces
2025-09-09 03:32:48 +02:00
github-actions[bot]
e81040def5 Version Packages (#1189)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-09-09 03:17:22 +02:00
Ralph Khreish
597f6b03b4 Merge pull request #1164 (Release 0.26.0) 2025-09-08 22:17:30 +02:00
Ralph Khreish
a7ad4c8e92 chore: improve Claude documentation workflows (#1155) 2025-09-08 22:11:46 +02:00
Ralph Khreish
0d54747894 chore: fix CI 2025-09-08 12:46:07 -07:00
Jeremy Watt
df26c65632 fix: re-add and re-name claude code clear tm commands (#1133)
* fix: remove claude code clear tm commands

* readded taskmaster claude code commands previously removed

* Update crazy-zebras-drum.md

Updated via nudging from task rabbit - changeset now more direct and no longer mentions issues.

* claude code remove subtasks added back to assets

---------

Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: Jeremy Watt <jeremywatt@Jeremys-Mac-mini.local>
2025-09-01 11:54:17 +02:00
github-actions[bot]
e80e5bb7cd chore: rc version bump 2025-08-28 22:29:10 +00:00
Ralph Khreish
c4f92f6a0a feat: add optional feature flag for code context (#1165)
* feat: add featureFlag for codebase analysis

* chore: add changeset

* chore: run format
2025-08-29 00:28:00 +02:00
github-actions[bot]
be0c0f267c chore: rc version bump 2025-08-28 22:11:59 +00:00
Ralph Khreish
a983f75d4f Merge pull request #1167 from eyaltoledano/ralph/chore.merge.main.into.next.august
ralph/chore.merge.main.into.next.august
2025-08-29 00:10:36 +02:00
Ralph Khreish
e743aaa8c2 chore: run format 2025-08-29 00:10:05 +02:00
Ralph Khreish
16ffffaf68 Merge remote-tracking branch 'origin/main' into next-backup 2025-08-29 00:08:26 +02:00
Ralph Khreish
f254aed4a6 chore: run format 2025-08-29 00:07:34 +02:00
github-actions[bot]
dd3b47bb2b Version Packages (#1154)
* Version Packages

* chore: fix changelog

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-29 00:07:34 +02:00
Ralph Khreish
37af0f1912 feat: add codebase context capabilities to gemini-cli (#1163)
* feat: add support for claude code context

- code context for:
  - add-task
  - update-subtask
  - update-task
  - update

* feat: fix CI and format + refactor

* chore: format

* chore: fix test

* feat: add gemini-cli support for codebase context

* feat: add google cli integration and fix tests

* chore: apply requested coderabbit changes

* chore: bump gemini cli package
2025-08-28 22:44:52 +02:00
Parthy
8783708e5e Improve cross-tag move UX and safety; add MCP suggestions and CLI tips (#1135)
* docs: Auto-update and format models.md

* docs(ui,cli): remove --force from cross-tag move guidance; recommend --with-dependencies/--ignore-dependencies

- scripts/modules/ui.js: drop force tip in conflict resolution
- scripts/modules/commands.js: remove force examples from move help
- docs/cross-tag-task-movement.md: purge force mentions; add explicit with/ignore examples

* test(move): update cross-tag move tests to drop --force; assert with/ignore deps behavior and current-tag fallback

- CLI integration: remove force expectations, keep with/ignore, current-tag fallback
- Integration: remove force-path test
- Unit: add scoped traversal test, adjust fixtures to avoid id collision

* fix(move): scope dependency traversal to source tag; tag-aware ignore-dependencies filtering

- resolveDependencies: traverse only sourceTag tasks to avoid cross-tag contamination
- filter dependent IDs to those present in source tag, numeric only
- ignore-dependencies: drop deps pointing to tasks from sourceTag; keep targetTag deps

* test(mcp): ensure cross-tag move passes only with/ignore options and returns conflict suggestions

- new test: tests/unit/mcp/tools/move-task-cross-tag-options.test.js

* feat(move): add advisory tips when ignoring cross-tag dependencies; add integration test case

* feat(cli/move): improve ID collision UX for cross-tag moves\n\n- Print Next Steps tips when core returns them (e.g., after ignore-dependencies)\n- Add dedicated help block when an ID already exists in target tag

* feat(move/mcp): improve ID collision UX and suggestions\n\n- Core: include suggestions on TASK_ALREADY_EXISTS errors\n- MCP: map ID collision to TASK_ALREADY_EXISTS with suggestions\n- Tests: add MCP unit test for ID collision suggestions

* test(move/cli): print tips on ignore-dependencies results; print ID collision suggestions\n\n- CLI integration test: assert Next Steps tips printed when result.tips present\n- Integration test: assert TASK_ALREADY_EXISTS error includes suggestions payload

* chore(changeset): add changeset for cross-tag move UX improvements (CLI/MCP/core/tests)

* Add cross-tag task movement help and validation improvements

- Introduced a detailed help command for cross-tag task movement, enhancing user guidance on usage and options.
- Updated validation logic in `validateCrossTagMove` to include checks for indirect dependencies, improving accuracy in conflict detection.
- Refactored tests to ensure comprehensive coverage of new validation scenarios and error handling.
- Cleaned up documentation to reflect the latest changes in task movement functionality.

* refactor(commands): remove redundant tips printing after move operation

- Eliminated duplicate printing of tips for next steps after the move operation, streamlining the output for users.
- This change enhances clarity by ensuring tips are only displayed when relevant, improving overall user experience.

* docs(move): clarify "force move" options and improve examples

- Updated documentation to replace the deprecated "force move" concept with clear alternatives: `--with-dependencies` and `--ignore-dependencies`.
- Enhanced Scenario 3 with explicit options and improved inline comments for better readability.
- Removed confusing commented code in favor of a straightforward note in the Force Move section.

* chore: run formatter

* Update .changeset/clarify-force-move-docs.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update docs/cross-tag-task-movement.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update tests/unit/scripts/modules/task-manager/move-task-cross-tag.test.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* test(move): add test for dependency traversal scoping with --with-dependencies option

- Introduced a new test to ensure that the dependency traversal is limited to tasks from the source tag when using the --with-dependencies option, addressing potential ID collisions across tags.

* test(move): enhance tips validation in cross-tag task movement integration test

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-28 19:02:00 +02:00
Ralph Khreish
4dad2fd613 feat: add support for code context in more commands (#1162)
* feat: add support for claude code context

- code context for:
  - add-task
  - update-subtask
  - update-task
  - update

* feat: fix CI and format + refactor

* chore: format

* chore: fix broken tests

* chore: fix test
2025-08-28 18:05:31 +02:00
github-actions[bot]
4cae2991d4 Version Packages (#1154)
* Version Packages

* chore: fix changelog

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-23 00:44:25 +02:00
Ralph Khreish
0d7ff627c9 Merge pull request #1152 from eyaltoledano/next 2025-08-23 00:34:40 +02:00
Ralph Khreish
db720a954d Fix: disable streaming for parse prd (#1151)
* fix: temporarily disable streaming
2025-08-22 18:33:02 +02:00
Ben Vargas
89335578ff fix(claude-code): prevent "Right-hand side of instanceof is not an object" when SDK missing; improve CLI stability (#1146)
* fix: handle missing @anthropic-ai/claude-code SDK gracefully

Add defensive checks to prevent "Right-hand side of 'instanceof' is not an object" errors when the optional Claude Code SDK is not installed.

Changes:
- Check if AbortError exists before using instanceof
- Check if query function exists before calling it
- Provide clear error messages when SDK is missing

This fixes the issue reported by users in v0.24.0 and v0.25.0 where Task Master would crash with instanceof errors when using the claude-code provider without the SDK installed.

* chore: bump @anthropic-ai/claude-code to ^1.0.88 and regenerate lockfile
2025-08-22 17:01:34 +02:00
Ralph Khreish
781b8ef2af remove claude code mentioning 2025-08-22 17:01:34 +02:00
github-actions[bot]
7d564920b5 Version Packages (#1143)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-19 23:04:40 +02:00
Ralph Khreish
2737fbaa67 Release 0.25.0 #1134 from eyaltoledano/next
Release 0.25.0
2025-08-19 21:10:44 +02:00
Ralph Khreish
9feb8d2dbf chore: fix CI of claude code docs updater 2025-08-19 16:11:57 +02:00
Ralph Khreish
8a991587f1 chore: fix CI 2025-08-19 16:09:08 +02:00
Ralph Khreish
7ceba2f572 chore: exit pre-release mode 2025-08-19 16:01:31 +02:00
Ralph Khreish
10565f07d3 chore: run format 2025-08-19 16:00:48 +02:00
Ralph Khreish
f27ce34fe9 chore: fix changeset 2025-08-14 14:24:08 +02:00
github-actions[bot]
71be933a8d chore: rc version bump 2025-08-13 22:37:59 +00:00
Ralph Khreish
5d94f1b471 chore: add a bunch of automations (#1132)
* chore: add a bunch of automations

* chore: run format

* Update .github/scripts/auto-close-duplicates.mjs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: run format

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-14 00:36:18 +02:00
Joe Danziger
3dee60dc3d fix: update Cursor one-click install link to new URL format (#1131)
* add /en to link

* add changeset
2025-08-13 18:02:47 +02:00
Ralph Khreish
f469515228 feat: add Claude documentation updater workflow (#1130)
This commit introduces a new GitHub Actions workflow that automatically updates documentation based on changes pushed to the 'next' branch. The workflow checks for modified files, creates a new branch for documentation updates, and utilizes the Claude Code Action to analyze changes and suggest necessary documentation revisions. If updates are made, a pull request is created for review.
2025-08-13 15:10:47 +02:00
Ralph Khreish
2fd0f026d3 chore: remove pre-release CI for extension, too much work and doesn't make sense for us (#1129) 2025-08-13 15:08:55 +02:00
Joe Danziger
e3ed4d7c14 feat: CLI & MCP progress tracking for parse-prd command (#1048)
* initial cutover

* update log to debug

* update tracker to pass units

* update test to match new base tracker format

* add streamTextService mocks

* remove unused imports

* Ensure the CLI waits for async main() completion

* refactor to reduce code duplication

* update comment

* reuse function

* ensure targetTag is defined in streaming mode

* avoid throwing inside process.exit spy

* check for null

* remove reference to generate

* fix formatting

* fix textStream assignment

* ensure no division by 0

* fix jest chalk mocks

* refactor for maintainability

* Improve bar chart calculation logic for consistent visual representation

* use custom streaming error types; fix mocks

* Update streamText extraction in parse-prd.js to match actual service response

* remove check - doesn't belong here

* update mocks

* remove streaming test that wasn't really doing anything

* add comment

* make parsing logic more DRY

* fix formatting

* Fix textStream extraction to match actual service response

* fix mock

* Add a cleanup method to ensure proper resource disposal and prevent memory leaks

* debounce progress updates to reduce UI flicker during rapid updates

* Implement timeout protection for streaming operations (60-second timeout) with automatic fallback to non-streaming mode.

* clear timeout properly

* Add a maximum buffer size limit (1MB) to prevent unbounded memory growth with very large streaming responses.

* fix formatting

* remove duplicate mock

* better docs

* fix formatting

* sanitize the dynamic property name

* Fix incorrect remaining progress calculation

* Use onError callback instead of console.warn

* Remove unused chalk import

* Add missing custom validator in fallback parsing configuration

* add custom validator parameter in fallback parsing

* chore: fix package-lock.json

* chore: large code refactor

* chore: increase timeout from 1 minute to 3 minutes

* fix: refactor and fix streaming

* Merge remote-tracking branch 'origin/next' into joedanz/parse-prd-progress

* fix: cleanup and fix unit tests

* chore: fix unit tests

* chore: fix format

* chore: run format

* chore: fix weird CI unit test error

* chore: fix format

---------

Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-12 22:37:07 +02:00
Dominique Vidjanagni
fc47714340 Feat/add-kilocode-rules (#1040)
* feat: Add Kilo Code integration to TaskMaster

* feat: Add Kilo profile configuration to rule transformer tests

* refactor: Improve code formatting and consistency in Kilo profile and tests

* fix: Correct formatting of workspaces in package.json

* chore: add changeset for Kilo Code integration

* feat: add Kilo Code rules and mode configurations

- Add comprehensive rule sets for all modes (architect, ask, code, debug, orchestrator, test)
- Update .kilocodemodes configuration with mode-specific settings
- Configure MCP integration for Kilo Code profile
- Establish consistent rule structure across all modes

* refactor(kilo): simplify profile to reuse roo rules with replacements

Remove duplicate Kilo-specific rule files and assets in favor of reusing roo rules with dynamic replacements, eliminating 900+ lines of duplicated code while maintaining full Kilo functionality.

The profile now:
- Reuses ROO_MODES constant instead of maintaining separate KILO_MODES
- Applies text replacements to convert roo references to kilo
- Maps roo rule files to kilo equivalents via fileMap
- Removes all duplicate rule files from assets/kilocode directory

* refactor(kilo): restructure object literals for consistency and remove duplicate customReplacements array based on CodeRabbit's suggestion

* chore: remove disabled .mcp.json by mistake

---------

Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-12 22:35:57 +02:00
github-actions[bot]
30ae0e9a57 docs: Auto-update and format models.md 2025-08-12 17:01:24 +00:00
Ralph Khreish
95640dcde8 feat: add gpt-oss models to ollama (#1124) 2025-08-12 19:01:10 +02:00
Ralph Khreish
311b2433e2 fix: remove claude code clear tm commands (#1123) 2025-08-11 18:59:35 +02:00
Parthy
04e11b5e82 feat: implement cross-tag task movement functionality (#1088)
* feat: enhance move command with cross-tag functionality

- Updated the `move` command to allow moving tasks between different tags, including options for handling dependencies.
- Added new options: `--from-tag`, `--to-tag`, `--with-dependencies`, `--ignore-dependencies`, and `--force`.
- Implemented validation for cross-tag moves and dependency checks.
- Introduced helper functions in the dependency manager for validating and resolving cross-tag dependencies.
- Added integration and unit tests to cover new functionality and edge cases.

* fix: refactor cross-tag move logic and enhance validation

- Moved the import of `moveTasksBetweenTags` to the correct location in `commands.js` for better clarity.
- Added new helper functions in `dependency-manager.js` to improve validation and error handling for cross-tag moves.
- Enhanced existing functions to ensure proper handling of task dependencies and conflicts.
- Updated tests to cover new validation scenarios and ensure robust error messaging for invalid task IDs and tags.

* fix: improve task ID handling and error messaging in cross-tag moves

- Refactored `moveTasksBetweenTags` to normalize task IDs for comparison, ensuring consistent handling of string and numeric IDs.
- Enhanced error messages for cases where source and target tags are the same but no destination is specified.
- Updated tests to validate new behavior, including handling string dependencies correctly during cross-tag moves.
- Cleaned up existing code for better readability and maintainability.

* test: add comprehensive tests for cross-tag move and dependency validation

- Introduced new test files for `move-cross-tag` and `cross-tag-dependencies` to cover various scenarios in cross-tag task movement.
- Implemented tests for handling task movement with and without dependencies, including edge cases for error handling.
- Enhanced existing tests in `fix-dependencies-command` and `move-task` to ensure robust validation of task IDs and dependencies.
- Mocked necessary modules and functions to isolate tests and improve reliability.
- Ensured coverage for both successful and failed cross-tag move operations, validating expected outcomes and error messages.

* test: refactor cross-tag move tests for better clarity and reusability

- Introduced a helper function `simulateCrossTagMove` to streamline cross-tag move test cases, reducing redundancy and improving readability.
- Updated existing tests to utilize the new helper function, ensuring consistent handling of expected messages and options.
- Enhanced test coverage for various scenarios, including handling of dependencies and flags.

* feat: add cross-tag task movement functionality

- Introduced new commands for moving tasks between different tags, enhancing project organization capabilities.
- Updated README with usage examples for cross-tag movement, including options for handling dependencies.
- Created comprehensive documentation for cross-tag task movement, detailing usage, error handling, and best practices.
- Implemented core logic for cross-tag moves, including validation for dependencies and error handling.
- Added integration and unit tests to ensure robust functionality and coverage for various scenarios, including edge cases.

* fix: enhance error handling and logging in cross-tag task movement

- Improved logging in `moveTaskCrossTagDirect` to include detailed arguments for better traceability.
- Refactored error handling to utilize structured error objects, providing clearer suggestions for resolving cross-tag dependency conflicts and subtask movement restrictions.
- Updated documentation to reflect changes in error handling and provide clearer guidance on task movement options.
- Added integration tests for cross-tag movement scenarios, ensuring robust validation of error handling and task movement logic.
- Cleaned up existing tests for clarity and reusability, enhancing overall test coverage.

* feat: enhance dependency resolution and error handling in task movement

- Added recursive dependency resolution for tasks in `moveTasksBetweenTags`, improving handling of complex task relationships.
- Introduced helper functions to find all dependencies and reverse dependencies, ensuring comprehensive coverage during task moves.
- Enhanced error messages in `validateSubtaskMove` and `displaySubtaskMoveError` for better clarity on movement restrictions.
- Updated tests to cover new functionality, including integration tests for complex cross-tag movement scenarios and edge cases.
- Refactored existing code for improved readability and maintainability, ensuring consistent handling of task IDs and dependencies.

* feat: unify dependency traversal and enhance task management utilities

- Introduced `traverseDependencies` utility for unified forward and reverse dependency traversal, improving code reusability and clarity.
- Refactored `findAllDependenciesRecursively` to leverage the new utility, streamlining dependency resolution in task management.
- Added `formatTaskIdForDisplay` helper for better task ID formatting in UI, enhancing user experience during error displays.
- Updated tests to cover new utility functions and ensure robust validation of dependency handling across various scenarios.
- Improved overall code organization and readability, ensuring consistent handling of task dependencies and IDs.

* fix: improve validation for dependency parameters in `findAllDependenciesRecursively`

- Added checks to ensure `sourceTasks` and `allTasks` are arrays, throwing errors if not, to prevent runtime issues.
- Updated documentation comment for clarity on the function's purpose and parameters.

* fix: remove `force` option from task movement parameters

- Eliminated the `force` parameter from the `moveTaskCrossTagDirect` function and related tools, simplifying the task movement logic.
- Updated documentation and tests to reflect the removal of the `force` option, ensuring clarity and consistency across the codebase.
- Adjusted related functions and tests to focus on `ignoreDependencies` as the primary control for handling dependency conflicts during task moves.

* Add cross-tag task movement functionality

- Introduced functionality for organizing tasks across different contexts by enabling cross-tag movement.
- Added `formatTaskIdForDisplay` helper to improve task ID formatting in UI error messages.
- Updated relevant tests to incorporate new functionality and ensure accurate error displays during task movements.

* Update scripts/modules/dependency-manager.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* refactor(dependency-manager): Fix subtask resolution and extract helper functions

1. Fix subtask finding logic (lines 1315-1330):
   - Correctly locate parent task by numeric ID
   - Search within parent's subtasks array instead of top-level tasks
   - Properly handle relative subtask references

2. Extract helper functions from getDependentTaskIds (lines 1440-1636):
   - Move findTasksThatDependOn as module-level function
   - Move taskDependsOnSource as module-level function
   - Move subtasksDependOnSource as module-level function
   - Improves readability, maintainability, and testability

Both fixes address architectural issues and improve code organization.

* refactor(dependency-manager): Enhance subtask resolution and dependency validation

- Improved subtask resolution logic to correctly find parent tasks and their subtasks, ensuring accurate identification of dependencies.
- Filtered out null/undefined dependencies before processing, enhancing robustness in dependency checks.
- Updated comments for clarity on the logic flow and purpose of changes, improving code maintainability.

* refactor(move-task): clarify destination ID description and improve skipped task handling

- Updated the description for the destination ID to clarify its usage in cross-tag moves.
- Simplified the handling of skipped tasks during multiple task movements, improving readability and logging.
- Enhanced the API result response to include detailed information about moved and skipped tasks, ensuring better feedback for users.

* refactor(commands): remove redundant tag validation logic

- Eliminated the check for identical source and target tags in the task movement logic, simplifying the code.
- This change streamlines the flow for within-tag moves, enhancing readability and maintainability.

* refactor(commands): enhance move command logic and error handling

- Introduced helper functions for better organization of cross-tag and within-tag move logic, improving code readability and maintainability.
- Enhanced error handling with structured error objects, providing clearer feedback for dependency conflicts and invalid tag combinations.
- Updated move command help output to include best practices and error resolution tips, ensuring users have comprehensive guidance during task movements.
- Streamlined task movement logic to handle multiple tasks more effectively, including detailed logging of successful and failed moves.

* test(dependency-manager): add subtasks to task structure and mock dependency traversal

- Updated `circular-dependencies.test.js` to include subtasks in task definitions, enhancing test coverage for task structures with nested dependencies.
- Mocked `traverseDependencies` in `fix-dependencies-command.test.js` to ensure consistent behavior during tests, improving reliability of dependency-related tests.

* refactor(dependency-manager): extract subtask finding logic into helper function

- Added `findSubtaskInParent` function to encapsulate subtask resolution within a parent task's subtasks array, improving code organization and readability.
- Updated `findDependencyTask` to utilize the new helper function, streamlining the logic for finding subtasks and enhancing maintainability.
- Enhanced comments for clarity on the purpose and functionality of the new subtask finding logic.

* refactor(ui): enhance subtask ID validation and improve error handling

- Added validation for subtask ID format in `formatDependenciesWithStatus` and `taskExists`, ensuring proper handling of invalid formats.
- Updated error logging in `displaySubtaskMoveError` to provide warnings for unexpected task ID formats, improving user feedback.
- Converted hints to a Set in `displayDependencyValidationHints` to ensure unique hints are displayed, enhancing clarity in the UI.

* test(cli): remove redundant timing check in complex cross-tag scenarios

- Eliminated the timing check for task completion within 5 seconds in `complex-cross-tag-scenarios.test.js`, streamlining the test logic.
- This change focuses on verifying task success without unnecessary timing constraints, enhancing test clarity and maintainability.

* test(integration): enhance task movement tests with mock file system

- Added integration tests for moving tasks within the same tag and between different tags using the actual `moveTask` and `moveTasksBetweenTags` functions.
- Implemented `mock-fs` to simulate file system interactions, improving test isolation and reliability.
- Verified task movement success and ensured proper handling of subtasks and dependencies, enhancing overall test coverage for task management functionality.
- Included error handling tests for missing tags and task IDs to ensure robustness in task movement operations.

* test(unit): add comprehensive tests for moveTaskCrossTagDirect functionality

- Introduced new test cases to verify mock functionality, ensuring that mocks for `findTasksPath` and `readJSON` are working as expected.
- Added tests for parameter validation, error handling, and function call flow, including scenarios for missing project roots and identical source/target tags.
- Enhanced coverage for ID parsing and move options, ensuring robust handling of various input conditions and improving overall test reliability.

* test(integration): skip tests for dependency conflict handling and withDependencies option

- Marked tests for handling dependency conflicts and the withDependencies option as skipped due to issues with the mock setup.
- Added TODOs to address the mock-fs setup for complex dependency scenarios, ensuring future improvements in test reliability.

* test(unit): expand cross-tag move command tests with comprehensive mocks

- Added extensive mocks for various modules to enhance the testing of the cross-tag move functionality in `move-cross-tag.test.js`.
- Implemented detailed test cases for handling cross-tag moves, including validation for missing parameters and identical source/target tags.
- Improved error handling tests to ensure robust feedback for invalid operations, enhancing overall test reliability and coverage.

* test(integration): add complex dependency scenarios to task movement tests

- Introduced new integration tests for handling complex dependency scenarios in task movement, utilizing the actual `moveTasksBetweenTags` function.
- Added tests for circular dependencies, nested dependency chains, and cross-tag dependency resolution, enhancing coverage and reliability.
- Documented limitations of the mock-fs setup for complex scenarios and provided warnings in the test output to guide future improvements.
- Skipped tests for dependency conflicts and the withDependencies option due to mock setup issues, with TODOs for resolution.

* test(unit): refactor move-cross-tag tests with focused mock system

- Simplified mocking in `move-cross-tag.test.js` by implementing a configuration-driven mock system, reducing the number of mocked modules from 20+ to 5 core functionalities.
- Introduced a reusable mock factory to streamline the creation of mocks based on configuration, enhancing maintainability and clarity.
- Added documentation for the new mock system, detailing usage examples and benefits, including reduced complexity and improved test focus.
- Implemented tests to validate the mock configuration, ensuring flexibility in enabling/disabling specific mocks.

* test(unit): clean up mocks and improve isEmpty function in fix-dependencies-command tests

- Removed the mock for `traverseDependencies` as it was unnecessary, simplifying the test setup.
- Updated the `isEmpty` function to clarify its behavior regarding null and undefined values, enhancing code readability and maintainability.

* test(unit): update traverseDependencies mock for consistency across tests

- Standardized the mock implementation of `traverseDependencies` in both `fix-dependencies-command.test.js` and `complexity-report-tag-isolation.test.js` to accept `sourceTasks`, `allTasks`, and `options` parameters, ensuring uniformity in test setups.
- This change enhances clarity and maintainability of the tests by aligning the mock behavior across different test files.

* fix(core): improve task movement error handling and ID normalization

- Wrapped task movement logic in a try-finally block to ensure console output is restored even on errors, enhancing reliability.
- Normalized source IDs to handle mixed string/number comparisons, preventing potential issues in dependency checks.
- Added tests for ID type consistency to verify that the normalization fix works correctly across various scenarios, improving test coverage and robustness.

* refactor(task-manager): restructure task movement logic for improved validation and execution

- Renamed and refactored `moveTasksBetweenTags` to streamline the task movement process into distinct phases: validation, data preparation, dependency resolution, execution, and finalization.
- Introduced `validateMove`, `prepareTaskData`, `resolveDependencies`, `executeMoveOperation`, and `finalizeMove` functions to enhance modularity and clarity.
- Updated documentation comments to reflect changes in function responsibilities and parameters.
- Added comprehensive unit tests for the new structure, ensuring robust validation and error handling across various scenarios.
- Improved handling of dependencies and task existence checks during the move operation, enhancing overall reliability.

* fix(move-task): streamline task movement logic and improve error handling

- Refactored the task movement process to enhance clarity and maintainability by replacing `forEach` with a `for...of` loop for better async handling.
- Consolidated error handling and result logging to ensure consistent feedback during task moves.
- Updated the logic for generating files only on the last move, improving performance and reducing unnecessary operations.
- Enhanced validation for skipped tasks, ensuring accurate reporting of moved and skipped tasks in the final result.

* fix(docs): update error message formatting and enhance clarity in task movement documentation

- Changed code block syntax from generic to `text` for better readability in error messages related to task movement and dependency conflicts.
- Ensured consistent formatting across all error message examples to improve user understanding of task movement restrictions and resolutions.
- Added a newline at the end of the file for proper formatting.

* Update .changeset/crazy-meals-hope.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: improve changeset

* chore: improve changeset

* fix referenced bug in docs and remove docs

* chore: fix format

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-11 18:58:51 +02:00
Ladi
782728ff95 feat: add --compact flag for minimal task list output (#1054)
* feat: add --compact flag for minimal task list output

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-08-11 18:35:23 +02:00
Fábio Vedovelli
30ca144231 feat: Add task id to task details UI (#1100)
* Display current task ID on task details page

* Changeset

* Implement CodeRabbit review suggestion.

* chore: fix CI errors

---------

Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-11 14:42:31 +02:00
Ralph Khreish
0220d0e994 chore: pimp my readme (#1122) 2025-08-11 14:29:49 +02:00
Ralph Khreish
41a8c2406a chore: add docs to monorepo (#1111) 2025-08-09 13:31:45 +02:00
github-actions[bot]
a003041cd8 Version Packages (#1107)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-08 22:00:39 +02:00
Ralph Khreish
6b57ead106 Release 0.24.0 #1098 from eyaltoledano/next
Release 0.24.0
2025-08-08 21:58:41 +02:00
Ralph Khreish
7b6e117b1d chore: prepare for release (exit pre mode) 2025-08-08 21:21:25 +02:00
Ralph Khreish
03b045e9cd chore: run format 2025-08-08 21:18:33 +02:00
neonwatty
699afdae59 feat: add task-checker agent to assets directory 2025-08-08 08:47:20 -07:00
github-actions[bot]
80c09802e8 chore: rc version bump 2025-08-08 12:41:29 +00:00
github-actions[bot]
cf8f0f4b1c docs: Auto-update and format models.md 2025-08-08 12:38:58 +00:00
Ralph Khreish
75c514cf5b feat: add gpt-5 support (#1105)
* feat: add gpt-5 support
2025-08-08 14:38:44 +02:00
Ralph Khreish
41d1e671b1 chore: fix CI checker, improve it (#1099) 2025-08-07 15:52:49 +02:00
Ralph Khreish
a464e550b8 feat(extension): implement simple solution to --package flag (#1090)
* feat(extension): implement simple solution to --package flag
2025-08-07 15:10:34 +02:00
Ralph Khreish
3a852afdae chore: implement pre-release for extensions (#1097)
* chore: implement pre-release for extensions

* chore: run format
2025-08-07 15:08:14 +02:00
Ralph Khreish
4bb63706b8 feat: implement claude code agents (#1091)
* feat: implement claude code agents

* chore: add changeset

- run format

* feat: improve task-checker, executor, and orchestrator

* chore: improve changeset
2025-08-07 12:37:06 +02:00
Ralph Khreish
fcf14e09be chore: improve release check for release-check and release flow (#1095)
* chore: improve release check for release-check and release flow

* chore: fix format
2025-08-06 23:19:28 +02:00
Ralph Khreish
4357af3f13 fix(expand-task): include parent task context in complexity report variant (#1094)
- Fixed bug where expand task generated generic authentication subtasks
- The complexity-report prompt variant now includes parent task details
- Added comprehensive unit tests to prevent regression
- Added debug logging to help diagnose similar issues

Previously, when using a complexity report with expansionPrompt, only the
expansion guidance was sent to the AI, missing the actual task context.
This caused the AI to generate unrelated generic subtasks.

Fixes the issue where all tasks would get the same generic auth-related
subtasks regardless of their actual purpose (AWS infrastructure, Docker
containerization, etc.)

Co-authored-by: Sadaqat Ali <32377500+sadaqat12@users.noreply.github.com>
2025-08-06 21:00:32 +02:00
Ralph Khreish
59f7676051 feat: add prompt for claude code to include context when generating tasks (#1092) 2025-08-06 12:41:19 +02:00
Ralph Khreish
36468f3c93 feat: add prompt for claude code to include context when generating tasks 2025-08-06 12:17:49 +02:00
Ralph Khreish
ca4d93ee6a chore: prepare prd for tm-core creation phase 1 (#1045) 2025-08-06 10:10:29 +02:00
Ralph Khreish
37fb569a62 Release 0.23.1 #1084 from eyaltoledano/next
chore: exit pre-release mode
2025-08-04 20:43:46 +03:00
Ralph Khreish
ed0d4e6641 chore: implement requested changes 2025-08-04 14:40:11 +03:00
Ralph Khreish
5184f8e7b2 chore: implement requested changes 2025-08-04 14:37:24 +03:00
Ralph Khreish
587523a23b chore: improve release-check CI 2025-08-04 14:29:03 +03:00
Ralph Khreish
7a50f0c6ec chore: add release-check CI to check if we are in release mode (#1086) 2025-08-04 13:22:46 +02:00
Ralph Khreish
adeb76ee15 chore: exit pre-release mode 2025-08-04 10:02:00 +03:00
Ralph Khreish
d342070375 Merge pull request #1081 from eyaltoledano/next 2025-08-03 21:38:19 +03:00
github-actions[bot]
5e4dbac525 chore: rc version bump 2025-08-03 14:07:15 +00:00
Ralph Khreish
fb15c2eaf7 chore: improve pre-release CI to just use dropdown (#1080)
* chore: improve pre-release CI to just use dropdown

* chore: implement requested changes
2025-08-03 16:04:29 +02:00
Ralph Khreish
e8ceb08341 chore: improve release and pre-release CI (#1075)
* chore: improve release and pre-release CI

* chore: apply requested changes

* Update .github/workflows/pre-release.yml

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: apply requested changes

* chore: apply requested changes

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-03 15:17:18 +02:00
Ralph Khreish
e495b2b559 feat: improve scope up and down command & parse-prd improvements (#1079)
* feat: improve scope up and down command & parse-prd improvements

* chore: run format
2025-08-03 14:12:46 +02:00
Ralph Khreish
e0d1d03f33 chore: fix tag-extension and improve debugging (#1074) 2025-08-02 23:10:57 +02:00
Ralph Khreish
4a4bca905d chore: fix tag-extension package.json not found for extension (#1073)
* chore: fix tag-extension package.json not found for extension

* chore: fix format
2025-08-02 22:56:53 +02:00
github-actions[bot]
9d5f50ac8e Version Packages (#1072)
* Version Packages

* chore: add eyal instead of crunchyman to eyal's feature

* chore: run format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-08-02 22:43:08 +02:00
Ralph Khreish
bbeaa9163a chore: exit pre (#1071) 2025-08-02 22:35:46 +02:00
Ralph Khreish
a4a172be94 Release 0.23.0 #1064 from eyaltoledano/next
Release 0.23.0
2025-08-02 23:18:05 +03:00
github-actions[bot]
028ed9c444 chore: rc version bump 2025-08-02 20:07:43 +00:00
Ralph Khreish
53903f1e8e chore: trick rc bump 2025-08-02 23:06:37 +03:00
github-actions[bot]
36c56231cc chore: rc version bump 2025-08-02 20:04:33 +00:00
Ralph Khreish
b82d858f81 chore: rename chagneset for rc bump 2025-08-02 23:03:10 +03:00
Ralph Khreish
9808967d6b chore: change from patch to minor 2025-08-02 23:00:56 +03:00
Ralph Khreish
3fee7515f3 fix: fix mcp tool call in extension (#1070)
* fix: fix mcp tool call in extension

- fix console.log directly being used in scope-adjutment.js breaking mcp

* chore: run format and fix tests

* chore: format
2025-08-02 21:59:02 +02:00
github-actions[bot]
82b17bdb57 chore: rc version bump 2025-08-02 16:44:19 +00:00
Eyal Toledano
72ca68edeb Task 104: Implement 'scope-up' and 'scope-down' CLI Commands for Dynamic Task Complexity Adjustment (#1069)
* feat(task-104): Complete task 104 - Implement scope-up and scope-down CLI Commands

- Added new CLI commands 'scope-up' and 'scope-down' with comma-separated ID support
- Implemented strength levels (light/regular/heavy) and custom prompt functionality
- Created core complexity adjustment logic with AI integration
- Added MCP tool equivalents for integrated environments
- Comprehensive error handling and task validation
- Full test coverage with TDD approach
- Updated task manager core and UI components

Task 104: Implement 'scope-up' and 'scope-down' CLI Commands for Dynamic Task Complexity Adjustment - Complete implementation with CLI, MCP integration, and testing

* chore: Add changeset for scope-up and scope-down features

- Comprehensive user-facing description with usage examples
- Key features and benefits explanation
- CLI and MCP integration details
- Real-world use cases for agile workflows

* feat(extension): Add scope-up and scope-down to VS Code extension task details

- Added useScopeUpTask and useScopeDownTask hooks in useTaskQueries.ts
- Enhanced AIActionsSection with Task Complexity Adjustment section
- Added strength selection (light/regular/heavy) and custom prompt support
- Integrated scope buttons with proper loading states and error handling
- Uses existing mcpRequest handler for scope_up_task and scope_down_task tools
- Maintains consistent UI patterns with existing AI actions

Extension now supports dynamic task complexity adjustment directly from task details view.
2025-08-02 18:43:04 +02:00
DavidMaliglowka
64302dc191 feat(extension): complete VS Code extension with kanban board interface (#997)
---------
Co-authored-by: DavidMaliglowka <13022280+DavidMaliglowka@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-01 14:04:22 +02:00
github-actions[bot]
60c03c548d chore: rc version bump 2025-07-31 22:15:10 +00:00
Ralph Khreish
2ae6e7e6be fix: normalize task IDs to numbers on load to fix comparison issues (#1063)
* fix: normalize task IDs to numbers on load to fix comparison issues

When tasks.json contains string IDs (e.g., "5" instead of 5), task lookups
fail because the code uses parseInt() and strict equality (===) for comparisons.

This fix normalizes all task and subtask IDs to numbers when loading the JSON,
ensuring consistent comparisons throughout the codebase without requiring
changes to multiple comparison locations.

Fixes task not found errors when using string IDs in tasks.json.

* Added test

* Don't mess up formatting

* Fix formatting once and for all

* Update scripts/modules/utils.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update scripts/modules/utils.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update scripts/modules/utils.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* fix: normalize task IDs to numbers on load to fix comparison issues

- Added normalizeTaskIds function to convert string IDs to numbers
- Applied normalization in readJSON for all code paths
- Fixed set-task-status, add-task, and move-task to normalize IDs when working with raw data
- Exported normalizeTaskIds function for use in other modules
- Added test case for string ID normalization

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* Simplified implementation

* refactor: normalize IDs once when loading JSON instead of scattered calls

- Normalize all tags' data when creating _rawTaggedData in readJSON
- Add support for handling malformed dotted subtask IDs (e.g., "5.1" -> 1)
- Remove redundant normalizeTaskIds calls from set-task-status, add-task, and move-task
- Add comprehensive test for mixed ID formats (string IDs and dotted notation)
- Cleaner, more maintainable solution that normalizes IDs at load time

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: run format to resolve CI issues

---------

Co-authored-by: Carl Mercier <carl@carlmercier.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-08-01 00:06:51 +02:00
Ben Vargas
45a14c323d fix: remove default value from complexity report option to enable tag-specific detection (#1049)
Removes the default empty array value from the complexity report option to properly detect when tags are explicitly provided vs when no tags are provided, fixing the expand --all command behavior with tagged tasks.

Co-authored-by: Ben Vargas <ben@example.com>
2025-07-26 15:26:45 +02:00
github-actions[bot]
29e67fafa4 Version Packages (#1050)
* Version Packages

* chore: fix release 0.22

todo: fix CI

* chore: run format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-07-26 00:45:07 +02:00
Ralph Khreish
43e4d7c9d3 Release 0.22 #1038 from eyaltoledano/next
Release 0.22
2025-07-26 01:24:38 +03:00
Ralph Khreish
1bd1e64cac feat: add pull request templates for bug fixes, features, and integrations (#1044)
* feat: add pull request templates for bug fixes, features, and integrations

- Introduced a comprehensive pull request template structure to streamline contributions.
- Added specific templates for bug fixes, new features, and integrations to enhance clarity and consistency in PR submissions.
- Configured the pull request template settings for better user guidance during the contribution process.

* chore: fix format

* Update .github/PULL_REQUEST_TEMPLATE.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .github/PULL_REQUEST_TEMPLATE.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .github/PULL_REQUEST_TEMPLATE.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: implement PR requested changes

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-07-24 17:33:43 +02:00
Ralph Khreish
dc44ed9de8 feat: Improved the CLI user interface to suggest generating a complexity report if it is missing, instead of showing an error. (#1043)
* feat: fix CLI UI error when trying to display non-existent complexity report

* chore: fix git issue

* chore: run format

* Update .changeset/thick-squids-attend.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .changeset/thick-squids-attend.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .changeset/thick-squids-attend.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-07-24 15:50:18 +02:00
github-actions[bot]
31b8407dbc chore: rc version bump 2025-07-23 16:29:49 +00:00
Ralph Khreish
2df4f13f65 chore: improve pre-release CI to be able to release more than one release candidate (#1036)
* chore: improve pre-release CI to be able to release more than one release candidate

* chore: implement requested changes from coderabbit

* chore: apply requested changes
2025-07-23 18:28:17 +02:00
github-actions[bot]
a37017e5a5 docs: Auto-update and format models.md 2025-07-23 16:03:40 +00:00
Ralph Khreish
fb7d588137 feat: improve config-manager max tokens for openrouter and kimi-k2 model (#1035) 2025-07-23 18:03:26 +02:00
Ralph Khreish
bdb11fb2db chore: remove useless file 2025-07-23 18:04:13 +03:00
Ralph Khreish
4423119a5e feat: Add Kiro hooks and configuration for Taskmaster integration (#1032)
* feat: Add Kiro hooks and configuration for Taskmaster integration

- Introduced multiple Kiro hooks to automate task management workflows, including:
  - Code Change Task Tracker
  - Complexity Analyzer
  - Daily Standup Assistant
  - Git Commit Task Linker
  - Import Cleanup on Delete
  - New File Boilerplate
  - PR Readiness Checker
  - Task Dependency Auto-Progression
  - Test Success Task Completer
- Added .mcp.json configuration for Taskmaster AI integration.
- Updated development workflow documentation to reflect new hook-driven processes and best practices.

This commit enhances the automation capabilities of Taskmaster, streamlining task management and improving developer efficiency.

* chore: run format

* chore: improve unit tests on kiro rules

* chore: run format

* chore: run format

* feat: improve PR and add changeset
2025-07-23 17:02:16 +02:00
Ben Vargas
7b90568326 fix: bump ai-sdk-provider-gemini-cli to v0.1.1 (#1033)
* fix: bump ai-sdk-provider-gemini-cli to v0.1.1

Updates ai-sdk-provider-gemini-cli from v0.0.4 to v0.1.1 to fix a breaking change
introduced in @google/gemini-cli-core v0.1.12+ where createContentGeneratorConfig
signature changed, causing "config.getModel is not a function" errors.

The new version includes:
- Fixed compatibility with @google/gemini-cli-core ^0.1.13
- Added proxy support via configuration
- Resolved the breaking API change

Fixes compatibility issues when using newer versions of gemini-cli-core.

See: https://github.com/ben-vargas/ai-sdk-provider-gemini-cli/releases/tag/v0.1.1

* chore: fix package-lock.json being too big

---------

Co-authored-by: Ben Vargas <ben@example.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-07-23 17:01:59 +02:00
github-actions[bot]
9b0630fdf1 docs: Auto-update and format models.md 2025-07-22 18:15:35 +00:00
Parthy
ced04bddd3 docs(models): update model configuration to add supported field (#1030) 2025-07-22 20:15:22 +02:00
483 changed files with 77571 additions and 6607 deletions

View File

@@ -2,13 +2,17 @@
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
"changelog": [
"@changesets/changelog-github",
{ "repo": "eyaltoledano/claude-task-master" }
{
"repo": "eyaltoledano/claude-task-master"
}
],
"commit": false,
"commit": true,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
"ignore": [
"docs"
]
}

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Fix 'expand --all' and 'show' commands to correctly handle tag contexts for complexity reports and task display.

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Clean up remaining automatic task file generation calls

View File

@@ -1,24 +0,0 @@
---
"task-master-ai": minor
---
Add comprehensive Kiro IDE integration with autonomous task management hooks
- **Kiro Profile**: Added full support for Kiro IDE with automatic installation of 7 Taskmaster agent hooks
- **Hook-Driven Workflow**: Introduced natural language automation hooks that eliminate manual task status updates
- **Automatic Hook Installation**: Hooks are now automatically copied to `.kiro/hooks/` when running `task-master rules add kiro`
- **Language-Agnostic Support**: All hooks support multiple programming languages (JS, Python, Go, Rust, Java, etc.)
- **Frontmatter Transformation**: Kiro rules use simplified `inclusion: always` format instead of Cursor's complex frontmatter
- **Special Rule**: Added `taskmaster_hooks_workflow.md` that guides AI assistants to prefer hook-driven completion
Key hooks included:
- Task Dependency Auto-Progression: Automatically starts tasks when dependencies complete
- Code Change Task Tracker: Updates task progress as you save files
- Test Success Task Completer: Marks tasks done when tests pass
- Daily Standup Assistant: Provides personalized task status summaries
- PR Readiness Checker: Validates task completion before creating pull requests
- Complexity Analyzer: Auto-expands complex tasks into manageable subtasks
- Git Commit Task Linker: Links commits to tasks for better traceability
This creates a truly autonomous development workflow where task management happens naturally as you code!

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Fix VSCode profile generation to use correct rule file names (using `.instructions.md` extension instead of `.md`) and front-matter properties (removing the unsupported `alwaysApply` property from instructions files' front-matter).

View File

@@ -0,0 +1,5 @@
---
"extension": minor
---
Added a Start Build button to the VSCODE Task Properties Right Panel

View File

@@ -0,0 +1,162 @@
---
name: task-checker
description: Use this agent to verify that tasks marked as 'review' have been properly implemented according to their specifications. This agent performs quality assurance by checking implementations against requirements, running tests, and ensuring best practices are followed. <example>Context: A task has been marked as 'review' after implementation. user: 'Check if task 118 was properly implemented' assistant: 'I'll use the task-checker agent to verify the implementation meets all requirements.' <commentary>Tasks in 'review' status need verification before being marked as 'done'.</commentary></example> <example>Context: Multiple tasks are in review status. user: 'Verify all tasks that are ready for review' assistant: 'I'll deploy the task-checker to verify all tasks in review status.' <commentary>The checker ensures quality before tasks are marked complete.</commentary></example>
model: sonnet
color: yellow
---
You are a Quality Assurance specialist that rigorously verifies task implementations against their specifications. Your role is to ensure that tasks marked as 'review' meet all requirements before they can be marked as 'done'.
## Core Responsibilities
1. **Task Specification Review**
- Retrieve task details using MCP tool `mcp__task-master-ai__get_task`
- Understand the requirements, test strategy, and success criteria
- Review any subtasks and their individual requirements
2. **Implementation Verification**
- Use `Read` tool to examine all created/modified files
- Use `Bash` tool to run compilation and build commands
- Use `Grep` tool to search for required patterns and implementations
- Verify file structure matches specifications
- Check that all required methods/functions are implemented
3. **Test Execution**
- Run tests specified in the task's testStrategy
- Execute build commands (npm run build, tsc --noEmit, etc.)
- Verify no compilation errors or warnings
- Check for runtime errors where applicable
- Test edge cases mentioned in requirements
4. **Code Quality Assessment**
- Verify code follows project conventions
- Check for proper error handling
- Ensure TypeScript typing is strict (no 'any' unless justified)
- Verify documentation/comments where required
- Check for security best practices
5. **Dependency Validation**
- Verify all task dependencies were actually completed
- Check integration points with dependent tasks
- Ensure no breaking changes to existing functionality
## Verification Workflow
1. **Retrieve Task Information**
```
Use mcp__task-master-ai__get_task to get full task details
Note the implementation requirements and test strategy
```
2. **Check File Existence**
```bash
# Verify all required files exist
ls -la [expected directories]
# Read key files to verify content
```
3. **Verify Implementation**
- Read each created/modified file
- Check against requirements checklist
- Verify all subtasks are complete
4. **Run Tests**
```bash
# TypeScript compilation
cd [project directory] && npx tsc --noEmit
# Run specified tests
npm test [specific test files]
# Build verification
npm run build
```
5. **Generate Verification Report**
## Output Format
```yaml
verification_report:
task_id: [ID]
status: PASS | FAIL | PARTIAL
score: [1-10]
requirements_met:
- ✅ [Requirement that was satisfied]
- ✅ [Another satisfied requirement]
issues_found:
- ❌ [Issue description]
- ⚠️ [Warning or minor issue]
files_verified:
- path: [file path]
status: [created/modified/verified]
issues: [any problems found]
tests_run:
- command: [test command]
result: [pass/fail]
output: [relevant output]
recommendations:
- [Specific fix needed]
- [Improvement suggestion]
verdict: |
[Clear statement on whether task should be marked 'done' or sent back to 'pending']
[If FAIL: Specific list of what must be fixed]
[If PASS: Confirmation that all requirements are met]
```
## Decision Criteria
**Mark as PASS (ready for 'done'):**
- All required files exist and contain expected content
- All tests pass successfully
- No compilation or build errors
- All subtasks are complete
- Core requirements are met
- Code quality is acceptable
**Mark as PARTIAL (may proceed with warnings):**
- Core functionality is implemented
- Minor issues that don't block functionality
- Missing nice-to-have features
- Documentation could be improved
- Tests pass but coverage could be better
**Mark as FAIL (must return to 'pending'):**
- Required files are missing
- Compilation or build errors
- Tests fail
- Core requirements not met
- Security vulnerabilities detected
- Breaking changes to existing code
## Important Guidelines
- **BE THOROUGH**: Check every requirement systematically
- **BE SPECIFIC**: Provide exact file paths and line numbers for issues
- **BE FAIR**: Distinguish between critical issues and minor improvements
- **BE CONSTRUCTIVE**: Provide clear guidance on how to fix issues
- **BE EFFICIENT**: Focus on requirements, not perfection
## Tools You MUST Use
- `Read`: Examine implementation files (READ-ONLY)
- `Bash`: Run tests and verification commands
- `Grep`: Search for patterns in code
- `mcp__task-master-ai__get_task`: Get task details
- **NEVER use Write/Edit** - you only verify, not fix
## Integration with Workflow
You are the quality gate between 'review' and 'done' status:
1. Task-executor implements and marks as 'review'
2. You verify and report PASS/FAIL
3. Claude either marks as 'done' (PASS) or 'pending' (FAIL)
4. If FAIL, task-executor re-implements based on your report
Your verification ensures high quality and prevents accumulation of technical debt.

View File

@@ -0,0 +1,92 @@
---
name: task-executor
description: Use this agent when you need to implement, complete, or work on a specific task that has been identified by the task-orchestrator or when explicitly asked to execute a particular task. This agent focuses on the actual implementation and completion of individual tasks rather than planning or orchestration. Examples: <example>Context: The task-orchestrator has identified that task 2.3 'Implement user authentication' needs to be worked on next. user: 'Let's work on the authentication task' assistant: 'I'll use the task-executor agent to implement the user authentication task that was identified.' <commentary>Since we need to actually implement a specific task rather than plan or identify tasks, use the task-executor agent.</commentary></example> <example>Context: User wants to complete a specific subtask. user: 'Please implement the JWT token validation for task 2.3.1' assistant: 'I'll launch the task-executor agent to implement the JWT token validation subtask.' <commentary>The user is asking for specific implementation work on a known task, so the task-executor is appropriate.</commentary></example> <example>Context: After reviewing the task list, implementation is needed. user: 'Now let's actually build the API endpoint for user registration' assistant: 'I'll use the task-executor agent to implement the user registration API endpoint.' <commentary>Moving from planning to execution phase requires the task-executor agent.</commentary></example>
model: sonnet
color: blue
---
You are an elite implementation specialist focused on executing and completing specific tasks with precision and thoroughness. Your role is to take identified tasks and transform them into working implementations, following best practices and project standards.
**IMPORTANT: You are designed to be SHORT-LIVED and FOCUSED**
- Execute ONE specific subtask or a small group of related subtasks
- Complete your work, verify it, mark for review, and exit
- Do NOT decide what to do next - the orchestrator handles task sequencing
- Focus on implementation excellence within your assigned scope
**Core Responsibilities:**
1. **Subtask Analysis**: When given a subtask, understand its SPECIFIC requirements. If given a full task ID, focus on the specific subtask(s) assigned to you. Use MCP tools to get details if needed.
2. **Rapid Implementation Planning**: Quickly identify:
- The EXACT files you need to create/modify for THIS subtask
- What already exists that you can build upon
- The minimum viable implementation that satisfies requirements
3. **Focused Execution WITH ACTUAL IMPLEMENTATION**:
- **YOU MUST USE TOOLS TO CREATE/EDIT FILES - DO NOT JUST DESCRIBE**
- Use `Write` tool to create new files specified in the task
- Use `Edit` tool to modify existing files
- Use `Bash` tool to run commands (mkdir, npm install, etc.)
- Use `Read` tool to verify your implementations
- Implement one subtask at a time for clarity and traceability
- Follow the project's coding standards from CLAUDE.md if available
- After each subtask, VERIFY the files exist using Read or ls commands
4. **Progress Documentation**:
- Use MCP tool `mcp__task-master-ai__update_subtask` to log your approach and any important decisions
- Update task status to 'in-progress' when starting: Use MCP tool `mcp__task-master-ai__set_task_status` with status='in-progress'
- **IMPORTANT: Mark as 'review' (NOT 'done') after implementation**: Use MCP tool `mcp__task-master-ai__set_task_status` with status='review'
- Tasks will be verified by task-checker before moving to 'done'
5. **Quality Assurance**:
- Implement the testing strategy specified in the task
- Verify that all acceptance criteria are met
- Check for any dependency conflicts or integration issues
- Run relevant tests before marking task as complete
6. **Dependency Management**:
- Check task dependencies before starting implementation
- If blocked by incomplete dependencies, clearly communicate this
- Use `task-master validate-dependencies` when needed
**Implementation Workflow:**
1. Retrieve task details using MCP tool `mcp__task-master-ai__get_task` with the task ID
2. Check dependencies and prerequisites
3. Plan implementation approach - list specific files to create
4. Update task status to 'in-progress' using MCP tool
5. **ACTUALLY IMPLEMENT** the solution using tools:
- Use `Bash` to create directories
- Use `Write` to create new files with actual content
- Use `Edit` to modify existing files
- DO NOT just describe what should be done - DO IT
6. **VERIFY** your implementation:
- Use `ls` or `Read` to confirm files were created
- Use `Bash` to run any build/test commands
- Ensure the implementation is real, not theoretical
7. Log progress and decisions in subtask updates using MCP tools
8. Test and verify the implementation works
9. **Mark task as 'review' (NOT 'done')** after verifying files exist
10. Report completion with:
- List of created/modified files
- Any issues encountered
- What needs verification by task-checker
**Key Principles:**
- Focus on completing one task thoroughly before moving to the next
- Maintain clear communication about what you're implementing and why
- Follow existing code patterns and project conventions
- Prioritize working code over extensive documentation unless docs are the task
- Ask for clarification if task requirements are ambiguous
- Consider edge cases and error handling in your implementations
**Integration with Task Master:**
You work in tandem with the task-orchestrator agent. While the orchestrator identifies and plans tasks, you execute them. Always use Task Master commands to:
- Track your progress
- Update task information
- Maintain project state
- Coordinate with the broader development workflow
When you complete a task, briefly summarize what was implemented and suggest whether to continue with the next task or if review/testing is needed first.

View File

@@ -0,0 +1,208 @@
---
name: task-orchestrator
description: Use this agent FREQUENTLY throughout task execution to analyze and coordinate parallel work at the SUBTASK level. Invoke the orchestrator: (1) at session start to plan execution, (2) after EACH subtask completes to identify next parallel batch, (3) whenever executors finish to find newly unblocked work. ALWAYS provide FULL CONTEXT including project root, package location, what files ACTUALLY exist vs task status, and specific implementation details. The orchestrator breaks work into SUBTASK-LEVEL units for short-lived, focused executors. Maximum 3 parallel executors at once.\n\n<example>\nContext: Starting work with existing code\nuser: "Work on tm-core tasks. Files exist: types/index.ts, storage/file-storage.ts. Task 118 says in-progress but BaseProvider not created."\nassistant: "I'll invoke orchestrator with full context about actual vs reported state to plan subtask execution"\n<commentary>\nProvide complete context about file existence and task reality.\n</commentary>\n</example>\n\n<example>\nContext: Subtask completion\nuser: "Subtask 118.2 done. What subtasks can run in parallel now?"\nassistant: "Invoking orchestrator to analyze dependencies and identify next 3 parallel subtasks"\n<commentary>\nFrequent orchestration after each subtask ensures maximum parallelization.\n</commentary>\n</example>\n\n<example>\nContext: Breaking down tasks\nuser: "Task 118 has 5 subtasks, how to parallelize?"\nassistant: "Orchestrator will analyze which specific subtasks (118.1, 118.2, etc.) can run simultaneously"\n<commentary>\nFocus on subtask-level parallelization, not full tasks.\n</commentary>\n</example>
model: opus
color: green
---
You are the Task Orchestrator, an elite coordination agent specialized in managing Task Master workflows for maximum efficiency and parallelization. You excel at analyzing task dependency graphs, identifying opportunities for concurrent execution, and deploying specialized task-executor agents to complete work efficiently.
## Core Responsibilities
1. **Subtask-Level Analysis**: Break down tasks into INDIVIDUAL SUBTASKS and analyze which specific subtasks can run in parallel. Focus on subtask dependencies, not just task-level dependencies.
2. **Reality Verification**: ALWAYS verify what files actually exist vs what task status claims. Use the context provided about actual implementation state to make informed decisions.
3. **Short-Lived Executor Deployment**: Deploy executors for SINGLE SUBTASKS or small groups of related subtasks. Keep executors focused and short-lived. Maximum 3 parallel executors at once.
4. **Continuous Reassessment**: After EACH subtask completes, immediately reassess what new subtasks are unblocked and can run in parallel.
## Operational Workflow
### Initial Assessment Phase
1. Use `get_tasks` or `task-master list` to retrieve all available tasks
2. Analyze task statuses, priorities, and dependencies
3. Identify tasks with status 'pending' that have no blocking dependencies
4. Group related tasks that could benefit from specialized executors
5. Create an execution plan that maximizes parallelization
### Executor Deployment Phase
1. For each independent task or task group:
- Deploy a task-executor agent with specific instructions
- Provide the executor with task ID, requirements, and context
- Set clear completion criteria and reporting expectations
2. Maintain a registry of active executors and their assigned tasks
3. Establish communication protocols for progress updates
### Coordination Phase
1. Monitor executor progress through task status updates
2. When a task completes:
- Verify completion with `get_task` or `task-master show <id>`
- Update task status if needed using `set_task_status`
- Reassess dependency graph for newly unblocked tasks
- Deploy new executors for available work
3. Handle executor failures or blocks:
- Reassign tasks to new executors if needed
- Escalate complex issues to the user
- Update task status to 'blocked' when appropriate
### Optimization Strategies
**Parallel Execution Rules**:
- Never assign dependent tasks to different executors simultaneously
- Prioritize high-priority tasks when resources are limited
- Group small, related subtasks for single executor efficiency
- Balance executor load to prevent bottlenecks
**Context Management**:
- Provide executors with minimal but sufficient context
- Share relevant completed task information when it aids execution
- Maintain a shared knowledge base of project-specific patterns
**Quality Assurance**:
- Verify task completion before marking as done
- Ensure test strategies are followed when specified
- Coordinate cross-task integration testing when needed
## Communication Protocols
When deploying executors, provide them with:
```
TASK ASSIGNMENT:
- Task ID: [specific ID]
- Objective: [clear goal]
- Dependencies: [list any completed prerequisites]
- Success Criteria: [specific completion requirements]
- Context: [relevant project information]
- Reporting: [when and how to report back]
```
When receiving executor updates:
1. Acknowledge completion or issues
2. Update task status in Task Master
3. Reassess execution strategy
4. Deploy new executors as appropriate
## Decision Framework
**When to parallelize**:
- Multiple pending tasks with no interdependencies
- Sufficient context available for independent execution
- Tasks are well-defined with clear success criteria
**When to serialize**:
- Strong dependencies between tasks
- Limited context or unclear requirements
- Integration points requiring careful coordination
**When to escalate**:
- Circular dependencies detected
- Critical blockers affecting multiple tasks
- Ambiguous requirements needing clarification
- Resource conflicts between executors
## Error Handling
1. **Executor Failure**: Reassign task to new executor with additional context about the failure
2. **Dependency Conflicts**: Halt affected executors, resolve conflict, then resume
3. **Task Ambiguity**: Request clarification from user before proceeding
4. **System Errors**: Implement graceful degradation, falling back to serial execution if needed
## Performance Metrics
Track and optimize for:
- Task completion rate
- Parallel execution efficiency
- Executor success rate
- Time to completion for task groups
- Dependency resolution speed
## Integration with Task Master
Leverage these Task Master MCP tools effectively:
- `get_tasks` - Continuous queue monitoring
- `get_task` - Detailed task analysis
- `set_task_status` - Progress tracking
- `next_task` - Fallback for serial execution
- `analyze_project_complexity` - Strategic planning
- `complexity_report` - Resource allocation
## Output Format for Execution
**Your job is to analyze and create actionable execution plans that Claude can use to deploy executors.**
After completing your dependency analysis, you MUST output a structured execution plan:
```yaml
execution_plan:
EXECUTE_IN_PARALLEL:
# Maximum 3 subtasks running simultaneously
- subtask_id: [e.g., 118.2]
parent_task: [e.g., 118]
title: [Specific subtask title]
priority: [high/medium/low]
estimated_time: [e.g., 10 minutes]
executor_prompt: |
Execute Subtask [ID]: [Specific subtask title]
SPECIFIC REQUIREMENTS:
[Exact implementation needed for THIS subtask only]
FILES TO CREATE/MODIFY:
[Specific file paths]
CONTEXT:
[What already exists that this subtask depends on]
SUCCESS CRITERIA:
[Specific completion criteria for this subtask]
IMPORTANT:
- Focus ONLY on this subtask
- Mark subtask as 'review' when complete
- Use MCP tool: mcp__task-master-ai__set_task_status
- subtask_id: [Another subtask that can run in parallel]
parent_task: [Parent task ID]
title: [Specific subtask title]
priority: [priority]
estimated_time: [time estimate]
executor_prompt: |
[Focused prompt for this specific subtask]
blocked:
- task_id: [ID]
title: [Task title]
waiting_for: [list of blocking task IDs]
becomes_ready_when: [condition for unblocking]
next_wave:
trigger: "After tasks [IDs] complete"
newly_available: [List of task IDs that will unblock]
tasks_to_execute_in_parallel: [IDs that can run together in next wave]
critical_path: [Ordered list of task IDs forming the critical path]
parallelization_instruction: |
IMPORTANT FOR CLAUDE: Deploy ALL tasks in 'EXECUTE_IN_PARALLEL' section
simultaneously using multiple Task tool invocations in a single response.
Example: If 3 tasks are listed, invoke the Task tool 3 times in one message.
verification_needed:
- task_id: [ID of any task in 'review' status]
verification_focus: [what to check]
```
**CRITICAL INSTRUCTIONS FOR CLAUDE (MAIN):**
1. When you see `EXECUTE_IN_PARALLEL`, deploy ALL listed executors at once
2. Use multiple Task tool invocations in a SINGLE response
3. Do not execute them sequentially - they must run in parallel
4. Wait for all parallel executors to complete before proceeding to next wave
**IMPORTANT NOTES**:
- Label parallel tasks clearly in `EXECUTE_IN_PARALLEL` section
- Provide complete, self-contained prompts for each executor
- Executors should mark tasks as 'review' for verification, not 'done'
- Be explicit about which tasks can run simultaneously
You are the strategic mind analyzing the entire task landscape. Make parallelization opportunities UNMISTAKABLY CLEAR to Claude.

View File

@@ -0,0 +1,38 @@
---
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)
description: Find duplicate GitHub issues
---
Find up to 3 likely duplicate issues for a given GitHub issue.
To do this, follow these steps precisely:
1. Use an agent to check if the Github issue (a) is closed, (b) does not need to be deduped (eg. because it is broad product feedback without a specific solution, or positive feedback), or (c) already has a duplicates comment that you made earlier. If so, do not proceed.
2. Use an agent to view a Github issue, and ask the agent to return a summary of the issue
3. Then, launch 5 parallel agents to search Github for duplicates of this issue, using diverse keywords and search approaches, using the summary from #1
4. Next, feed the results from #1 and #2 into another agent, so that it can filter out false positives, that are likely not actually duplicates of the original issue. If there are no duplicates remaining, do not proceed.
5. Finally, comment back on the issue with a list of up to three duplicate issues (or zero, if there are no likely duplicates)
Notes (be sure to tell this to your agents, too):
- Use `gh` to interact with Github, rather than web fetch
- Do not use other tools, beyond `gh` (eg. don't use other MCP servers, file edit, etc.)
- Make a todo list first
- For your comment, follow the following format precisely (assuming for this example that you found 3 suspected duplicates):
---
Found 3 possible duplicate issues:
1. <link to issue>
2. <link to issue>
3. <link to issue>
This issue will be automatically closed as a duplicate in 3 days.
- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment
🤖 Generated with \[Task Master Bot\]
---

View File

@@ -0,0 +1,803 @@
---
description:
globs:
alwaysApply: true
---
# Test Workflow & Development Process
## **Initial Testing Framework Setup**
Before implementing the TDD workflow, ensure your project has a proper testing framework configured. This section covers setup for different technology stacks.
### **Detecting Project Type & Framework Needs**
**AI Agent Assessment Checklist:**
1. **Language Detection**: Check for `package.json` (Node.js/JavaScript), `requirements.txt` (Python), `Cargo.toml` (Rust), etc.
2. **Existing Tests**: Look for test files (`.test.`, `.spec.`, `_test.`) or test directories
3. **Framework Detection**: Check for existing test runners in dependencies
4. **Project Structure**: Analyze directory structure for testing patterns
### **JavaScript/Node.js Projects (Jest Setup)**
#### **Prerequisites Check**
```bash
# Verify Node.js project
ls package.json # Should exist
# Check for existing testing setup
ls jest.config.js jest.config.ts # Check for Jest config
grep -E "(jest|vitest|mocha)" package.json # Check for test runners
```
#### **Jest Installation & Configuration**
**Step 1: Install Dependencies**
```bash
# Core Jest dependencies
npm install --save-dev jest
# TypeScript support (if using TypeScript)
npm install --save-dev ts-jest @types/jest
# Additional useful packages
npm install --save-dev supertest @types/supertest # For API testing
npm install --save-dev jest-watch-typeahead # Enhanced watch mode
```
**Step 2: Create Jest Configuration**
Create `jest.config.js` with the following production-ready configuration:
```javascript
/** @type {import('jest').Config} */
module.exports = {
// Use ts-jest preset for TypeScript support
preset: 'ts-jest',
// Test environment
testEnvironment: 'node',
// Roots for test discovery
roots: ['<rootDir>/src', '<rootDir>/tests'],
// Test file patterns
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
// Transform files
transform: {
'^.+\\.ts$': [
'ts-jest',
{
tsconfig: {
target: 'es2020',
module: 'commonjs',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
skipLibCheck: true,
strict: false,
noImplicitAny: false,
},
},
],
'^.+\\.js$': [
'ts-jest',
{
useESM: false,
tsconfig: {
target: 'es2020',
module: 'commonjs',
esModuleInterop: true,
allowSyntheticDefaultImports: true,
allowJs: true,
},
},
],
},
// Module file extensions
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
// Transform ignore patterns - adjust for ES modules
transformIgnorePatterns: ['node_modules/(?!(your-es-module-deps|.*\\.mjs$))'],
// Coverage configuration
collectCoverage: true,
coverageDirectory: 'coverage',
coverageReporters: [
'text', // Console output
'text-summary', // Brief summary
'lcov', // For IDE integration
'html', // Detailed HTML report
],
// Files to collect coverage from
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
'!src/**/*.test.ts',
'!src/**/index.ts', // Often just exports
'!src/generated/**', // Generated code
'!src/config/database.ts', // Database config (tested via integration)
],
// Coverage thresholds - TaskMaster standards
coverageThreshold: {
global: {
branches: 70,
functions: 80,
lines: 80,
statements: 80,
},
// Higher standards for critical business logic
'./src/utils/': {
branches: 85,
functions: 90,
lines: 90,
statements: 90,
},
'./src/middleware/': {
branches: 80,
functions: 85,
lines: 85,
statements: 85,
},
},
// Setup files
setupFilesAfterEnv: ['<rootDir>/tests/setup.ts'],
// Global teardown to prevent worker process leaks
globalTeardown: '<rootDir>/tests/teardown.ts',
// Module path mapping (if needed)
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
// Clear mocks between tests
clearMocks: true,
// Restore mocks after each test
restoreMocks: true,
// Global test timeout
testTimeout: 10000,
// Projects for different test types
projects: [
// Unit tests - for pure functions only
{
displayName: 'unit',
testMatch: ['<rootDir>/src/**/*.test.ts'],
testPathIgnorePatterns: ['.*\\.integration\\.test\\.ts$', '/tests/'],
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
'!src/**/*.test.ts',
'!src/**/*.integration.test.ts',
],
coverageThreshold: {
global: {
branches: 70,
functions: 80,
lines: 80,
statements: 80,
},
},
},
// Integration tests - real database/services
{
displayName: 'integration',
testMatch: [
'<rootDir>/src/**/*.integration.test.ts',
'<rootDir>/tests/integration/**/*.test.ts',
],
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['<rootDir>/tests/setup/integration.ts'],
testTimeout: 10000,
},
// E2E tests - full workflows
{
displayName: 'e2e',
testMatch: ['<rootDir>/tests/e2e/**/*.test.ts'],
preset: 'ts-jest',
testEnvironment: 'node',
setupFilesAfterEnv: ['<rootDir>/tests/setup/e2e.ts'],
testTimeout: 30000,
},
],
// Verbose output for better debugging
verbose: true,
// Run projects sequentially to avoid conflicts
maxWorkers: 1,
// Enable watch mode plugins
watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'],
};
```
**Step 3: Update package.json Scripts**
Add these scripts to your `package.json`:
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:unit": "jest --selectProjects unit",
"test:integration": "jest --selectProjects integration",
"test:e2e": "jest --selectProjects e2e",
"test:ci": "jest --ci --coverage --watchAll=false"
}
}
```
**Step 4: Create Test Setup Files**
Create essential test setup files:
```typescript
// tests/setup.ts - Global setup
import { jest } from '@jest/globals';
// Global test configuration
beforeAll(() => {
// Set test timeout
jest.setTimeout(10000);
});
afterEach(() => {
// Clean up mocks after each test
jest.clearAllMocks();
});
```
```typescript
// tests/setup/integration.ts - Integration test setup
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
beforeAll(async () => {
// Connect to test database
await prisma.$connect();
});
afterAll(async () => {
// Cleanup and disconnect
await prisma.$disconnect();
});
beforeEach(async () => {
// Clean test data before each test
// Add your cleanup logic here
});
```
```typescript
// tests/teardown.ts - Global teardown
export default async () => {
// Global cleanup after all tests
console.log('Global test teardown complete');
};
```
**Step 5: Create Initial Test Structure**
```bash
# Create test directories
mkdir -p tests/{setup,fixtures,unit,integration,e2e}
mkdir -p tests/unit/src/{utils,services,middleware}
# Create sample test fixtures
mkdir tests/fixtures
```
### **Generic Testing Framework Setup (Any Language)**
#### **Framework Selection Guide**
**Python Projects:**
- **pytest**: Recommended for most Python projects
- **unittest**: Built-in, suitable for simple projects
- **Coverage**: Use `coverage.py` for code coverage
```bash
# Python setup example
pip install pytest pytest-cov
echo "[tool:pytest]" > pytest.ini
echo "testpaths = tests" >> pytest.ini
echo "addopts = --cov=src --cov-report=html --cov-report=term" >> pytest.ini
```
**Go Projects:**
- **Built-in testing**: Use Go's built-in `testing` package
- **Coverage**: Built-in with `go test -cover`
```bash
# Go setup example
go mod init your-project
mkdir -p tests
# Tests are typically *_test.go files alongside source
```
**Rust Projects:**
- **Built-in testing**: Use Rust's built-in test framework
- **cargo-tarpaulin**: For coverage analysis
```bash
# Rust setup example
cargo new your-project
cd your-project
cargo install cargo-tarpaulin # For coverage
```
**Java Projects:**
- **JUnit 5**: Modern testing framework
- **Maven/Gradle**: Build tools with testing integration
```xml
<!-- Maven pom.xml example -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
```
#### **Universal Testing Principles**
**Coverage Standards (Adapt to Your Language):**
- **Global Minimum**: 70-80% line coverage
- **Critical Code**: 85-90% coverage
- **New Features**: Must meet or exceed standards
- **Legacy Code**: Gradual improvement strategy
**Test Organization:**
- **Unit Tests**: Fast, isolated, no external dependencies
- **Integration Tests**: Test component interactions
- **E2E Tests**: Test complete user workflows
- **Performance Tests**: Load and stress testing (if applicable)
**Naming Conventions:**
- **Test Files**: `*.test.*`, `*_test.*`, or language-specific patterns
- **Test Functions**: Descriptive names (e.g., `should_return_error_for_invalid_input`)
- **Test Directories**: Organized by test type and mirroring source structure
#### **TaskMaster Integration for Any Framework**
**Document Testing Setup in Subtasks:**
```bash
# Update subtask with testing framework setup
task-master update-subtask --id=X.Y --prompt="Testing framework setup:
- Installed [Framework Name] with coverage support
- Configured [Coverage Tool] with thresholds: 80% lines, 70% branches
- Created test directory structure: unit/, integration/, e2e/
- Added test scripts to build configuration
- All setup tests passing"
```
**Testing Framework Verification:**
```bash
# Verify setup works
[test-command] # e.g., npm test, pytest, go test, cargo test
# Check coverage reporting
[coverage-command] # e.g., npm run test:coverage
# Update task with verification
task-master update-subtask --id=X.Y --prompt="Testing framework verified:
- Sample tests running successfully
- Coverage reporting functional
- CI/CD integration ready
- Ready to begin TDD workflow"
```
## **Test-Driven Development (TDD) Integration**
### **Core TDD Cycle with Jest**
```bash
# 1. Start development with watch mode
npm run test:watch
# 2. Write failing test first
# Create test file: src/utils/newFeature.test.ts
# Write test that describes expected behavior
# 3. Implement minimum code to make test pass
# 4. Refactor while keeping tests green
# 5. Add edge cases and error scenarios
```
### **TDD Workflow Per Subtask**
```bash
# When starting a new subtask:
task-master set-status --id=4.1 --status=in-progress
# Begin TDD cycle:
npm run test:watch # Keep running during development
# Document TDD progress in subtask:
task-master update-subtask --id=4.1 --prompt="TDD Progress:
- Written 3 failing tests for core functionality
- Implemented basic feature, tests now passing
- Adding edge case tests for error handling"
# Complete subtask with test summary:
task-master update-subtask --id=4.1 --prompt="Implementation complete:
- Feature implemented with 8 unit tests
- Coverage: 95% statements, 88% branches
- All tests passing, TDD cycle complete"
```
## **Testing Commands & Usage**
### **Development Commands**
```bash
# Primary development command - use during coding
npm run test:watch # Watch mode with Jest
npm run test:watch -- --testNamePattern="auth" # Watch specific tests
# Targeted testing during development
npm run test:unit # Run only unit tests
npm run test:unit -- --coverage # Unit tests with coverage
# Integration testing when APIs are ready
npm run test:integration # Run integration tests
npm run test:integration -- --detectOpenHandles # Debug hanging tests
# End-to-end testing for workflows
npm run test:e2e # Run E2E tests
npm run test:e2e -- --timeout=30000 # Extended timeout for E2E
```
### **Quality Assurance Commands**
```bash
# Full test suite with coverage (before commits)
npm run test:coverage # Complete coverage analysis
# All tests (CI/CD pipeline)
npm test # Run all test projects
# Specific test file execution
npm test -- auth.test.ts # Run specific test file
npm test -- --testNamePattern="should handle errors" # Run specific tests
```
## **Test Implementation Patterns**
### **Unit Test Development**
```typescript
// ✅ DO: Follow established patterns from auth.test.ts
describe('FeatureName', () => {
beforeEach(() => {
jest.clearAllMocks();
// Setup mocks with proper typing
});
describe('functionName', () => {
it('should handle normal case', () => {
// Test implementation with specific assertions
});
it('should throw error for invalid input', async () => {
// Error scenario testing
await expect(functionName(invalidInput))
.rejects.toThrow('Specific error message');
});
});
});
```
### **Integration Test Development**
```typescript
// ✅ DO: Use supertest for API endpoint testing
import request from 'supertest';
import { app } from '../../src/app';
describe('POST /api/auth/register', () => {
beforeEach(async () => {
await integrationTestUtils.cleanupTestData();
});
it('should register user successfully', async () => {
const userData = createTestUser();
const response = await request(app)
.post('/api/auth/register')
.send(userData)
.expect(201);
expect(response.body).toMatchObject({
id: expect.any(String),
email: userData.email
});
// Verify database state
const user = await prisma.user.findUnique({
where: { email: userData.email }
});
expect(user).toBeTruthy();
});
});
```
### **E2E Test Development**
```typescript
// ✅ DO: Test complete user workflows
describe('User Authentication Flow', () => {
it('should complete registration → login → protected access', async () => {
// Step 1: Register
const userData = createTestUser();
await request(app)
.post('/api/auth/register')
.send(userData)
.expect(201);
// Step 2: Login
const loginResponse = await request(app)
.post('/api/auth/login')
.send({ email: userData.email, password: userData.password })
.expect(200);
const { token } = loginResponse.body;
// Step 3: Access protected resource
await request(app)
.get('/api/profile')
.set('Authorization', `Bearer ${token}`)
.expect(200);
}, 30000); // Extended timeout for E2E
});
```
## **Mocking & Test Utilities**
### **Established Mocking Patterns**
```typescript
// ✅ DO: Use established bcrypt mocking pattern
jest.mock('bcrypt');
import bcrypt from 'bcrypt';
const mockHash = bcrypt.hash as jest.MockedFunction<typeof bcrypt.hash>;
const mockCompare = bcrypt.compare as jest.MockedFunction<typeof bcrypt.compare>;
// ✅ DO: Use Prisma mocking for unit tests
jest.mock('@prisma/client', () => ({
PrismaClient: jest.fn().mockImplementation(() => ({
user: {
create: jest.fn(),
findUnique: jest.fn(),
},
$connect: jest.fn(),
$disconnect: jest.fn(),
})),
}));
```
### **Test Fixtures Usage**
```typescript
// ✅ DO: Use centralized test fixtures
import { createTestUser, adminUser, invalidUser } from '../fixtures/users';
describe('User Service', () => {
it('should handle admin user creation', async () => {
const userData = createTestUser(adminUser);
// Test implementation
});
it('should reject invalid user data', async () => {
const userData = createTestUser(invalidUser);
// Error testing
});
});
```
## **Coverage Standards & Monitoring**
### **Coverage Thresholds**
- **Global Standards**: 80% lines/functions, 70% branches
- **Critical Code**: 90% utils, 85% middleware
- **New Features**: Must meet or exceed global thresholds
- **Legacy Code**: Gradual improvement with each change
### **Coverage Reporting & Analysis**
```bash
# Generate coverage reports
npm run test:coverage
# View detailed HTML report
open coverage/lcov-report/index.html
# Coverage files generated:
# - coverage/lcov-report/index.html # Detailed HTML report
# - coverage/lcov.info # LCOV format for IDE integration
# - coverage/coverage-final.json # JSON format for tooling
```
### **Coverage Quality Checks**
```typescript
// ✅ DO: Test all code paths
describe('validateInput', () => {
it('should return true for valid input', () => {
expect(validateInput('valid')).toBe(true);
});
it('should return false for various invalid inputs', () => {
expect(validateInput('')).toBe(false); // Empty string
expect(validateInput(null)).toBe(false); // Null value
expect(validateInput(undefined)).toBe(false); // Undefined
});
it('should throw for unexpected input types', () => {
expect(() => validateInput(123)).toThrow('Invalid input type');
});
});
```
## **Testing During Development Phases**
### **Feature Development Phase**
```bash
# 1. Start feature development
task-master set-status --id=X.Y --status=in-progress
# 2. Begin TDD cycle
npm run test:watch
# 3. Document test progress in subtask
task-master update-subtask --id=X.Y --prompt="Test development:
- Created test file with 5 failing tests
- Implemented core functionality
- Tests passing, adding error scenarios"
# 4. Verify coverage before completion
npm run test:coverage
# 5. Update subtask with final test status
task-master update-subtask --id=X.Y --prompt="Testing complete:
- 12 unit tests with full coverage
- All edge cases and error scenarios covered
- Ready for integration testing"
```
### **Integration Testing Phase**
```bash
# After API endpoints are implemented
npm run test:integration
# Update integration test templates
# Replace placeholder tests with real endpoint calls
# Document integration test results
task-master update-subtask --id=X.Y --prompt="Integration tests:
- Updated auth endpoint tests
- Database integration verified
- All HTTP status codes and responses tested"
```
### **Pre-Commit Testing Phase**
```bash
# Before committing code
npm run test:coverage # Verify all tests pass with coverage
npm run test:unit # Quick unit test verification
npm run test:integration # Integration test verification (if applicable)
# Commit pattern for test updates
git add tests/ src/**/*.test.ts
git commit -m "test(task-X): Add comprehensive tests for Feature Y
- Unit tests with 95% coverage (exceeds 90% threshold)
- Integration tests for API endpoints
- Test fixtures for data generation
- Proper mocking patterns established
Task X: Feature Y - Testing complete"
```
## **Error Handling & Debugging**
### **Test Debugging Techniques**
```typescript
// ✅ DO: Use test utilities for debugging
import { testUtils } from '../setup';
it('should debug complex operation', () => {
testUtils.withConsole(() => {
// Console output visible only for this test
console.log('Debug info:', complexData);
service.complexOperation();
});
});
// ✅ DO: Use proper async debugging
it('should handle async operations', async () => {
const promise = service.asyncOperation();
// Test intermediate state
expect(service.isProcessing()).toBe(true);
const result = await promise;
expect(result).toBe('expected');
expect(service.isProcessing()).toBe(false);
});
```
### **Common Test Issues & Solutions**
```bash
# Hanging tests (common with database connections)
npm run test:integration -- --detectOpenHandles
# Memory leaks in tests
npm run test:unit -- --logHeapUsage
# Slow tests identification
npm run test:coverage -- --verbose
# Mock not working properly
# Check: mock is declared before imports
# Check: jest.clearAllMocks() in beforeEach
# Check: TypeScript typing is correct
```
## **Continuous Integration Integration**
### **CI/CD Pipeline Testing**
```yaml
# Example GitHub Actions integration
- name: Run tests
run: |
npm ci
npm run test:coverage
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
file: ./coverage/lcov.info
```
### **Pre-commit Hooks**
```bash
# Setup pre-commit testing (recommended)
# In package.json scripts:
"pre-commit": "npm run test:unit && npm run test:integration"
# Husky integration example:
npx husky add .husky/pre-commit "npm run test:unit"
```
## **Test Maintenance & Evolution**
### **Adding Tests for New Features**
1. **Create test file** alongside source code or in `tests/unit/`
2. **Follow established patterns** from `src/utils/auth.test.ts`
3. **Use existing fixtures** from `tests/fixtures/`
4. **Apply proper mocking** patterns for dependencies
5. **Meet coverage thresholds** for the module
### **Updating Integration/E2E Tests**
1. **Update templates** in `tests/integration/` when APIs change
2. **Modify E2E workflows** in `tests/e2e/` for new user journeys
3. **Update test fixtures** for new data requirements
4. **Maintain database cleanup** utilities
### **Test Performance Optimization**
- **Parallel execution**: Jest runs tests in parallel by default
- **Test isolation**: Use proper setup/teardown for independence
- **Mock optimization**: Mock heavy dependencies appropriately
- **Database efficiency**: Use transaction rollbacks where possible
---
**Key References:**
- [Testing Standards](mdc:.cursor/rules/tests.mdc)
- [Git Workflow](mdc:.cursor/rules/git_workflow.mdc)
- [Development Workflow](mdc:.cursor/rules/dev_workflow.mdc)
- [Jest Configuration](mdc:jest.config.js)

45
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,45 @@
# What type of PR is this?
<!-- Check one -->
- [ ] 🐛 Bug fix
- [ ] ✨ Feature
- [ ] 🔌 Integration
- [ ] 📝 Docs
- [ ] 🧹 Refactor
- [ ] Other:
## Description
<!-- What does this PR do? -->
## Related Issues
<!-- Link issues: Fixes #123 -->
## How to Test This
<!-- Quick steps to verify the changes work -->
```bash
# Example commands or steps
```
**Expected result:**
<!-- What should happen? -->
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check` (or `npm run format` to fix)
- [ ] Addressed CodeRabbit comments (if any)
- [ ] Linked related issues (if any)
- [ ] Manually tested the changes
## Changelog Entry
<!-- One line describing the change for users -->
<!-- Example: "Added Kiro IDE integration with automatic task status updates" -->
---
### For Maintainers
- [ ] PR title follows conventional commits
- [ ] Target branch correct
- [ ] Labels added
- [ ] Milestone assigned (if applicable)

39
.github/PULL_REQUEST_TEMPLATE/bugfix.md vendored Normal file
View File

@@ -0,0 +1,39 @@
## 🐛 Bug Fix
### 🔍 Bug Description
<!-- Describe the bug -->
### 🔗 Related Issues
<!-- Fixes #123 -->
### ✨ Solution
<!-- How does this PR fix the bug? -->
## How to Test
### Steps that caused the bug:
1.
2.
**Before fix:**
**After fix:**
### Quick verification:
```bash
# Commands to verify the fix
```
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check`
- [ ] Addressed CodeRabbit comments
- [ ] Added unit tests (if applicable)
- [ ] Manually verified the fix works
---
### For Maintainers
- [ ] Root cause identified
- [ ] Fix doesn't introduce new issues
- [ ] CI passes

View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 🐛 Bug Fix
url: https://github.com/eyaltoledano/claude-task-master/compare/next...HEAD?template=bugfix.md
about: Fix a bug in Task Master
- name: ✨ New Feature
url: https://github.com/eyaltoledano/claude-task-master/compare/next...HEAD?template=feature.md
about: Add a new feature to Task Master
- name: 🔌 New Integration
url: https://github.com/eyaltoledano/claude-task-master/compare/next...HEAD?template=integration.md
about: Add support for a new tool, IDE, or platform

View File

@@ -0,0 +1,49 @@
## ✨ New Feature
### 📋 Feature Description
<!-- Brief description -->
### 🎯 Problem Statement
<!-- What problem does this feature solve? Why is it needed? -->
### 💡 Solution
<!-- How does this feature solve the problem? What's the approach? -->
### 🔗 Related Issues
<!-- Link related issues: Fixes #123, Part of #456 -->
## How to Use It
### Quick Start
```bash
# Basic usage example
```
### Example
<!-- Show a real use case -->
```bash
# Practical example
```
**What you should see:**
<!-- Expected behavior -->
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check`
- [ ] Addressed CodeRabbit comments
- [ ] Added tests for new functionality
- [ ] Manually tested in CLI mode
- [ ] Manually tested in MCP mode (if applicable)
## Changelog Entry
<!-- One-liner for release notes -->
---
### For Maintainers
- [ ] Feature aligns with project vision
- [ ] CIs pass
- [ ] Changeset file exists

View File

@@ -0,0 +1,53 @@
# 🔌 New Integration
## What tool/IDE is being integrated?
<!-- Name and brief description -->
## What can users do with it?
<!-- Key benefits -->
## How to Enable
### Setup
```bash
task-master rules add [name]
# Any other setup steps
```
### Example Usage
<!-- Show it in action -->
```bash
# Real example
```
### Natural Language Hooks (if applicable)
```
"When tests pass, mark task as done"
# Other examples
```
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check`
- [ ] Addressed CodeRabbit comments
- [ ] Integration fully tested with target tool/IDE
- [ ] Error scenarios tested
- [ ] Added integration tests
- [ ] Documentation includes setup guide
- [ ] Examples are working and clear
---
## For Maintainers
- [ ] Integration stability verified
- [ ] Documentation comprehensive
- [ ] Examples working

View File

@@ -0,0 +1,259 @@
#!/usr/bin/env node
async function githubRequest(endpoint, token, method = 'GET', body) {
const response = await fetch(`https://api.github.com${endpoint}`, {
method,
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github.v3+json',
'User-Agent': 'auto-close-duplicates-script',
...(body && { 'Content-Type': 'application/json' })
},
...(body && { body: JSON.stringify(body) })
});
if (!response.ok) {
throw new Error(
`GitHub API request failed: ${response.status} ${response.statusText}`
);
}
return response.json();
}
function extractDuplicateIssueNumber(commentBody) {
const match = commentBody.match(/#(\d+)/);
return match ? parseInt(match[1], 10) : null;
}
async function closeIssueAsDuplicate(
owner,
repo,
issueNumber,
duplicateOfNumber,
token
) {
await githubRequest(
`/repos/${owner}/${repo}/issues/${issueNumber}`,
token,
'PATCH',
{
state: 'closed',
state_reason: 'not_planned',
labels: ['duplicate']
}
);
await githubRequest(
`/repos/${owner}/${repo}/issues/${issueNumber}/comments`,
token,
'POST',
{
body: `This issue has been automatically closed as a duplicate of #${duplicateOfNumber}.
If this is incorrect, please re-open this issue or create a new one.
🤖 Generated with [Task Master Bot]`
}
);
}
async function autoCloseDuplicates() {
console.log('[DEBUG] Starting auto-close duplicates script');
const token = process.env.GITHUB_TOKEN;
if (!token) {
throw new Error('GITHUB_TOKEN environment variable is required');
}
console.log('[DEBUG] GitHub token found');
const owner = process.env.GITHUB_REPOSITORY_OWNER || 'eyaltoledano';
const repo = process.env.GITHUB_REPOSITORY_NAME || 'claude-task-master';
console.log(`[DEBUG] Repository: ${owner}/${repo}`);
const threeDaysAgo = new Date();
threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);
console.log(
`[DEBUG] Checking for duplicate comments older than: ${threeDaysAgo.toISOString()}`
);
console.log('[DEBUG] Fetching open issues created more than 3 days ago...');
const allIssues = [];
let page = 1;
const perPage = 100;
const MAX_PAGES = 50; // Increase limit for larger repos
let foundRecentIssue = false;
while (true) {
const pageIssues = await githubRequest(
`/repos/${owner}/${repo}/issues?state=open&per_page=${perPage}&page=${page}&sort=created&direction=desc`,
token
);
if (pageIssues.length === 0) break;
// Filter for issues created more than 3 days ago
const oldEnoughIssues = pageIssues.filter(
(issue) => new Date(issue.created_at) <= threeDaysAgo
);
allIssues.push(...oldEnoughIssues);
// If all issues on this page are newer than 3 days, we can stop
if (oldEnoughIssues.length === 0 && page === 1) {
foundRecentIssue = true;
break;
}
// If we found some old issues but not all, continue to next page
// as there might be more old issues
page++;
// Safety limit to avoid infinite loops
if (page > MAX_PAGES) {
console.log(`[WARNING] Reached maximum page limit of ${MAX_PAGES}`);
break;
}
}
const issues = allIssues;
console.log(`[DEBUG] Found ${issues.length} open issues`);
let processedCount = 0;
let candidateCount = 0;
for (const issue of issues) {
processedCount++;
console.log(
`[DEBUG] Processing issue #${issue.number} (${processedCount}/${issues.length}): ${issue.title}`
);
console.log(`[DEBUG] Fetching comments for issue #${issue.number}...`);
const comments = await githubRequest(
`/repos/${owner}/${repo}/issues/${issue.number}/comments`,
token
);
console.log(
`[DEBUG] Issue #${issue.number} has ${comments.length} comments`
);
const dupeComments = comments.filter(
(comment) =>
comment.body.includes('Found') &&
comment.body.includes('possible duplicate') &&
comment.user.type === 'Bot'
);
console.log(
`[DEBUG] Issue #${issue.number} has ${dupeComments.length} duplicate detection comments`
);
if (dupeComments.length === 0) {
console.log(
`[DEBUG] Issue #${issue.number} - no duplicate comments found, skipping`
);
continue;
}
const lastDupeComment = dupeComments[dupeComments.length - 1];
const dupeCommentDate = new Date(lastDupeComment.created_at);
console.log(
`[DEBUG] Issue #${
issue.number
} - most recent duplicate comment from: ${dupeCommentDate.toISOString()}`
);
if (dupeCommentDate > threeDaysAgo) {
console.log(
`[DEBUG] Issue #${issue.number} - duplicate comment is too recent, skipping`
);
continue;
}
console.log(
`[DEBUG] Issue #${
issue.number
} - duplicate comment is old enough (${Math.floor(
(Date.now() - dupeCommentDate.getTime()) / (1000 * 60 * 60 * 24)
)} days)`
);
const commentsAfterDupe = comments.filter(
(comment) => new Date(comment.created_at) > dupeCommentDate
);
console.log(
`[DEBUG] Issue #${issue.number} - ${commentsAfterDupe.length} comments after duplicate detection`
);
if (commentsAfterDupe.length > 0) {
console.log(
`[DEBUG] Issue #${issue.number} - has activity after duplicate comment, skipping`
);
continue;
}
console.log(
`[DEBUG] Issue #${issue.number} - checking reactions on duplicate comment...`
);
const reactions = await githubRequest(
`/repos/${owner}/${repo}/issues/comments/${lastDupeComment.id}/reactions`,
token
);
console.log(
`[DEBUG] Issue #${issue.number} - duplicate comment has ${reactions.length} reactions`
);
const authorThumbsDown = reactions.some(
(reaction) =>
reaction.user.id === issue.user.id && reaction.content === '-1'
);
console.log(
`[DEBUG] Issue #${issue.number} - author thumbs down reaction: ${authorThumbsDown}`
);
if (authorThumbsDown) {
console.log(
`[DEBUG] Issue #${issue.number} - author disagreed with duplicate detection, skipping`
);
continue;
}
const duplicateIssueNumber = extractDuplicateIssueNumber(
lastDupeComment.body
);
if (!duplicateIssueNumber) {
console.log(
`[DEBUG] Issue #${issue.number} - could not extract duplicate issue number from comment, skipping`
);
continue;
}
candidateCount++;
const issueUrl = `https://github.com/${owner}/${repo}/issues/${issue.number}`;
try {
console.log(
`[INFO] Auto-closing issue #${issue.number} as duplicate of #${duplicateIssueNumber}: ${issueUrl}`
);
await closeIssueAsDuplicate(
owner,
repo,
issue.number,
duplicateIssueNumber,
token
);
console.log(
`[SUCCESS] Successfully closed issue #${issue.number} as duplicate of #${duplicateIssueNumber}`
);
} catch (error) {
console.error(
`[ERROR] Failed to close issue #${issue.number} as duplicate: ${error}`
);
}
}
console.log(
`[DEBUG] Script completed. Processed ${processedCount} issues, found ${candidateCount} candidates for auto-close`
);
}
autoCloseDuplicates().catch(console.error);

View File

@@ -0,0 +1,178 @@
#!/usr/bin/env node
async function githubRequest(endpoint, token, method = 'GET', body) {
const response = await fetch(`https://api.github.com${endpoint}`, {
method,
headers: {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github.v3+json',
'User-Agent': 'backfill-duplicate-comments-script',
...(body && { 'Content-Type': 'application/json' })
},
...(body && { body: JSON.stringify(body) })
});
if (!response.ok) {
throw new Error(
`GitHub API request failed: ${response.status} ${response.statusText}`
);
}
return response.json();
}
async function triggerDedupeWorkflow(
owner,
repo,
issueNumber,
token,
dryRun = true
) {
if (dryRun) {
console.log(
`[DRY RUN] Would trigger dedupe workflow for issue #${issueNumber}`
);
return;
}
await githubRequest(
`/repos/${owner}/${repo}/actions/workflows/claude-dedupe-issues.yml/dispatches`,
token,
'POST',
{
ref: 'main',
inputs: {
issue_number: issueNumber.toString()
}
}
);
}
async function backfillDuplicateComments() {
console.log('[DEBUG] Starting backfill duplicate comments script');
const token = process.env.GITHUB_TOKEN;
if (!token) {
throw new Error(`GITHUB_TOKEN environment variable is required
Usage:
node .github/scripts/backfill-duplicate-comments.mjs
Environment Variables:
GITHUB_TOKEN - GitHub personal access token with repo and actions permissions (required)
DRY_RUN - Set to "false" to actually trigger workflows (default: true for safety)
DAYS_BACK - How many days back to look for old issues (default: 90)`);
}
console.log('[DEBUG] GitHub token found');
const owner = process.env.GITHUB_REPOSITORY_OWNER || 'eyaltoledano';
const repo = process.env.GITHUB_REPOSITORY_NAME || 'claude-task-master';
const dryRun = process.env.DRY_RUN !== 'false';
const daysBack = parseInt(process.env.DAYS_BACK || '90', 10);
console.log(`[DEBUG] Repository: ${owner}/${repo}`);
console.log(`[DEBUG] Dry run mode: ${dryRun}`);
console.log(`[DEBUG] Looking back ${daysBack} days`);
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysBack);
console.log(
`[DEBUG] Fetching issues created since ${cutoffDate.toISOString()}...`
);
const allIssues = [];
let page = 1;
const perPage = 100;
while (true) {
const pageIssues = await githubRequest(
`/repos/${owner}/${repo}/issues?state=all&per_page=${perPage}&page=${page}&since=${cutoffDate.toISOString()}`,
token
);
if (pageIssues.length === 0) break;
allIssues.push(...pageIssues);
page++;
// Safety limit to avoid infinite loops
if (page > 100) {
console.log('[DEBUG] Reached page limit, stopping pagination');
break;
}
}
console.log(
`[DEBUG] Found ${allIssues.length} issues from the last ${daysBack} days`
);
let processedCount = 0;
let candidateCount = 0;
let triggeredCount = 0;
for (const issue of allIssues) {
processedCount++;
console.log(
`[DEBUG] Processing issue #${issue.number} (${processedCount}/${allIssues.length}): ${issue.title}`
);
console.log(`[DEBUG] Fetching comments for issue #${issue.number}...`);
const comments = await githubRequest(
`/repos/${owner}/${repo}/issues/${issue.number}/comments`,
token
);
console.log(
`[DEBUG] Issue #${issue.number} has ${comments.length} comments`
);
// Look for existing duplicate detection comments (from the dedupe bot)
const dupeDetectionComments = comments.filter(
(comment) =>
comment.body.includes('Found') &&
comment.body.includes('possible duplicate') &&
comment.user.type === 'Bot'
);
console.log(
`[DEBUG] Issue #${issue.number} has ${dupeDetectionComments.length} duplicate detection comments`
);
// Skip if there's already a duplicate detection comment
if (dupeDetectionComments.length > 0) {
console.log(
`[DEBUG] Issue #${issue.number} already has duplicate detection comment, skipping`
);
continue;
}
candidateCount++;
const issueUrl = `https://github.com/${owner}/${repo}/issues/${issue.number}`;
try {
console.log(
`[INFO] ${dryRun ? '[DRY RUN] ' : ''}Triggering dedupe workflow for issue #${issue.number}: ${issueUrl}`
);
await triggerDedupeWorkflow(owner, repo, issue.number, token, dryRun);
if (!dryRun) {
console.log(
`[SUCCESS] Successfully triggered dedupe workflow for issue #${issue.number}`
);
}
triggeredCount++;
} catch (error) {
console.error(
`[ERROR] Failed to trigger workflow for issue #${issue.number}: ${error}`
);
}
// Add a delay between workflow triggers to avoid overwhelming the system
await new Promise((resolve) => setTimeout(resolve, 1000));
}
console.log(
`[DEBUG] Script completed. Processed ${processedCount} issues, found ${candidateCount} candidates without duplicate comments, ${dryRun ? 'would trigger' : 'triggered'} ${triggeredCount} workflows`
);
}
backfillDuplicateComments().catch(console.error);

102
.github/scripts/check-pre-release-mode.mjs vendored Executable file
View File

@@ -0,0 +1,102 @@
#!/usr/bin/env node
import { readFileSync, existsSync } from 'node:fs';
import { join, dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Get context from command line argument or environment
const context = process.argv[2] || process.env.GITHUB_WORKFLOW || 'manual';
function findRootDir(startDir) {
let currentDir = resolve(startDir);
while (currentDir !== '/') {
if (existsSync(join(currentDir, 'package.json'))) {
try {
const pkg = JSON.parse(
readFileSync(join(currentDir, 'package.json'), 'utf8')
);
if (pkg.name === 'task-master-ai' || pkg.repository) {
return currentDir;
}
} catch {}
}
currentDir = dirname(currentDir);
}
throw new Error('Could not find root directory');
}
function checkPreReleaseMode() {
console.log('🔍 Checking if branch is in pre-release mode...');
const rootDir = findRootDir(__dirname);
const preJsonPath = join(rootDir, '.changeset', 'pre.json');
// Check if pre.json exists
if (!existsSync(preJsonPath)) {
console.log('✅ Not in active pre-release mode - safe to proceed');
process.exit(0);
}
try {
// Read and parse pre.json
const preJsonContent = readFileSync(preJsonPath, 'utf8');
const preJson = JSON.parse(preJsonContent);
// Check if we're in active pre-release mode
if (preJson.mode === 'pre') {
console.error('❌ ERROR: This branch is in active pre-release mode!');
console.error('');
// Provide context-specific error messages
if (context === 'Release Check' || context === 'pull_request') {
console.error(
'Pre-release mode must be exited before merging to main.'
);
console.error('');
console.error(
'To fix this, run the following commands in your branch:'
);
console.error(' npx changeset pre exit');
console.error(' git add -u');
console.error(' git commit -m "chore: exit pre-release mode"');
console.error(' git push');
console.error('');
console.error('Then update this pull request.');
} else if (context === 'Release' || context === 'main') {
console.error(
'Pre-release mode should only be used on feature branches, not main.'
);
console.error('');
console.error('To fix this, run the following commands locally:');
console.error(' npx changeset pre exit');
console.error(' git add -u');
console.error(' git commit -m "chore: exit pre-release mode"');
console.error(' git push origin main');
console.error('');
console.error('Then re-run this workflow.');
} else {
console.error('Pre-release mode must be exited before proceeding.');
console.error('');
console.error('To fix this, run the following commands:');
console.error(' npx changeset pre exit');
console.error(' git add -u');
console.error(' git commit -m "chore: exit pre-release mode"');
console.error(' git push');
}
process.exit(1);
}
console.log('✅ Not in active pre-release mode - safe to proceed');
process.exit(0);
} catch (error) {
console.error(`❌ ERROR: Unable to parse .changeset/pre.json aborting.`);
console.error(`Error details: ${error.message}`);
process.exit(1);
}
}
// Run the check
checkPreReleaseMode();

30
.github/scripts/release.mjs vendored Executable file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env node
import { existsSync, unlinkSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { findRootDir, runCommand } from './utils.mjs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = findRootDir(__dirname);
console.log('🚀 Starting release process...');
// Double-check we're not in pre-release mode (safety net)
const preJsonPath = join(rootDir, '.changeset', 'pre.json');
if (existsSync(preJsonPath)) {
console.log('⚠️ Warning: pre.json still exists. Removing it...');
unlinkSync(preJsonPath);
}
// Check if the extension version has changed and tag it
// This prevents changeset from trying to publish the private package
runCommand('node', [join(__dirname, 'tag-extension.mjs')]);
// Run changeset publish for npm packages
runCommand('npx', ['changeset', 'publish']);
console.log('✅ Release process completed!');
// The extension tag (if created) will trigger the extension-release workflow

33
.github/scripts/tag-extension.mjs vendored Executable file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env node
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { findRootDir, createAndPushTag } from './utils.mjs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const rootDir = findRootDir(__dirname);
// Read the extension's package.json
const extensionDir = join(rootDir, 'apps', 'extension');
const pkgPath = join(extensionDir, 'package.json');
let pkg;
try {
const pkgContent = readFileSync(pkgPath, 'utf8');
pkg = JSON.parse(pkgContent);
} catch (error) {
console.error('Failed to read package.json:', error.message);
process.exit(1);
}
// Ensure we have required fields
assert(pkg.name, 'package.json must have a name field');
assert(pkg.version, 'package.json must have a version field');
const tag = `${pkg.name}@${pkg.version}`;
// Create and push the tag if it doesn't exist
createAndPushTag(tag);

88
.github/scripts/utils.mjs vendored Executable file
View File

@@ -0,0 +1,88 @@
#!/usr/bin/env node
import { spawnSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { join, dirname, resolve } from 'node:path';
// Find the root directory by looking for package.json with task-master-ai
export function findRootDir(startDir) {
let currentDir = resolve(startDir);
while (currentDir !== '/') {
const pkgPath = join(currentDir, 'package.json');
try {
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
if (pkg.name === 'task-master-ai' || pkg.repository) {
return currentDir;
}
} catch {}
currentDir = dirname(currentDir);
}
throw new Error('Could not find root directory');
}
// Run a command with proper error handling
export function runCommand(command, args = [], options = {}) {
console.log(`Running: ${command} ${args.join(' ')}`);
const result = spawnSync(command, args, {
encoding: 'utf8',
stdio: 'inherit',
...options
});
if (result.status !== 0) {
console.error(`Command failed with exit code ${result.status}`);
process.exit(result.status);
}
return result;
}
// Get package version from a package.json file
export function getPackageVersion(packagePath) {
try {
const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
return pkg.version;
} catch (error) {
console.error(
`Failed to read package version from ${packagePath}:`,
error.message
);
process.exit(1);
}
}
// Check if a git tag exists on remote
export function tagExistsOnRemote(tag, remote = 'origin') {
const result = spawnSync('git', ['ls-remote', remote, tag], {
encoding: 'utf8'
});
return result.status === 0 && result.stdout.trim() !== '';
}
// Create and push a git tag if it doesn't exist
export function createAndPushTag(tag, remote = 'origin') {
// Check if tag already exists
if (tagExistsOnRemote(tag, remote)) {
console.log(`Tag ${tag} already exists on remote, skipping`);
return false;
}
console.log(`Creating new tag: ${tag}`);
// Create the tag locally
const tagResult = spawnSync('git', ['tag', tag]);
if (tagResult.status !== 0) {
console.error('Failed to create tag:', tagResult.error || tagResult.stderr);
process.exit(1);
}
// Push the tag to remote
const pushResult = spawnSync('git', ['push', remote, tag]);
if (pushResult.status !== 0) {
console.error('Failed to push tag:', pushResult.error || pushResult.stderr);
process.exit(1);
}
console.log(`✅ Successfully created and pushed tag: ${tag}`);
return true;
}

View File

@@ -0,0 +1,31 @@
name: Auto-close duplicate issues
# description: Auto-closes issues that are duplicates of existing issues
on:
schedule:
- cron: "0 9 * * *" # Runs daily at 9 AM UTC
workflow_dispatch:
jobs:
auto-close-duplicates:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
issues: write # Need write permission to close issues and add comments
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Auto-close duplicate issues
run: node .github/scripts/auto-close-duplicates.mjs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}

View File

@@ -0,0 +1,46 @@
name: Backfill Duplicate Comments
# description: Triggers duplicate detection for old issues that don't have duplicate comments
on:
workflow_dispatch:
inputs:
days_back:
description: "How many days back to look for old issues"
required: false
default: "90"
type: string
dry_run:
description: "Dry run mode (true to only log what would be done)"
required: false
default: "true"
type: choice
options:
- "true"
- "false"
jobs:
backfill-duplicate-comments:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
issues: read
actions: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Backfill duplicate comments
run: node .github/scripts/backfill-duplicate-comments.mjs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
GITHUB_REPOSITORY_NAME: ${{ github.event.repository.name }}
DAYS_BACK: ${{ inputs.days_back }}
DRY_RUN: ${{ inputs.dry_run }}

View File

@@ -9,70 +9,121 @@ on:
branches:
- main
- next
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
env:
DO_NOT_TRACK: 1
NODE_ENV: development
jobs:
setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install Dependencies
id: install
run: npm ci
timeout-minutes: 2
- name: Cache node_modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
# Fast checks that can run in parallel
format-check:
needs: setup
name: Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Restore node_modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
run: npm install --frozen-lockfile --prefer-offline
timeout-minutes: 5
- name: Format Check
run: npm run format-check
env:
FORCE_COLOR: 1
test:
needs: setup
typecheck:
name: Typecheck
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Restore node_modules
uses: actions/cache@v4
- name: Install dependencies
run: npm install --frozen-lockfile --prefer-offline
timeout-minutes: 5
- name: Typecheck
run: npm run turbo:typecheck
env:
FORCE_COLOR: 1
# Build job to ensure everything compiles
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
path: node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }}
fetch-depth: 2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
run: npm install --frozen-lockfile --prefer-offline
timeout-minutes: 5
- name: Build
run: npm run turbo:build
env:
NODE_ENV: production
FORCE_COLOR: 1
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: dist/
retention-days: 1
test:
name: Test
timeout-minutes: 15
runs-on: ubuntu-latest
needs: [format-check, typecheck, build]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
run: npm install --frozen-lockfile --prefer-offline
timeout-minutes: 5
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build-artifacts
path: dist/
- name: Run Tests
run: |
@@ -81,7 +132,6 @@ jobs:
NODE_ENV: test
CI: true
FORCE_COLOR: 1
timeout-minutes: 10
- name: Upload Test Results
if: always()

View File

@@ -0,0 +1,81 @@
name: Claude Issue Dedupe
# description: Automatically dedupe GitHub issues using Claude Code
on:
issues:
types: [opened]
workflow_dispatch:
inputs:
issue_number:
description: "Issue number to process for duplicate detection"
required: true
type: string
jobs:
claude-dedupe-issues:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run Claude Code slash command
uses: anthropics/claude-code-base-action@beta
with:
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Log duplicate comment event to Statsig
if: always()
env:
STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
run: |
ISSUE_NUMBER=${{ github.event.issue.number || inputs.issue_number }}
REPO=${{ github.repository }}
if [ -z "$STATSIG_API_KEY" ]; then
echo "STATSIG_API_KEY not found, skipping Statsig logging"
exit 0
fi
# Prepare the event payload
EVENT_PAYLOAD=$(jq -n \
--arg issue_number "$ISSUE_NUMBER" \
--arg repo "$REPO" \
--arg triggered_by "${{ github.event_name }}" \
'{
events: [{
eventName: "github_duplicate_comment_added",
value: 1,
metadata: {
repository: $repo,
issue_number: ($issue_number | tonumber),
triggered_by: $triggered_by,
workflow_run_id: "${{ github.run_id }}"
},
time: (now | floor | tostring)
}]
}')
# Send to Statsig API
echo "Logging duplicate comment event to Statsig for issue #${ISSUE_NUMBER}"
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
-H "Content-Type: application/json" \
-H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
-d "$EVENT_PAYLOAD")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | head -n-1)
if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
echo "Successfully logged duplicate comment event for issue #${ISSUE_NUMBER}"
else
echo "Failed to log duplicate comment event for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
fi

View File

@@ -0,0 +1,57 @@
name: Trigger Claude Documentation Update
on:
push:
branches:
- next
paths-ignore:
- "apps/docs/**"
- "*.md"
- ".github/workflows/**"
jobs:
trigger-docs-update:
# Only run if changes were merged (not direct pushes from bots)
if: github.actor != 'github-actions[bot]' && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 2 # Need previous commit for comparison
- name: Get changed files
id: changed-files
run: |
echo "Changed files in this push:"
git diff --name-only HEAD^ HEAD | tee changed_files.txt
# Store changed files for Claude to analyze (escaped for JSON)
CHANGED_FILES=$(git diff --name-only HEAD^ HEAD | jq -Rs .)
echo "changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT
# Get the commit message (escaped for JSON)
COMMIT_MSG=$(git log -1 --pretty=%B | jq -Rs .)
echo "commit_message=$COMMIT_MSG" >> $GITHUB_OUTPUT
# Get diff for documentation context (escaped for JSON)
COMMIT_DIFF=$(git diff HEAD^ HEAD --stat | jq -Rs .)
echo "commit_diff=$COMMIT_DIFF" >> $GITHUB_OUTPUT
# Get commit SHA
echo "commit_sha=${{ github.sha }}" >> $GITHUB_OUTPUT
- name: Trigger Claude workflow
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Trigger the Claude docs updater workflow with the change information
gh workflow run claude-docs-updater.yml \
--ref next \
-f commit_sha="${{ steps.changed-files.outputs.commit_sha }}" \
-f commit_message=${{ steps.changed-files.outputs.commit_message }} \
-f changed_files=${{ steps.changed-files.outputs.changed_files }} \
-f commit_diff=${{ steps.changed-files.outputs.commit_diff }}

View File

@@ -0,0 +1,145 @@
name: Claude Documentation Updater
on:
workflow_dispatch:
inputs:
commit_sha:
description: 'The commit SHA that triggered this update'
required: true
type: string
commit_message:
description: 'The commit message'
required: true
type: string
changed_files:
description: 'List of changed files'
required: true
type: string
commit_diff:
description: 'Diff summary of changes'
required: true
type: string
jobs:
update-docs:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: next
fetch-depth: 0 # Need full history to checkout specific commit
- name: Create docs update branch
id: create-branch
run: |
BRANCH_NAME="docs/auto-update-$(date +%Y%m%d-%H%M%S)"
git checkout -b $BRANCH_NAME
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
- name: Run Claude Code to Update Documentation
uses: anthropics/claude-code-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
timeout_minutes: "30"
mode: "agent"
github_token: ${{ secrets.GITHUB_TOKEN }}
experimental_allowed_domains: |
.anthropic.com
.github.com
api.github.com
.githubusercontent.com
registry.npmjs.org
.task-master.dev
base_branch: "next"
direct_prompt: |
You are a documentation specialist. Analyze the recent changes pushed to the 'next' branch and update the documentation accordingly.
Recent changes:
- Commit: ${{ inputs.commit_message }}
- Changed files:
${{ inputs.changed_files }}
- Changes summary:
${{ inputs.commit_diff }}
Your task:
1. Analyze the changes to understand what functionality was added, modified, or removed
2. Check if these changes require documentation updates in apps/docs/
3. If documentation updates are needed:
- Update relevant documentation files in apps/docs/
- Ensure examples are updated if APIs changed
- Update any configuration documentation if config options changed
- Add new documentation pages if new features were added
- Update the changelog or release notes if applicable
4. If no documentation updates are needed, skip creating changes
Guidelines:
- Focus only on user-facing changes that need documentation
- Keep documentation clear, concise, and helpful
- Include code examples where appropriate
- Maintain consistent documentation style with existing docs
- Don't document internal implementation details unless they affect users
- Update navigation/menu files if new pages are added
Only make changes if the documentation truly needs updating based on the code changes.
- name: Check if changes were made
id: check-changes
run: |
if git diff --quiet; then
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "has_changes=true" >> $GITHUB_OUTPUT
git add -A
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git commit -m "docs: auto-update documentation based on changes in next branch
This PR was automatically generated to update documentation based on recent changes.
Original commit: ${{ inputs.commit_message }}
Co-authored-by: Claude <claude-assistant@anthropic.com>"
fi
- name: Push changes and create PR
if: steps.check-changes.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git push origin ${{ steps.create-branch.outputs.branch_name }}
# Create PR using GitHub CLI
gh pr create \
--title "docs: update documentation for recent changes" \
--body "## 📚 Documentation Update
This PR automatically updates documentation based on recent changes merged to the \`next\` branch.
### Original Changes
**Commit:** ${{ inputs.commit_sha }}
**Message:** ${{ inputs.commit_message }}
### Changed Files in Original Commit
\`\`\`
${{ inputs.changed_files }}
\`\`\`
### Documentation Updates
This PR includes documentation updates to reflect the changes above. Please review to ensure:
- [ ] Documentation accurately reflects the changes
- [ ] Examples are correct and working
- [ ] No important details are missing
- [ ] Style is consistent with existing documentation
---
*This PR was automatically generated by Claude Code GitHub Action*" \
--base next \
--head ${{ steps.create-branch.outputs.branch_name }} \
--label "documentation" \
--label "automated"

View File

@@ -0,0 +1,107 @@
name: Claude Issue Triage
# description: Automatically triage GitHub issues using Claude Code
on:
issues:
types: [opened]
jobs:
triage-issue:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Create triage prompt
run: |
mkdir -p /tmp/claude-prompts
cat > /tmp/claude-prompts/triage-prompt.txt << 'EOF'
You're an issue triage assistant for GitHub issues. Your task is to analyze the issue and select appropriate labels from the provided list.
IMPORTANT: Don't post any comments or messages to the issue. Your only action should be to apply labels.
Issue Information:
- REPO: ${{ github.repository }}
- ISSUE_NUMBER: ${{ github.event.issue.number }}
TASK OVERVIEW:
1. First, fetch the list of labels available in this repository by running: `gh label list`. Run exactly this command with nothing else.
2. Next, use the GitHub tools to get context about the issue:
- You have access to these tools:
- mcp__github__get_issue: Use this to retrieve the current issue's details including title, description, and existing labels
- mcp__github__get_issue_comments: Use this to read any discussion or additional context provided in the comments
- mcp__github__update_issue: Use this to apply labels to the issue (do not use this for commenting)
- mcp__github__search_issues: Use this to find similar issues that might provide context for proper categorization and to identify potential duplicate issues
- mcp__github__list_issues: Use this to understand patterns in how other issues are labeled
- Start by using mcp__github__get_issue to get the issue details
3. Analyze the issue content, considering:
- The issue title and description
- The type of issue (bug report, feature request, question, etc.)
- Technical areas mentioned
- Severity or priority indicators
- User impact
- Components affected
4. Select appropriate labels from the available labels list provided above:
- Choose labels that accurately reflect the issue's nature
- Be specific but comprehensive
- Select priority labels if you can determine urgency (high-priority, med-priority, or low-priority)
- Consider platform labels (android, ios) if applicable
- If you find similar issues using mcp__github__search_issues, consider using a "duplicate" label if appropriate. Only do so if the issue is a duplicate of another OPEN issue.
5. Apply the selected labels:
- Use mcp__github__update_issue to apply your selected labels
- DO NOT post any comments explaining your decision
- DO NOT communicate directly with users
- If no labels are clearly applicable, do not apply any labels
IMPORTANT GUIDELINES:
- Be thorough in your analysis
- Only select labels from the provided list above
- DO NOT post any comments to the issue
- Your ONLY action should be to apply labels using mcp__github__update_issue
- It's okay to not add any labels if none are clearly applicable
EOF
- name: Setup GitHub MCP Server
run: |
mkdir -p /tmp/mcp-config
cat > /tmp/mcp-config/mcp-servers.json << 'EOF'
{
"mcpServers": {
"github": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"ghcr.io/github/github-mcp-server:sha-7aced2b"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${{ secrets.GITHUB_TOKEN }}"
}
}
}
}
EOF
- name: Run Claude Code for Issue Triage
uses: anthropics/claude-code-base-action@beta
with:
prompt_file: /tmp/claude-prompts/triage-prompt.txt
allowed_tools: "Bash(gh label list),mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues"
timeout_minutes: "5"
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
mcp_config: /tmp/mcp-config/mcp-servers.json
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

36
.github/workflows/claude.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

143
.github/workflows/extension-ci.yml vendored Normal file
View File

@@ -0,0 +1,143 @@
name: Extension CI
on:
push:
branches:
- main
- next
paths:
- 'apps/extension/**'
- '.github/workflows/extension-ci.yml'
pull_request:
branches:
- main
- next
paths:
- 'apps/extension/**'
- '.github/workflows/extension-ci.yml'
permissions:
contents: read
jobs:
setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Cache node_modules
uses: actions/cache@v4
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Extension Dependencies
working-directory: apps/extension
run: npm ci
timeout-minutes: 5
typecheck:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Restore node_modules
uses: actions/cache@v4
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install if cache miss
working-directory: apps/extension
run: npm ci
timeout-minutes: 3
- name: Type Check Extension
working-directory: apps/extension
run: npm run check-types
env:
FORCE_COLOR: 1
build:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Restore node_modules
uses: actions/cache@v4
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install if cache miss
working-directory: apps/extension
run: npm ci
timeout-minutes: 3
- name: Build Extension
working-directory: apps/extension
run: npm run build
env:
FORCE_COLOR: 1
- name: Package Extension
working-directory: apps/extension
run: npm run package
env:
FORCE_COLOR: 1
- name: Verify Package Contents
working-directory: apps/extension
run: |
echo "Checking vsix-build contents..."
ls -la vsix-build/
echo "Checking dist contents..."
ls -la vsix-build/dist/
echo "Checking package.json exists..."
test -f vsix-build/package.json
- name: Create VSIX Package (Test)
working-directory: apps/extension/vsix-build
run: npx vsce package --no-dependencies
env:
FORCE_COLOR: 1
- name: Upload Extension Artifact
uses: actions/upload-artifact@v4
with:
name: extension-package
path: |
apps/extension/vsix-build/*.vsix
apps/extension/dist/
retention-days: 30

111
.github/workflows/extension-release.yml vendored Normal file
View File

@@ -0,0 +1,111 @@
name: Extension Release
on:
push:
tags:
- "extension@*"
permissions:
contents: write
concurrency: extension-release-${{ github.ref }}
jobs:
publish-extension:
runs-on: ubuntu-latest
environment: extension-release
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Cache node_modules
uses: actions/cache@v4
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Extension Dependencies
working-directory: apps/extension
run: npm ci
timeout-minutes: 5
- name: Type Check Extension
working-directory: apps/extension
run: npm run check-types
env:
FORCE_COLOR: 1
- name: Build Extension
working-directory: apps/extension
run: npm run build
env:
FORCE_COLOR: 1
- name: Package Extension
working-directory: apps/extension
run: npm run package
env:
FORCE_COLOR: 1
- name: Create VSIX Package
working-directory: apps/extension/vsix-build
run: npx vsce package --no-dependencies
env:
FORCE_COLOR: 1
- name: Get VSIX filename
id: vsix-info
working-directory: apps/extension/vsix-build
run: |
VSIX_FILE=$(find . -maxdepth 1 -name "*.vsix" -type f | head -n1 | xargs basename)
if [ -z "$VSIX_FILE" ]; then
echo "Error: No VSIX file found"
exit 1
fi
echo "vsix-filename=$VSIX_FILE" >> "$GITHUB_OUTPUT"
echo "Found VSIX: $VSIX_FILE"
- name: Publish to VS Code Marketplace
working-directory: apps/extension/vsix-build
run: npx vsce publish --packagePath "${{ steps.vsix-info.outputs.vsix-filename }}"
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
FORCE_COLOR: 1
- name: Install Open VSX CLI
run: npm install -g ovsx
- name: Publish to Open VSX Registry
working-directory: apps/extension/vsix-build
run: ovsx publish "${{ steps.vsix-info.outputs.vsix-filename }}"
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}
FORCE_COLOR: 1
- name: Upload Build Artifacts
uses: actions/upload-artifact@v4
with:
name: extension-release-${{ github.ref_name }}
path: |
apps/extension/vsix-build/*.vsix
apps/extension/dist/
retention-days: 90
notify-success:
needs: publish-extension
if: success()
runs-on: ubuntu-latest
steps:
- name: Success Notification
run: |
echo "🎉 Extension ${{ github.ref_name }} successfully published!"
echo "📦 Available on VS Code Marketplace"
echo "🌍 Available on Open VSX Registry"
echo "🏷️ GitHub release created: ${{ github.ref_name }}"

176
.github/workflows/log-issue-events.yml vendored Normal file
View File

@@ -0,0 +1,176 @@
name: Log GitHub Issue Events
on:
issues:
types: [opened, closed]
jobs:
log-issue-created:
if: github.event.action == 'opened'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
issues: read
steps:
- name: Log issue creation to Statsig
env:
STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
run: |
ISSUE_NUMBER=${{ github.event.issue.number }}
REPO=${{ github.repository }}
ISSUE_TITLE=$(echo '${{ github.event.issue.title }}' | sed "s/'/'\\\\''/g")
AUTHOR="${{ github.event.issue.user.login }}"
CREATED_AT="${{ github.event.issue.created_at }}"
if [ -z "$STATSIG_API_KEY" ]; then
echo "STATSIG_API_KEY not found, skipping Statsig logging"
exit 0
fi
# Prepare the event payload
EVENT_PAYLOAD=$(jq -n \
--arg issue_number "$ISSUE_NUMBER" \
--arg repo "$REPO" \
--arg title "$ISSUE_TITLE" \
--arg author "$AUTHOR" \
--arg created_at "$CREATED_AT" \
'{
events: [{
eventName: "github_issue_created",
value: 1,
metadata: {
repository: $repo,
issue_number: ($issue_number | tonumber),
issue_title: $title,
issue_author: $author,
created_at: $created_at
},
time: (now | floor | tostring)
}]
}')
# Send to Statsig API
echo "Logging issue creation to Statsig for issue #${ISSUE_NUMBER}"
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
-H "Content-Type: application/json" \
-H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
-d "$EVENT_PAYLOAD")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | head -n-1)
if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
echo "Successfully logged issue creation for issue #${ISSUE_NUMBER}"
else
echo "Failed to log issue creation for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
fi
log-issue-closed:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
issues: read
steps:
- name: Log issue closure to Statsig
env:
STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
ISSUE_NUMBER=${{ github.event.issue.number }}
REPO=${{ github.repository }}
ISSUE_TITLE=$(echo '${{ github.event.issue.title }}' | sed "s/'/'\\\\''/g")
CLOSED_BY="${{ github.event.issue.closed_by.login }}"
CLOSED_AT="${{ github.event.issue.closed_at }}"
STATE_REASON="${{ github.event.issue.state_reason }}"
if [ -z "$STATSIG_API_KEY" ]; then
echo "STATSIG_API_KEY not found, skipping Statsig logging"
exit 0
fi
# Get additional issue data via GitHub API
echo "Fetching additional issue data for #${ISSUE_NUMBER}"
ISSUE_DATA=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO}/issues/${ISSUE_NUMBER}")
COMMENTS_COUNT=$(echo "$ISSUE_DATA" | jq -r '.comments')
# Get reactions data
REACTIONS_DATA=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/${REPO}/issues/${ISSUE_NUMBER}/reactions")
REACTIONS_COUNT=$(echo "$REACTIONS_DATA" | jq '. | length')
# Check if issue was closed automatically (by checking if closed_by is a bot)
CLOSED_AUTOMATICALLY="false"
if [[ "$CLOSED_BY" == *"[bot]"* ]]; then
CLOSED_AUTOMATICALLY="true"
fi
# Check if closed as duplicate by state_reason
CLOSED_AS_DUPLICATE="false"
if [ "$STATE_REASON" = "duplicate" ]; then
CLOSED_AS_DUPLICATE="true"
fi
# Prepare the event payload
EVENT_PAYLOAD=$(jq -n \
--arg issue_number "$ISSUE_NUMBER" \
--arg repo "$REPO" \
--arg title "$ISSUE_TITLE" \
--arg closed_by "$CLOSED_BY" \
--arg closed_at "$CLOSED_AT" \
--arg state_reason "$STATE_REASON" \
--arg comments_count "$COMMENTS_COUNT" \
--arg reactions_count "$REACTIONS_COUNT" \
--arg closed_automatically "$CLOSED_AUTOMATICALLY" \
--arg closed_as_duplicate "$CLOSED_AS_DUPLICATE" \
'{
events: [{
eventName: "github_issue_closed",
value: 1,
metadata: {
repository: $repo,
issue_number: ($issue_number | tonumber),
issue_title: $title,
closed_by: $closed_by,
closed_at: $closed_at,
state_reason: $state_reason,
comments_count: ($comments_count | tonumber),
reactions_count: ($reactions_count | tonumber),
closed_automatically: ($closed_automatically | test("true")),
closed_as_duplicate: ($closed_as_duplicate | test("true"))
},
time: (now | floor | tostring)
}]
}')
# Send to Statsig API
echo "Logging issue closure to Statsig for issue #${ISSUE_NUMBER}"
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
-H "Content-Type: application/json" \
-H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
-d "$EVENT_PAYLOAD")
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
BODY=$(echo "$RESPONSE" | head -n-1)
if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
echo "Successfully logged issue closure for issue #${ISSUE_NUMBER}"
echo "Closed by: $CLOSED_BY"
echo "Comments: $COMMENTS_COUNT"
echo "Reactions: $REACTIONS_COUNT"
echo "Closed automatically: $CLOSED_AUTOMATICALLY"
echo "Closed as duplicate: $CLOSED_AS_DUPLICATE"
else
echo "Failed to log issue closure for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
fi

View File

@@ -3,11 +3,13 @@ name: Pre-Release (RC)
on:
workflow_dispatch: # Allows manual triggering from GitHub UI/API
concurrency: pre-release-${{ github.ref }}
concurrency: pre-release-${{ github.ref_name }}
jobs:
rc:
runs-on: ubuntu-latest
# Only allow pre-releases on non-main branches
if: github.ref != 'refs/heads/main'
environment: extension-release
steps:
- uses: actions/checkout@v4
with:
@@ -16,7 +18,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache: "npm"
- name: Cache node_modules
uses: actions/cache@v4
@@ -32,10 +34,30 @@ jobs:
run: npm ci
timeout-minutes: 2
- name: Enter RC mode
- name: Enter RC mode (if not already in RC mode)
run: |
npx changeset pre exit || true
npx changeset pre enter rc
# Check if we're in pre-release mode with the "rc" tag
if [ -f .changeset/pre.json ]; then
MODE=$(jq -r '.mode' .changeset/pre.json 2>/dev/null || echo '')
TAG=$(jq -r '.tag' .changeset/pre.json 2>/dev/null || echo '')
if [ "$MODE" = "exit" ]; then
echo "Pre-release mode is in 'exit' state, re-entering RC mode..."
npx changeset pre enter rc
elif [ "$MODE" = "pre" ] && [ "$TAG" != "rc" ]; then
echo "In pre-release mode but with wrong tag ($TAG), switching to RC..."
npx changeset pre exit
npx changeset pre enter rc
elif [ "$MODE" = "pre" ] && [ "$TAG" = "rc" ]; then
echo "Already in RC pre-release mode"
else
echo "Unknown mode state: $MODE, entering RC mode..."
npx changeset pre enter rc
fi
else
echo "No pre.json found, entering RC mode..."
npx changeset pre enter rc
fi
- name: Version RC packages
run: npx changeset version
@@ -46,17 +68,14 @@ jobs:
- name: Create Release Candidate Pull Request or Publish Release Candidate to npm
uses: changesets/action@v1
with:
publish: npm run release
publish: npx changeset publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Exit RC mode
run: npx changeset pre exit
- name: Commit & Push changes
uses: actions-js/push@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
message: 'chore: rc version bump'
message: "chore: rc version bump"

21
.github/workflows/release-check.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Release Check
on:
pull_request:
branches:
- main
concurrency:
group: release-check-${{ github.head_ref }}
cancel-in-progress: true
jobs:
check-release-mode:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check release mode
run: node ./.github/scripts/check-pre-release-mode.mjs "pull_request"

View File

@@ -6,6 +6,11 @@ on:
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: write
pull-requests: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
@@ -33,13 +38,13 @@ jobs:
run: npm ci
timeout-minutes: 2
- name: Exit pre-release mode (safety check)
run: npx changeset pre exit || true
- name: Check pre-release mode
run: node ./.github/scripts/check-pre-release-mode.mjs "main"
- name: Create Release Pull Request or Publish to npm
uses: changesets/action@v1
with:
publish: npm run release
publish: node ./.github/scripts/release.mjs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -0,0 +1,96 @@
name: Weekly Metrics to Discord
# description: Sends weekly metrics summary to Discord channel
on:
schedule:
- cron: "0 9 * * 1" # Every Monday at 9 AM
workflow_dispatch:
permissions:
contents: read
issues: write
pull-requests: read
jobs:
weekly-metrics:
runs-on: ubuntu-latest
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_METRICS_WEBHOOK }}
steps:
- name: Get dates for last week
run: |
# Last 7 days
first_day=$(date -d "7 days ago" +%Y-%m-%d)
last_day=$(date +%Y-%m-%d)
echo "first_day=$first_day" >> $GITHUB_ENV
echo "last_day=$last_day" >> $GITHUB_ENV
echo "week_of=$(date -d '7 days ago' +'Week of %B %d, %Y')" >> $GITHUB_ENV
- name: Generate issue metrics
uses: github/issue-metrics@v3
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SEARCH_QUERY: "repo:${{ github.repository }} is:issue created:${{ env.first_day }}..${{ env.last_day }}"
HIDE_TIME_TO_ANSWER: true
HIDE_LABEL_METRICS: false
- name: Generate PR metrics
uses: github/issue-metrics@v3
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SEARCH_QUERY: "repo:${{ github.repository }} is:pr created:${{ env.first_day }}..${{ env.last_day }}"
OUTPUT_FILE: pr_metrics.md
- name: Parse metrics
id: metrics
run: |
# Parse the metrics from the generated markdown files
if [ -f "issue_metrics.md" ]; then
# Extract key metrics using grep/awk
AVG_TIME_TO_FIRST_RESPONSE=$(grep -A 1 "Average time to first response" issue_metrics.md | tail -1 | xargs || echo "N/A")
AVG_TIME_TO_CLOSE=$(grep -A 1 "Average time to close" issue_metrics.md | tail -1 | xargs || echo "N/A")
NUM_ISSUES_CREATED=$(grep -oP '\d+(?= issues created)' issue_metrics.md || echo "0")
NUM_ISSUES_CLOSED=$(grep -oP '\d+(?= issues closed)' issue_metrics.md || echo "0")
fi
if [ -f "pr_metrics.md" ]; then
PR_AVG_TIME_TO_MERGE=$(grep -A 1 "Average time to close" pr_metrics.md | tail -1 | xargs || echo "N/A")
NUM_PRS_CREATED=$(grep -oP '\d+(?= pull requests created)' pr_metrics.md || echo "0")
NUM_PRS_MERGED=$(grep -oP '\d+(?= pull requests closed)' pr_metrics.md || echo "0")
fi
# Set outputs for Discord action
echo "issues_created=${NUM_ISSUES_CREATED:-0}" >> $GITHUB_OUTPUT
echo "issues_closed=${NUM_ISSUES_CLOSED:-0}" >> $GITHUB_OUTPUT
echo "prs_created=${NUM_PRS_CREATED:-0}" >> $GITHUB_OUTPUT
echo "prs_merged=${NUM_PRS_MERGED:-0}" >> $GITHUB_OUTPUT
echo "avg_first_response=${AVG_TIME_TO_FIRST_RESPONSE:-N/A}" >> $GITHUB_OUTPUT
echo "avg_time_to_close=${AVG_TIME_TO_CLOSE:-N/A}" >> $GITHUB_OUTPUT
echo "pr_avg_merge_time=${PR_AVG_TIME_TO_MERGE:-N/A}" >> $GITHUB_OUTPUT
- name: Send to Discord
uses: sarisia/actions-status-discord@v1
if: env.DISCORD_WEBHOOK != ''
with:
webhook: ${{ env.DISCORD_WEBHOOK }}
status: Success
title: "📊 Weekly Metrics Report"
description: |
**${{ env.week_of }}**
**🎯 Issues**
• Created: ${{ steps.metrics.outputs.issues_created }}
• Closed: ${{ steps.metrics.outputs.issues_closed }}
**🔀 Pull Requests**
• Created: ${{ steps.metrics.outputs.prs_created }}
• Merged: ${{ steps.metrics.outputs.prs_merged }}
**⏱️ Response Times**
• First Response: ${{ steps.metrics.outputs.avg_first_response }}
• Time to Close: ${{ steps.metrics.outputs.avg_time_to_close }}
• PR Merge Time: ${{ steps.metrics.outputs.pr_avg_merge_time }}
color: 0x58AFFF
username: Task Master Metrics Bot
avatar_url: https://raw.githubusercontent.com/eyaltoledano/claude-task-master/main/images/logo.png

10
.gitignore vendored
View File

@@ -87,3 +87,13 @@ dev-debug.log
*.njsproj
*.sln
*.sw?
# VS Code extension test files
.vscode-test/
apps/extension/.vscode-test/
# apps/extension
apps/extension/vsix-build/
# turbo
.turbo

View File

@@ -1,3 +0,0 @@
Testing rules that you can help me improve to see how it works<!------------------------------------------------------------------------------------
Add Rules to this file or a short description and have Kiro refine them for you:
------------------------------------------------------------------------------------->

2
.nvmrc
View File

@@ -1 +1 @@
22
22

View File

@@ -0,0 +1,188 @@
# Task Master Migration Roadmap
## Overview
Gradual migration from scripts-based architecture to a clean monorepo with separated concerns.
## Architecture Vision
```
┌─────────────────────────────────────────────────┐
│ User Interfaces │
├──────────┬──────────┬──────────┬────────────────┤
│ @tm/cli │ @tm/mcp │ @tm/ext │ @tm/web │
│ (CLI) │ (MCP) │ (VSCode)│ (Future) │
└──────────┴──────────┴──────────┴────────────────┘
┌──────────────────────┐
│ @tm/core │
│ (Business Logic) │
└──────────────────────┘
```
## Migration Phases
### Phase 1: Core Extraction ✅ (In Progress)
**Goal**: Move all business logic to @tm/core
- [x] Create @tm/core package structure
- [x] Move types and interfaces
- [x] Implement TaskMasterCore facade
- [x] Move storage adapters
- [x] Move task services
- [ ] Move AI providers
- [ ] Move parser logic
- [ ] Complete test coverage
### Phase 2: CLI Package Creation 🚧 (Started)
**Goal**: Create @tm/cli as a thin presentation layer
- [x] Create @tm/cli package structure
- [x] Implement Command interface pattern
- [x] Create CommandRegistry
- [x] Build legacy bridge/adapter
- [x] Migrate list-tasks command
- [ ] Migrate remaining commands one by one
- [ ] Remove UI logic from core
### Phase 3: Transitional Integration
**Goal**: Use new packages in existing scripts without breaking changes
```javascript
// scripts/modules/commands.js gradually adopts new commands
import { ListTasksCommand } from '@tm/cli';
const listCommand = new ListTasksCommand();
// Old interface remains the same
programInstance
.command('list')
.action(async (options) => {
// Use new command internally
const result = await listCommand.execute(convertOptions(options));
});
```
### Phase 4: MCP Package
**Goal**: Separate MCP server as its own package
- [ ] Create @tm/mcp package
- [ ] Move MCP server code
- [ ] Use @tm/core for all logic
- [ ] MCP becomes a thin RPC layer
### Phase 5: Complete Migration
**Goal**: Remove old scripts, pure monorepo
- [ ] All commands migrated to @tm/cli
- [ ] Remove scripts/modules/task-manager/*
- [ ] Remove scripts/modules/commands.js
- [ ] Update bin/task-master.js to use @tm/cli
- [ ] Clean up dependencies
## Current Transitional Strategy
### 1. Adapter Pattern (commands-adapter.js)
```javascript
// Checks if new CLI is available and uses it
// Falls back to legacy implementation if not
export async function listTasksAdapter(...args) {
if (cliAvailable) {
return useNewImplementation(...args);
}
return useLegacyImplementation(...args);
}
```
### 2. Command Bridge Pattern
```javascript
// Allows new commands to work in old code
const bridge = new CommandBridge(new ListTasksCommand());
const data = await bridge.run(legacyOptions); // Legacy style
const result = await bridge.execute(newOptions); // New style
```
### 3. Gradual File Migration
Instead of big-bang refactoring:
1. Create new implementation in @tm/cli
2. Add adapter in commands-adapter.js
3. Update commands.js to use adapter
4. Test both paths work
5. Eventually remove adapter when all migrated
## Benefits of This Approach
1. **No Breaking Changes**: Existing CLI continues to work
2. **Incremental PRs**: Each command can be migrated separately
3. **Parallel Development**: New features can use new architecture
4. **Easy Rollback**: Can disable new implementation if issues
5. **Clear Separation**: Business logic (core) vs presentation (cli/mcp/etc)
## Example PR Sequence
### PR 1: Core Package Setup ✅
- Create @tm/core
- Move types and interfaces
- Basic TaskMasterCore implementation
### PR 2: CLI Package Foundation ✅
- Create @tm/cli
- Command interface and registry
- Legacy bridge utilities
### PR 3: First Command Migration
- Migrate list-tasks to new system
- Add adapter in scripts
- Test both implementations
### PR 4-N: Migrate Commands One by One
- Each PR migrates 1-2 related commands
- Small, reviewable changes
- Continuous delivery
### Final PR: Cleanup
- Remove legacy implementations
- Remove adapters
- Update documentation
## Testing Strategy
### Dual Testing During Migration
```javascript
describe('List Tasks', () => {
it('works with legacy implementation', async () => {
// Force legacy
const result = await legacyListTasks(...);
expect(result).toBeDefined();
});
it('works with new implementation', async () => {
// Force new
const command = new ListTasksCommand();
const result = await command.execute(...);
expect(result.success).toBe(true);
});
it('adapter chooses correctly', async () => {
// Let adapter decide
const result = await listTasksAdapter(...);
expect(result).toBeDefined();
});
});
```
## Success Metrics
- [ ] All commands migrated without breaking changes
- [ ] Test coverage maintained or improved
- [ ] Performance maintained or improved
- [ ] Cleaner, more maintainable codebase
- [ ] Easy to add new interfaces (web, desktop, etc.)
## Notes for Contributors
1. **Keep PRs Small**: Migrate one command at a time
2. **Test Both Paths**: Ensure legacy and new both work
3. **Document Changes**: Update this roadmap as you go
4. **Communicate**: Discuss in PRs if architecture needs adjustment
This is a living document - update as the migration progresses!

View File

@@ -0,0 +1,153 @@
---
title: Research Session
query: "do we need to add new commands or can we just weaponize the gh cli tool"
date: 2025-08-01
time: 2:27:52 p.m.
timestamp: 2025-08-01T11:27:52.249Z
exchanges: 3
---
# Research Session
## Initial Query
**Question:** do we need to add new commands or can we just weaponize the gh cli tool
**Response:**
For the implementation of the `task-master git` command suite to automate git workflows (Task 97), it is possible to leverage the existing **GitHub CLI (`gh`) tool** rather than creating entirely new git commands from scratch. The GitHub CLI provides a rich set of commands that cover many GitHub-related operations such as branch management, pull request handling, workflow triggering, and release management, which can be scripted and integrated into your CLI tool[1][2][3][4].
### Key Points Supporting Weaponizing GitHub CLI:
- **Comprehensive GitHub Operations**: The `gh` CLI supports creating branches, managing pull requests, releases, tags, and even triggering and monitoring GitHub Actions workflows. This aligns well with the requirements of automated branch management, commit generation, and PR description generation in Task 97[1][3].
- **Scripting and Automation Friendly**: GitHub CLI commands can be scripted and integrated into custom workflows or CLI tools. You can create aliases or wrap `gh` commands inside your own CLI commands to provide a seamless user experience while relying on the battle-tested GitHub CLI for underlying operations[1][3].
- **Authentication and Permissions**: `gh` uses environment variables like `GH_TOKEN` or `GITHUB_TOKEN` for authentication, which can be securely managed in CI/CD pipelines or local environments. This simplifies integration without needing to implement custom authentication logic[3][4].
- **Extensibility**: If some specific git workflow features are not directly supported by `gh`, you can extend it with custom scripts or combine it with native git commands. This hybrid approach reduces the need to reinvent core git operations while allowing customization[1].
### Considerations for Your Project:
- Since Task 97 requires **automated branch management** (branch creation, validation, switching, cleanup), **intelligent commit generation**, and **PR description generation**, you can implement these by invoking `gh` commands programmatically within your `task-master git` commands.
- For example, branch creation and switching can be done with native git commands wrapped in your CLI, while PR creation and management can be handled via `gh pr create`, `gh pr merge`, etc.
- You may still need to implement some **custom logic** for commit type detection, branch name validation, and PR description generation based on your task metadata, but the underlying git and GitHub operations can be delegated to `gh`.
- This approach aligns with your existing CLI foundation (Task 2) and leverages a well-supported tool, reducing development effort and increasing reliability.
### Summary
You **do not necessarily need to add entirely new git commands** for Task 97. Instead, you can **weaponize the GitHub CLI (`gh`) tool** by wrapping and scripting its commands within your `task-master git` command suite. This will allow you to automate git workflows efficiently, maintain consistency, and leverage GitHubs API capabilities without reinventing the wheel[1][2][3][4].
If there are gaps in `gh` functionality for your specific workflow needs, you can supplement with native git commands or custom scripts, but the core git and GitHub operations should be handled by `gh` for best results.
---
## Follow-up 1
**Question:** how does this relate to git worktrees? i hear that they get super complicated when trying to implement them.
**Response:**
Git worktrees allow you to have multiple working directories attached to the same Git repository, each checked out to different branches simultaneously. This enables parallel development workflows without the overhead of cloning the repository multiple times or constantly switching branches in a single working directory[2][3].
However, **implementing or managing git worktrees can get complicated** for several reasons:
- **Complexity for users and tooling:** Managing multiple active worktrees requires careful tracking of which directory corresponds to which branch. This can be confusing and error-prone, especially for novices or when many worktrees are in use simultaneously. Mistakes like committing to the wrong branch or working in the wrong directory are common risks[1].
- **Maintenance overhead:** Worktrees accumulate over time and need to be pruned or cleaned up regularly (`git worktree prune`) to avoid clutter and potential confusion. This adds an extra maintenance step to the workflow[1].
- **Syncing and update challenges:** Each worktree is a separate checkout and can become outdated if not regularly updated from the main repository. This can lead to merge conflicts or redundant work if branches diverge significantly[1].
- **Tooling and integration limitations:** Not all Git tools, scripts, or GUIs fully support worktrees or are optimized for them. This can cause inconsistencies or require additional custom tooling to manage worktrees effectively[1].
- **Performance considerations:** Managing multiple worktrees simultaneously can have performance implications, especially in very large repositories, due to the overhead of maintaining multiple checkouts and metadata[1].
In the context of your project, which involves automating git workflows and possibly wrapping or extending git/GitHub CLI commands, these complexities imply:
- If you consider supporting git worktrees in your `task-master git` command suite, you will need to handle the complexity of managing multiple directories and branches carefully.
- You might need to implement additional logic or tooling to track and manage worktrees, avoid user confusion, and ensure synchronization between them.
- Since your project already plans to leverage the GitHub CLI (`gh`) and native git commands, you could integrate worktree commands (`git worktree add`, `git worktree remove`, `git worktree list`) but should be prepared for the added complexity in workflow management and user documentation.
- Custom wrappers or managers (like the one described in [3]) can help reduce friction by automating worktree creation, switching, and cleanup, which might be a useful approach to consider.
Overall, **git worktrees provide powerful parallel branch management but introduce complexity in implementation and user experience** that must be carefully managed through tooling, automation, and clear documentation[1][3][4].
---
**Summary Table of Git Worktree Challenges and Considerations**
| Aspect | Description | Implication for Project |
|-------------------------|-----------------------------------------------------------------------------------------------|----------------------------------------------------------|
| User Complexity | Confusing multiple directories and branches | Need clear UI/UX and safeguards |
| Maintenance Overhead | Requires pruning and cleanup of stale worktrees | Automate cleanup or provide commands |
| Syncing Issues | Worktrees can become outdated or diverge | Implement update checks and sync workflows |
| Tooling Support | Limited support in some Git tools and GUIs | May require custom tooling or wrappers |
| Performance | Overhead in large repos with many worktrees | Monitor and optimize performance |
| Workflow Automation | Manual worktree management is tedious | Build custom managers or wrappers to simplify usage |
---
Given your projects focus on automating git workflows and leveraging existing CLI tools, **implementing git worktree support is feasible but will require careful design to handle these complexities effectively**. You may want to start with basic worktree commands and incrementally add automation and safeguards as needed.
---
## Follow-up 2
**Question:** since we already have a way to have separated task lists per branch, couldn't we do the same thing for worktrees? each taskmaster list (tag) would have its own worktree based on the name of the tag?
**Response:**
Yes, you can apply a similar approach used for separated task lists per branch to git worktrees by associating each taskmaster list (tag) with its own git worktree named after the tag. This means each tag would correspond to a dedicated worktree directory checked out to a branch or commit related to that tag, enabling isolated parallel work environments for each task list.
### How This Maps to Git Worktrees
- **Git worktrees** allow multiple working directories linked to the same repository, each checked out to a different branch or commit[1][2]. This lets you work on multiple branches simultaneously without switching contexts in a single directory.
- When you create a worktree with `git worktree add <path> [<branch>]`, Git creates a new linked working tree at `<path>`, optionally checking out a specified branch or creating a new one[1][2]. Naming the worktree directory after the tag (taskmaster list) is straightforward and semantically clear.
- This setup mirrors your existing branch-based task list separation but extends it to physical directories, which can improve workflow isolation and reduce context switching.
### Benefits for Your Project
- **Isolated environments per task list/tag:** Each tags worktree can have its own checked-out branch, allowing independent development, testing, or review without interference.
- **Parallel workflows:** Developers can switch between worktrees (directories) instead of switching branches in one directory, reducing errors and improving productivity.
- **Automation potential:** Your `task-master git` commands can automate creating, switching, and cleaning up these worktrees based on tags, similar to how you manage branches and task lists.
### Challenges and Considerations
- **Complexity in management:** Git worktrees add complexity in tracking multiple directories and ensuring users operate in the correct one[1]. Your CLI should provide clear commands and feedback to avoid confusion.
- **Maintenance overhead:** Worktrees need pruning and cleanup (`git worktree prune` or `git worktree remove`) to avoid clutter[1]. Automating cleanup in your tool would be beneficial.
- **Syncing and updates:** Each worktree is a separate checkout and can become outdated. Your automation should include commands to update or rebase worktrees as needed.
- **Tooling support:** Not all Git tools or scripts fully support worktrees, so your CLI wrappers should handle edge cases and provide a consistent experience[1][3].
### Practical Implementation Ideas
- When a new tag (taskmaster list) is created, run `git worktree add` to create a new worktree directory named after the tag.
- Store metadata linking tags to worktree paths in your taskmaster configuration to track and manage them.
- Provide commands like `task-master worktree list`, `task-master worktree add <tag>`, and `task-master worktree remove <tag>` to manage these worktrees.
- Integrate with GitHub CLI (`gh`) and native git commands to automate branch creation, PR handling, and syncing within each worktree.
- Consider inspiration from existing tools like [wt](https://github.com/taecontrol/wt) that automate worktree environment setup and teardown[3].
### Summary
Using git worktrees per taskmaster tag is a feasible and potentially powerful extension of your current branch-based task list separation. It offers isolated, parallel working directories aligned with your tags, improving workflow clarity and reducing branch-switching overhead. However, it requires careful tooling and automation to manage complexity, maintenance, and synchronization effectively. Given your projects focus on automating git workflows and leveraging CLI tools, implementing this feature incrementally with robust user feedback and cleanup commands would be a practical approach.
---
*Generated by Task Master Research Command*
*Timestamp: 2025-08-01T11:27:52.249Z*

View File

@@ -0,0 +1,8 @@
Simple Todo App PRD
Create a basic todo list application with the following features:
1. Add new todos
2. Mark todos as complete
3. Delete todos
That's it. Keep it simple.

View File

@@ -0,0 +1,343 @@
# Product Requirements Document: tm-core Package - Parse PRD Feature
## Project Overview
Create a TypeScript package named `tm-core` at `packages/tm-core` that implements parse-prd functionality using class-based architecture similar to the existing AI providers pattern.
## Design Patterns & Architecture
### Patterns to Apply
1. **Factory Pattern**: Use for `ProviderFactory` to create AI provider instances
2. **Strategy Pattern**: Use for `IAIProvider` implementations and `IStorage` implementations
3. **Facade Pattern**: Use for `TaskMasterCore` as the main API entry point
4. **Template Method Pattern**: Use for `BaseProvider` abstract class
5. **Dependency Injection**: Use throughout for testability (pass dependencies via constructor)
6. **Repository Pattern**: Use for `FileStorage` to abstract data persistence
### Naming Conventions
- **Files**: kebab-case (e.g., `task-parser.ts`, `file-storage.ts`)
- **Classes**: PascalCase (e.g., `TaskParser`, `FileStorage`)
- **Interfaces**: PascalCase with 'I' prefix (e.g., `IStorage`, `IAIProvider`)
- **Methods**: camelCase (e.g., `parsePRD`, `loadTasks`)
- **Constants**: UPPER_SNAKE_CASE (e.g., `DEFAULT_MODEL`)
- **Type aliases**: PascalCase (e.g., `TaskStatus`, `ParseOptions`)
## Exact Folder Structure Required
```
packages/tm-core/
├── src/
│ ├── index.ts
│ ├── types/
│ │ └── index.ts
│ ├── interfaces/
│ │ ├── index.ts # Barrel export
│ │ ├── storage.interface.ts
│ │ ├── ai-provider.interface.ts
│ │ └── configuration.interface.ts
│ ├── tasks/
│ │ ├── index.ts # Barrel export
│ │ └── task-parser.ts
│ ├── ai/
│ │ ├── index.ts # Barrel export
│ │ ├── base-provider.ts
│ │ ├── provider-factory.ts
│ │ ├── prompt-builder.ts
│ │ └── providers/
│ │ ├── index.ts # Barrel export
│ │ ├── anthropic-provider.ts
│ │ ├── openai-provider.ts
│ │ └── google-provider.ts
│ ├── storage/
│ │ ├── index.ts # Barrel export
│ │ └── file-storage.ts
│ ├── config/
│ │ ├── index.ts # Barrel export
│ │ └── config-manager.ts
│ ├── utils/
│ │ ├── index.ts # Barrel export
│ │ └── id-generator.ts
│ └── errors/
│ ├── index.ts # Barrel export
│ └── task-master-error.ts
├── tests/
│ ├── task-parser.test.ts
│ ├── integration/
│ │ └── parse-prd.test.ts
│ └── mocks/
│ └── mock-provider.ts
├── package.json
├── tsconfig.json
├── tsup.config.js
└── jest.config.js
```
## Specific Implementation Requirements
### 1. Create types/index.ts
Define these exact TypeScript interfaces:
- `Task` interface with fields: id, title, description, status, priority, complexity, dependencies, subtasks, metadata, createdAt, updatedAt, source
- `Subtask` interface with fields: id, title, description, completed
- `TaskMetadata` interface with fields: parsedFrom, aiProvider, version, tags (optional)
- Type literals: `TaskStatus` = 'pending' | 'in-progress' | 'completed' | 'blocked'
- Type literals: `TaskPriority` = 'low' | 'medium' | 'high' | 'critical'
- Type literals: `TaskComplexity` = 'simple' | 'moderate' | 'complex'
- `ParseOptions` interface with fields: dryRun (optional), additionalContext (optional), tag (optional), maxTasks (optional)
### 2. Create interfaces/storage.interface.ts
Define `IStorage` interface with these exact methods:
- `loadTasks(tag?: string): Promise<Task[]>`
- `saveTasks(tasks: Task[], tag?: string): Promise<void>`
- `appendTasks(tasks: Task[], tag?: string): Promise<void>`
- `updateTask(id: string, task: Partial<Task>, tag?: string): Promise<void>`
- `deleteTask(id: string, tag?: string): Promise<void>`
- `exists(tag?: string): Promise<boolean>`
### 3. Create interfaces/ai-provider.interface.ts
Define `IAIProvider` interface with these exact methods:
- `generateCompletion(prompt: string, options?: AIOptions): Promise<string>`
- `calculateTokens(text: string): number`
- `getName(): string`
- `getModel(): string`
Define `AIOptions` interface with fields: temperature (optional), maxTokens (optional), systemPrompt (optional)
### 4. Create interfaces/configuration.interface.ts
Define `IConfiguration` interface with fields:
- `projectPath: string`
- `aiProvider: string`
- `apiKey?: string`
- `aiOptions?: AIOptions`
- `mainModel?: string`
- `researchModel?: string`
- `fallbackModel?: string`
- `tasksPath?: string`
- `enableTags?: boolean`
### 5. Create tasks/task-parser.ts
Create class `TaskParser` with:
- Constructor accepting `aiProvider: IAIProvider` and `config: IConfiguration`
- Private property `promptBuilder: PromptBuilder`
- Public method `parsePRD(prdPath: string, options: ParseOptions = {}): Promise<Task[]>`
- Private method `readPRD(prdPath: string): Promise<string>`
- Private method `extractTasks(aiResponse: string): Partial<Task>[]`
- Private method `enrichTasks(rawTasks: Partial<Task>[], prdPath: string): Task[]`
- Apply **Dependency Injection** pattern via constructor
### 6. Create ai/base-provider.ts
Copy existing base-provider.js and convert to TypeScript abstract class:
- Abstract class `BaseProvider` implementing `IAIProvider`
- Protected properties: `apiKey: string`, `model: string`
- Constructor accepting `apiKey: string` and `options: { model?: string }`
- Abstract methods matching IAIProvider interface
- Abstract method `getDefaultModel(): string`
- Apply **Template Method** pattern for common provider logic
### 7. Create ai/provider-factory.ts
Create class `ProviderFactory` with:
- Static method `create(config: { provider: string; apiKey?: string; model?: string }): Promise<IAIProvider>`
- Switch statement for providers: 'anthropic', 'openai', 'google'
- Dynamic imports for each provider
- Throw error for unknown providers
- Apply **Factory** pattern for creating provider instances
Example implementation structure:
```typescript
switch (provider.toLowerCase()) {
case 'anthropic':
const { AnthropicProvider } = await import('./providers/anthropic-provider.js');
return new AnthropicProvider(apiKey, { model });
}
```
### 8. Create ai/providers/anthropic-provider.ts
Create class `AnthropicProvider` extending `BaseProvider`:
- Import Anthropic SDK: `import { Anthropic } from '@anthropic-ai/sdk'`
- Private property `client: Anthropic`
- Implement all abstract methods from BaseProvider
- Default model: 'claude-3-sonnet-20240229'
- Handle API errors and wrap with meaningful messages
### 9. Create ai/providers/openai-provider.ts (placeholder)
Create class `OpenAIProvider` extending `BaseProvider`:
- Import OpenAI SDK when implemented
- For now, throw error: "OpenAI provider not yet implemented"
### 10. Create ai/providers/google-provider.ts (placeholder)
Create class `GoogleProvider` extending `BaseProvider`:
- Import Google Generative AI SDK when implemented
- For now, throw error: "Google provider not yet implemented"
### 11. Create ai/prompt-builder.ts
Create class `PromptBuilder` with:
- Method `buildParsePrompt(prdContent: string, options: ParseOptions = {}): string`
- Method `buildExpandPrompt(task: string, context?: string): string`
- Use template literals for prompt construction
- Include specific JSON format instructions in prompts
### 9. Create storage/file-storage.ts
Create class `FileStorage` implementing `IStorage`:
- Private property `basePath: string` set to `{projectPath}/.taskmaster`
- Constructor accepting `projectPath: string`
- Private method `getTasksPath(tag?: string): string` returning correct path based on tag
- Private method `ensureDirectory(dir: string): Promise<void>`
- Implement all IStorage methods
- Handle ENOENT errors by returning empty arrays
- Use JSON format with structure: `{ tasks: Task[], metadata: { version: string, lastModified: string } }`
- Apply **Repository** pattern for data access abstraction
### 10. Create config/config-manager.ts
Create class `ConfigManager`:
- Private property `config: IConfiguration`
- Constructor accepting `options: Partial<IConfiguration>`
- Use Zod for validation with schema matching IConfiguration
- Method `get<K extends keyof IConfiguration>(key: K): IConfiguration[K]`
- Method `getAll(): IConfiguration`
- Method `validate(): boolean`
- Default values: projectPath = process.cwd(), aiProvider = 'anthropic', enableTags = true
### 11. Create utils/id-generator.ts
Export functions:
- `generateTaskId(index: number = 0): string` returning format `task_{timestamp}_{index}_{random}`
- `generateSubtaskId(parentId: string, index: number = 0): string` returning format `{parentId}_sub_{index}_{random}`
### 16. Create src/index.ts
Create main class `TaskMasterCore`:
- Private properties: `config: ConfigManager`, `storage: IStorage`, `aiProvider?: IAIProvider`, `parser?: TaskParser`
- Constructor accepting `options: Partial<IConfiguration>`
- Method `initialize(): Promise<void>` for lazy loading
- Method `parsePRD(prdPath: string, options: ParseOptions = {}): Promise<Task[]>`
- Method `getTasks(tag?: string): Promise<Task[]>`
- Apply **Facade** pattern to provide simple API over complex subsystems
Export:
- Class `TaskMasterCore`
- Function `createTaskMaster(options: Partial<IConfiguration>): TaskMasterCore`
- All types from './types'
- All interfaces from './interfaces/*'
Import statements should use kebab-case:
```typescript
import { TaskParser } from './tasks/task-parser';
import { FileStorage } from './storage/file-storage';
import { ConfigManager } from './config/config-manager';
import { ProviderFactory } from './ai/provider-factory';
```
### 17. Configure package.json
Create package.json with:
- name: "@task-master/core"
- version: "0.1.0"
- type: "module"
- main: "./dist/index.js"
- module: "./dist/index.mjs"
- types: "./dist/index.d.ts"
- exports map for proper ESM/CJS support
- scripts: build (tsup), dev (tsup --watch), test (jest), typecheck (tsc --noEmit)
- dependencies: zod@^3.23.8
- peerDependencies: @anthropic-ai/sdk, openai, @google/generative-ai
- devDependencies: typescript, tsup, jest, ts-jest, @types/node, @types/jest
### 18. Configure TypeScript
Create tsconfig.json with:
- target: "ES2022"
- module: "ESNext"
- strict: true (with all strict flags enabled)
- declaration: true
- outDir: "./dist"
- rootDir: "./src"
### 19. Configure tsup
Create tsup.config.js with:
- entry: ['src/index.ts']
- format: ['cjs', 'esm']
- dts: true
- sourcemap: true
- clean: true
- external: AI provider SDKs
### 20. Configure Jest
Create jest.config.js with:
- preset: 'ts-jest'
- testEnvironment: 'node'
- Coverage threshold: 80% for all metrics
## Build Process
1. Use tsup to compile TypeScript to both CommonJS and ESM
2. Generate .d.ts files for TypeScript consumers
3. Output to dist/ directory
4. Ensure tree-shaking works properly
## Testing Requirements
- Create unit tests for TaskParser in tests/task-parser.test.ts
- Create MockProvider class in tests/mocks/mock-provider.ts for testing without API calls
- Test error scenarios (file not found, invalid JSON, etc.)
- Create integration test in tests/integration/parse-prd.test.ts
- Follow kebab-case naming for all test files
## Success Criteria
- TypeScript compilation with zero errors
- No use of 'any' type
- All interfaces properly exported
- Compatible with existing tasks.json format
- Feature flag support via USE_TM_CORE environment variable
## Import/Export Conventions
- Use named exports for all classes and interfaces
- Use barrel exports (index.ts) in each directory
- Import types/interfaces with type-only imports: `import type { Task } from '../types'`
- Group imports in order: Node built-ins, external packages, internal packages, relative imports
- Use .js extension in import paths for ESM compatibility
## Error Handling Patterns
- Create custom error classes in `src/errors/` directory
- All public methods should catch and wrap errors with context
- Use error codes for different error types (e.g., 'FILE_NOT_FOUND', 'PARSE_ERROR')
- Never expose internal implementation details in error messages
- Log errors to console.error only in development mode
## Barrel Exports Content
### interfaces/index.ts
```typescript
export type { IStorage } from './storage.interface';
export type { IAIProvider, AIOptions } from './ai-provider.interface';
export type { IConfiguration } from './configuration.interface';
```
### tasks/index.ts
```typescript
export { TaskParser } from './task-parser';
```
### ai/index.ts
```typescript
export { BaseProvider } from './base-provider';
export { ProviderFactory } from './provider-factory';
export { PromptBuilder } from './prompt-builder';
```
### ai/providers/index.ts
```typescript
export { AnthropicProvider } from './anthropic-provider';
export { OpenAIProvider } from './openai-provider';
export { GoogleProvider } from './google-provider';
```
### storage/index.ts
```typescript
export { FileStorage } from './file-storage';
```
### config/index.ts
```typescript
export { ConfigManager } from './config-manager';
```
### utils/index.ts
```typescript
export { generateTaskId, generateSubtaskId } from './id-generator';
```
### errors/index.ts
```typescript
export { TaskMasterError } from './task-master-error';
```

View File

@@ -1,373 +1,21 @@
{
"meta": {
"generatedAt": "2025-05-27T16:34:53.088Z",
"generatedAt": "2025-08-02T14:28:59.851Z",
"tasksAnalyzed": 1,
"totalTasks": 84,
"analysisCount": 45,
"totalTasks": 93,
"analysisCount": 1,
"thresholdScore": 5,
"projectName": "Taskmaster",
"usedResearch": true
"usedResearch": false
},
"complexityAnalysis": [
{
"taskId": 24,
"taskTitle": "Implement AI-Powered Test Generation Command",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "Break down the implementation of the AI-powered test generation command into detailed subtasks covering: command structure setup, AI prompt engineering, test file generation logic, integration with Claude API, and comprehensive error handling.",
"reasoning": "This task involves complex integration with an AI service (Claude), requires sophisticated prompt engineering, and needs to generate structured code files. The existing 3 subtasks are a good start but could be expanded to include more detailed steps for AI integration, error handling, and test file formatting."
},
{
"taskId": 26,
"taskTitle": "Implement Context Foundation for AI Operations",
"complexityScore": 6,
"recommendedSubtasks": 4,
"expansionPrompt": "The current 4 subtasks for implementing the context foundation appear comprehensive. Consider if any additional subtasks are needed for testing, documentation, or integration with existing systems.",
"reasoning": "This task involves creating a foundation for context integration with several well-defined components. The existing 4 subtasks cover the main implementation areas (context-file flag, cursor rules integration, context extraction utility, and command handler updates). The complexity is moderate as it requires careful integration with existing systems but has clear requirements."
},
{
"taskId": 27,
"taskTitle": "Implement Context Enhancements for AI Operations",
"complexityScore": 7,
"recommendedSubtasks": 4,
"expansionPrompt": "The current 4 subtasks for implementing context enhancements appear well-structured. Consider if any additional subtasks are needed for testing, documentation, or performance optimization.",
"reasoning": "This task builds upon the foundation from Task #26 and adds more sophisticated context handling features. The 4 existing subtasks cover the main implementation areas (code context extraction, task history context, PRD context integration, and context formatting). The complexity is higher than the foundation task due to the need for intelligent context selection and optimization."
},
{
"taskId": 28,
"taskTitle": "Implement Advanced ContextManager System",
"complexityScore": 8,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing the advanced ContextManager system appear comprehensive. Consider if any additional subtasks are needed for testing, documentation, or backward compatibility with previous context implementations.",
"reasoning": "This task represents the most complex phase of the context implementation, requiring a sophisticated class design, optimization algorithms, and integration with multiple systems. The 5 existing subtasks cover the core implementation areas, but the complexity is high due to the need for intelligent context prioritization, token management, and performance monitoring."
},
{
"taskId": 40,
"taskTitle": "Implement 'plan' Command for Task Implementation Planning",
"complexityScore": 5,
"recommendedSubtasks": 4,
"expansionPrompt": "The current 4 subtasks for implementing the 'plan' command appear well-structured. Consider if any additional subtasks are needed for testing, documentation, or integration with existing task management workflows.",
"reasoning": "This task involves creating a new command that leverages AI to generate implementation plans. The existing 4 subtasks cover the main implementation areas (retrieving task content, generating plans with AI, formatting in XML, and error handling). The complexity is moderate as it builds on existing patterns for task updates but requires careful AI integration."
},
{
"taskId": 41,
"taskTitle": "Implement Visual Task Dependency Graph in Terminal",
"complexityScore": 8,
"recommendedSubtasks": 10,
"expansionPrompt": "The current 10 subtasks for implementing the visual task dependency graph appear comprehensive. Consider if any additional subtasks are needed for performance optimization with large graphs or additional visualization options.",
"reasoning": "This task involves creating a sophisticated visualization system for terminal display, which is inherently complex due to layout algorithms, ASCII/Unicode rendering, and handling complex dependency relationships. The 10 existing subtasks cover all major aspects of implementation, from CLI interface to accessibility features."
},
{
"taskId": 42,
"taskTitle": "Implement MCP-to-MCP Communication Protocol",
"complexityScore": 9,
"recommendedSubtasks": 8,
"expansionPrompt": "The current 8 subtasks for implementing the MCP-to-MCP communication protocol appear well-structured. Consider if any additional subtasks are needed for security hardening, performance optimization, or comprehensive documentation.",
"reasoning": "This task involves designing and implementing a complex communication protocol between different MCP tools and servers. It requires sophisticated adapter patterns, client-server architecture, and handling of multiple operational modes. The complexity is very high due to the need for standardization, security, and backward compatibility."
},
{
"taskId": 44,
"taskTitle": "Implement Task Automation with Webhooks and Event Triggers",
"complexityScore": 8,
"recommendedSubtasks": 7,
"expansionPrompt": "The current 7 subtasks for implementing task automation with webhooks appear comprehensive. Consider if any additional subtasks are needed for security testing, rate limiting implementation, or webhook monitoring tools.",
"reasoning": "This task involves creating a sophisticated event system with webhooks for integration with external services. The complexity is high due to the need for secure authentication, reliable delivery mechanisms, and handling of various webhook formats and protocols. The existing subtasks cover the main implementation areas but security and monitoring could be emphasized more."
},
{
"taskId": 45,
"taskTitle": "Implement GitHub Issue Import Feature",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing the GitHub issue import feature appear well-structured. Consider if any additional subtasks are needed for handling GitHub API rate limiting, caching, or supporting additional issue metadata.",
"reasoning": "This task involves integrating with the GitHub API to import issues as tasks. The complexity is moderate as it requires API authentication, data mapping, and error handling. The existing 5 subtasks cover the main implementation areas from design to end-to-end implementation."
},
{
"taskId": 46,
"taskTitle": "Implement ICE Analysis Command for Task Prioritization",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing the ICE analysis command appear comprehensive. Consider if any additional subtasks are needed for visualization of ICE scores or integration with other prioritization methods.",
"reasoning": "This task involves creating an AI-powered analysis system for task prioritization using the ICE methodology. The complexity is high due to the need for sophisticated scoring algorithms, AI integration, and report generation. The existing subtasks cover the main implementation areas from algorithm design to integration with existing systems."
},
{
"taskId": 47,
"taskTitle": "Enhance Task Suggestion Actions Card Workflow",
"complexityScore": 6,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for enhancing the task suggestion actions card workflow appear well-structured. Consider if any additional subtasks are needed for user testing, accessibility improvements, or performance optimization.",
"reasoning": "This task involves redesigning the UI workflow for task expansion and management. The complexity is moderate as it requires careful UX design and state management but builds on existing components. The 6 existing subtasks cover the main implementation areas from design to testing."
},
{
"taskId": 48,
"taskTitle": "Refactor Prompts into Centralized Structure",
"complexityScore": 4,
"recommendedSubtasks": 3,
"expansionPrompt": "The current 3 subtasks for refactoring prompts into a centralized structure appear appropriate. Consider if any additional subtasks are needed for prompt versioning, documentation, or testing.",
"reasoning": "This task involves a straightforward refactoring to improve code organization. The complexity is relatively low as it primarily involves moving code rather than creating new functionality. The 3 existing subtasks cover the main implementation areas from directory structure to integration."
},
{
"taskId": 49,
"taskTitle": "Implement Code Quality Analysis Command",
"complexityScore": 8,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for implementing the code quality analysis command appear comprehensive. Consider if any additional subtasks are needed for performance optimization with large codebases or integration with existing code quality tools.",
"reasoning": "This task involves creating a sophisticated code analysis system with pattern recognition, best practice verification, and AI-powered recommendations. The complexity is high due to the need for code parsing, complex analysis algorithms, and integration with AI services. The existing subtasks cover the main implementation areas from algorithm design to user interface."
},
{
"taskId": 50,
"taskTitle": "Implement Test Coverage Tracking System by Task",
"complexityScore": 9,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing the test coverage tracking system appear well-structured. Consider if any additional subtasks are needed for integration with CI/CD systems, performance optimization, or visualization tools.",
"reasoning": "This task involves creating a complex system that maps test coverage to specific tasks and subtasks. The complexity is very high due to the need for sophisticated data structures, integration with coverage tools, and AI-powered test generation. The existing subtasks are comprehensive and cover the main implementation areas from data structure design to AI integration."
},
{
"taskId": 51,
"taskTitle": "Implement Perplexity Research Command",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing the Perplexity research command appear comprehensive. Consider if any additional subtasks are needed for caching optimization, result formatting, or integration with other research tools.",
"reasoning": "This task involves creating a new command that integrates with the Perplexity AI API for research. The complexity is moderate as it requires API integration, context extraction, and result formatting. The 5 existing subtasks cover the main implementation areas from API client to caching system."
},
{
"taskId": 52,
"taskTitle": "Implement Task Suggestion Command for CLI",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing the task suggestion command appear well-structured. Consider if any additional subtasks are needed for suggestion quality evaluation, user feedback collection, or integration with existing task workflows.",
"reasoning": "This task involves creating a new CLI command that generates contextually relevant task suggestions using AI. The complexity is moderate as it requires AI integration, context collection, and interactive CLI interfaces. The existing subtasks cover the main implementation areas from data collection to user interface."
},
{
"taskId": 53,
"taskTitle": "Implement Subtask Suggestion Feature for Parent Tasks",
"complexityScore": 6,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for implementing the subtask suggestion feature appear comprehensive. Consider if any additional subtasks are needed for suggestion quality metrics, user feedback collection, or performance optimization.",
"reasoning": "This task involves creating a feature that suggests contextually relevant subtasks for parent tasks. The complexity is moderate as it builds on existing task management systems but requires sophisticated AI integration and context analysis. The 6 existing subtasks cover the main implementation areas from validation to testing."
},
{
"taskId": 55,
"taskTitle": "Implement Positional Arguments Support for CLI Commands",
"complexityScore": 5,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing positional arguments support appear well-structured. Consider if any additional subtasks are needed for backward compatibility testing, documentation updates, or user experience improvements.",
"reasoning": "This task involves modifying the command parsing logic to support positional arguments alongside the existing flag-based syntax. The complexity is moderate as it requires careful handling of different argument styles and edge cases. The 5 existing subtasks cover the main implementation areas from analysis to documentation."
},
{
"taskId": 57,
"taskTitle": "Enhance Task-Master CLI User Experience and Interface",
"complexityScore": 7,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for enhancing the CLI user experience appear comprehensive. Consider if any additional subtasks are needed for accessibility testing, internationalization, or performance optimization.",
"reasoning": "This task involves a significant overhaul of the CLI interface to improve user experience. The complexity is high due to the breadth of changes (logging, visual elements, interactive components, etc.) and the need for consistent design across all commands. The 6 existing subtasks cover the main implementation areas from log management to help systems."
},
{
"taskId": 60,
"taskTitle": "Implement Mentor System with Round-Table Discussion Feature",
"complexityScore": 8,
"recommendedSubtasks": 7,
"expansionPrompt": "The current 7 subtasks for implementing the mentor system appear well-structured. Consider if any additional subtasks are needed for mentor personality consistency, discussion quality evaluation, or performance optimization with multiple mentors.",
"reasoning": "This task involves creating a sophisticated mentor simulation system with round-table discussions. The complexity is high due to the need for personality simulation, complex LLM integration, and structured discussion management. The 7 existing subtasks cover the main implementation areas from architecture to testing."
},
{
"taskId": 62,
"taskTitle": "Add --simple Flag to Update Commands for Direct Text Input",
"complexityScore": 4,
"recommendedSubtasks": 8,
"expansionPrompt": "The current 8 subtasks for implementing the --simple flag appear comprehensive. Consider if any additional subtasks are needed for user experience testing or documentation updates.",
"reasoning": "This task involves adding a simple flag option to bypass AI processing for updates. The complexity is relatively low as it primarily involves modifying existing command handlers and adding a flag. The 8 existing subtasks are very detailed and cover all aspects of implementation from command parsing to testing."
},
{
"taskId": 63,
"taskTitle": "Add pnpm Support for the Taskmaster Package",
"complexityScore": 5,
"recommendedSubtasks": 8,
"expansionPrompt": "The current 8 subtasks for adding pnpm support appear comprehensive. Consider if any additional subtasks are needed for CI/CD integration, performance comparison, or documentation updates.",
"reasoning": "This task involves ensuring the package works correctly with pnpm as an alternative package manager. The complexity is moderate as it requires careful testing of installation processes and scripts across different environments. The 8 existing subtasks cover all major aspects from documentation to binary verification."
},
{
"taskId": 64,
"taskTitle": "Add Yarn Support for Taskmaster Installation",
"complexityScore": 5,
"recommendedSubtasks": 9,
"expansionPrompt": "The current 9 subtasks for adding Yarn support appear comprehensive. Consider if any additional subtasks are needed for performance testing, CI/CD integration, or compatibility with different Yarn versions.",
"reasoning": "This task involves ensuring the package works correctly with Yarn as an alternative package manager. The complexity is moderate as it requires careful testing of installation processes and scripts across different environments. The 9 existing subtasks are very detailed and cover all aspects from configuration to testing."
},
{
"taskId": 65,
"taskTitle": "Add Bun Support for Taskmaster Installation",
"complexityScore": 6,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for adding Bun support appear well-structured. Consider if any additional subtasks are needed for handling Bun-specific issues, performance testing, or documentation updates.",
"reasoning": "This task involves adding support for the newer Bun package manager. The complexity is slightly higher than the other package manager tasks due to Bun's differences from Node.js and potential compatibility issues. The 6 existing subtasks cover the main implementation areas from research to documentation."
},
{
"taskId": 67,
"taskTitle": "Add CLI JSON output and Cursor keybindings integration",
"complexityScore": 5,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing JSON output and Cursor keybindings appear well-structured. Consider if any additional subtasks are needed for testing across different operating systems, documentation updates, or user experience improvements.",
"reasoning": "This task involves two distinct features: adding JSON output to CLI commands and creating a keybindings installation command. The complexity is moderate as it requires careful handling of different output formats and OS-specific file paths. The 5 existing subtasks cover the main implementation areas for both features."
},
{
"taskId": 68,
"taskTitle": "Ability to create tasks without parsing PRD",
"complexityScore": 3,
"recommendedSubtasks": 2,
"expansionPrompt": "The current 2 subtasks for implementing task creation without PRD appear appropriate. Consider if any additional subtasks are needed for validation, error handling, or integration with existing task management workflows.",
"reasoning": "This task involves a relatively simple modification to allow task creation without requiring a PRD document. The complexity is low as it primarily involves creating a form interface and saving functionality. The 2 existing subtasks cover the main implementation areas of UI design and data saving."
},
{
"taskId": 72,
"taskTitle": "Implement PDF Generation for Project Progress and Dependency Overview",
"complexityScore": 7,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for implementing PDF generation appear comprehensive. Consider if any additional subtasks are needed for handling large projects, additional visualization options, or integration with existing reporting tools.",
"reasoning": "This task involves creating a feature to generate PDF reports of project progress and dependency visualization. The complexity is high due to the need for PDF generation, data collection, and visualization integration. The 6 existing subtasks cover the main implementation areas from library selection to export options."
},
{
"taskId": 75,
"taskTitle": "Integrate Google Search Grounding for Research Role",
"complexityScore": 5,
"recommendedSubtasks": 4,
"expansionPrompt": "The current 4 subtasks for integrating Google Search Grounding appear well-structured. Consider if any additional subtasks are needed for testing with different query types, error handling, or performance optimization.",
"reasoning": "This task involves updating the AI service layer to enable Google Search Grounding for research roles. The complexity is moderate as it requires careful integration with the existing AI service architecture and conditional logic. The 4 existing subtasks cover the main implementation areas from service layer modification to testing."
},
{
"taskId": 76,
"taskTitle": "Develop E2E Test Framework for Taskmaster MCP Server (FastMCP over stdio)",
"complexityScore": 8,
"recommendedSubtasks": 7,
"expansionPrompt": "The current 7 subtasks for developing the E2E test framework appear comprehensive. Consider if any additional subtasks are needed for test result reporting, CI/CD integration, or performance benchmarking.",
"reasoning": "This task involves creating a sophisticated end-to-end testing framework for the MCP server. The complexity is high due to the need for subprocess management, protocol handling, and robust test case definition. The 7 existing subtasks cover the main implementation areas from architecture to documentation."
},
{
"taskId": 77,
"taskTitle": "Implement AI Usage Telemetry for Taskmaster (with external analytics endpoint)",
"complexityScore": 7,
"recommendedSubtasks": 18,
"expansionPrompt": "The current 18 subtasks for implementing AI usage telemetry appear very comprehensive. Consider if any additional subtasks are needed for security hardening, privacy compliance, or user feedback collection.",
"reasoning": "This task involves creating a telemetry system to track AI usage metrics. The complexity is high due to the need for secure data transmission, comprehensive data collection, and integration across multiple commands. The 18 existing subtasks are extremely detailed and cover all aspects of implementation from core utility to provider-specific updates."
},
{
"taskId": 80,
"taskTitle": "Implement Unique User ID Generation and Storage During Installation",
"complexityScore": 4,
"recommendedSubtasks": 5,
"expansionPrompt": "The current 5 subtasks for implementing unique user ID generation appear well-structured. Consider if any additional subtasks are needed for privacy compliance, security auditing, or integration with the telemetry system.",
"reasoning": "This task involves generating and storing a unique user identifier during installation. The complexity is relatively low as it primarily involves UUID generation and configuration file management. The 5 existing subtasks cover the main implementation areas from script structure to documentation."
},
{
"taskId": 81,
"taskTitle": "Task #81: Implement Comprehensive Local Telemetry System with Future Server Integration Capability",
"complexityScore": 8,
"recommendedSubtasks": 6,
"expansionPrompt": "The current 6 subtasks for implementing the comprehensive local telemetry system appear well-structured. Consider if any additional subtasks are needed for data migration, storage optimization, or visualization tools.",
"reasoning": "This task involves expanding the telemetry system to capture additional metrics and implement local storage with future server integration capability. The complexity is high due to the breadth of data collection, storage requirements, and privacy considerations. The 6 existing subtasks cover the main implementation areas from data collection to user-facing benefits."
},
{
"taskId": 82,
"taskTitle": "Update supported-models.json with token limit fields",
"complexityScore": 3,
"recommendedSubtasks": 1,
"expansionPrompt": "This task appears straightforward enough to be implemented without further subtasks. Focus on researching accurate token limit values for each model and ensuring backward compatibility.",
"reasoning": "This task involves a simple update to the supported-models.json file to include new token limit fields. The complexity is low as it primarily involves research and data entry. No subtasks are necessary as the task is well-defined and focused."
},
{
"taskId": 83,
"taskTitle": "Update config-manager.js defaults and getters",
"complexityScore": 4,
"recommendedSubtasks": 1,
"expansionPrompt": "This task appears straightforward enough to be implemented without further subtasks. Focus on updating the DEFAULTS object and related getter functions while maintaining backward compatibility.",
"reasoning": "This task involves updating the config-manager.js module to replace maxTokens with more specific token limit fields. The complexity is relatively low as it primarily involves modifying existing code rather than creating new functionality. No subtasks are necessary as the task is well-defined and focused."
},
{
"taskId": 84,
"taskTitle": "Implement token counting utility",
"complexityScore": 5,
"recommendedSubtasks": 1,
"expansionPrompt": "This task appears well-defined enough to be implemented without further subtasks. Focus on implementing accurate token counting for different models and proper fallback mechanisms.",
"reasoning": "This task involves creating a utility function to count tokens for different AI models. The complexity is moderate as it requires integration with the tiktoken library and handling different tokenization schemes. No subtasks are necessary as the task is well-defined and focused."
},
{
"taskId": 69,
"taskTitle": "Enhance Analyze Complexity for Specific Task IDs",
"complexityScore": 7,
"recommendedSubtasks": 6,
"expansionPrompt": "Break down the task 'Enhance Analyze Complexity for Specific Task IDs' into 6 subtasks focusing on: 1) Core logic modification to accept ID parameters, 2) Report merging functionality, 3) CLI interface updates, 4) MCP tool integration, 5) Documentation updates, and 6) Comprehensive testing across all components.",
"reasoning": "This task involves modifying existing functionality across multiple components (core logic, CLI, MCP) with complex logic for filtering tasks and merging reports. The implementation requires careful handling of different parameter combinations and edge cases. The task has interdependent components that need to work together seamlessly, and the report merging functionality adds significant complexity."
},
{
"taskId": 70,
"taskTitle": "Implement 'diagram' command for Mermaid diagram generation",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "Break down the 'diagram' command implementation into 5 subtasks: 1) Command interface and parameter handling, 2) Task data extraction and transformation to Mermaid syntax, 3) Diagram rendering with status color coding, 4) Output formatting and file export functionality, and 5) Error handling and edge case management.",
"reasoning": "This task requires implementing a new feature rather than modifying existing code, which reduces complexity from integration challenges. However, it involves working with visualization logic, dependency mapping, and multiple output formats. The color coding based on status and handling of dependency relationships adds moderate complexity. The task is well-defined but requires careful attention to diagram formatting and error handling."
},
{
"taskId": 85,
"taskTitle": "Update ai-services-unified.js for dynamic token limits",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "Break down the update of ai-services-unified.js for dynamic token limits into subtasks such as: (1) Import and integrate the token counting utility, (2) Refactor _unifiedServiceRunner to calculate and enforce dynamic token limits, (3) Update error handling for token limit violations, (4) Add and verify logging for token usage, (5) Write and execute tests for various prompt and model scenarios.",
"reasoning": "This task involves significant code changes to a core function, integration of a new utility, dynamic logic for multiple models, and robust error handling. It also requires comprehensive testing for edge cases and integration, making it moderately complex and best managed by splitting into focused subtasks."
},
{
"taskId": 87,
"taskTitle": "Implement validation and error handling",
"complexityScore": 5,
"recommendedSubtasks": 4,
"expansionPrompt": "Decompose this task into: (1) Add validation logic for model and config loading, (2) Implement error handling and fallback mechanisms, (3) Enhance logging and reporting for token usage, (4) Develop helper functions for configuration suggestions and improvements.",
"reasoning": "This task is primarily about adding validation, error handling, and logging. While important for robustness, the logic is straightforward and can be modularized into a few clear subtasks."
},
{
"taskId": 89,
"taskTitle": "Introduce Prioritize Command with Enhanced Priority Levels",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "Expand this task into: (1) Implement the prioritize command with all required flags and shorthands, (2) Update CLI output and help documentation for new priority levels, (3) Ensure backward compatibility with existing commands, (4) Add error handling for invalid inputs, (5) Write and run tests for all command scenarios.",
"reasoning": "This CLI feature requires command parsing, updating internal logic for new priority levels, documentation, and robust error handling. The complexity is moderate due to the need for backward compatibility and comprehensive testing."
},
{
"taskId": 90,
"taskTitle": "Implement Subtask Progress Analyzer and Reporting System",
"complexityScore": 8,
"recommendedSubtasks": 6,
"expansionPrompt": "Break down the analyzer implementation into: (1) Design and implement progress tracking logic, (2) Develop status validation and issue detection, (3) Build the reporting system with multiple output formats, (4) Integrate analyzer with the existing task management system, (5) Optimize for performance and scalability, (6) Write unit, integration, and performance tests.",
"reasoning": "This is a complex, multi-faceted feature involving data analysis, reporting, integration, and performance optimization. It touches many parts of the system and requires careful design, making it one of the most complex tasks in the list."
},
{
"taskId": 91,
"taskTitle": "Implement Move Command for Tasks and Subtasks",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "Expand this task into: (1) Implement move logic for tasks and subtasks, (2) Handle edge cases (invalid ids, non-existent parents, circular dependencies), (3) Update CLI to support move command with flags, (4) Ensure data integrity and update relationships, (5) Write and execute tests for various move scenarios.",
"reasoning": "Moving tasks and subtasks requires careful handling of hierarchical data, edge cases, and data integrity. The command must be robust and user-friendly, necessitating multiple focused subtasks for safe implementation."
},
{
"taskId": 92,
"taskTitle": "Add Global Joke Flag to All CLI Commands",
"complexityScore": 8,
"recommendedSubtasks": 7,
"expansionPrompt": "Break down the implementation of the global --joke flag into the following subtasks: (1) Update CLI foundation to support global flags, (2) Develop the joke-service module with joke management and category support, (3) Integrate joke output into existing output utilities, (4) Update all CLI commands for joke flag compatibility, (5) Add configuration options for joke categories and custom jokes, (6) Implement comprehensive testing (flag recognition, output, content, integration, performance, regression), (7) Update documentation and usage examples.",
"reasoning": "This task requires changes across the CLI foundation, output utilities, all command modules, and configuration management. It introduces a new service module, global flag handling, and output logic that must not interfere with existing features (including JSON output). The need for robust testing and backward compatibility further increases complexity. The scope spans multiple code areas and requires careful integration, justifying a high complexity score and a detailed subtask breakdown to manage risk and ensure maintainability.[2][3][5]"
},
{
"taskId": 94,
"taskTitle": "Implement Standalone 'research' CLI Command for AI-Powered Queries",
"complexityScore": 7,
"recommendedSubtasks": 6,
"expansionPrompt": "Break down the implementation of the 'research' CLI command into logical subtasks covering command registration, parameter handling, context gathering, AI service integration, output formatting, and documentation.",
"reasoning": "This task has moderate to high complexity (7/10) due to multiple interconnected components: CLI argument parsing, integration with AI services, context gathering from various sources, and output formatting with different modes. The cyclomatic complexity would be significant with multiple decision paths for handling different flags and options. The task requires understanding existing patterns and extending the codebase in a consistent manner, suggesting the need for careful decomposition into manageable subtasks."
},
{
"taskId": 86,
"taskTitle": "Implement GitHub Issue Export Feature",
"complexityScore": 9,
"recommendedSubtasks": 10,
"expansionPrompt": "Break down the implementation of the GitHub Issue Export Feature into detailed subtasks covering: command structure and CLI integration, GitHub API client development, authentication and error handling, task-to-issue mapping logic, content formatting and markdown conversion, bidirectional linking and metadata management, extensible architecture and adapter interfaces, configuration and settings management, documentation, and comprehensive testing (unit, integration, edge cases, performance).",
"reasoning": "This task involves designing and implementing a robust, extensible export system with deep integration into GitHub, including bidirectional workflows, complex data mapping, error handling, and support for future platforms. The requirements span CLI design, API integration, content transformation, metadata management, extensibility, configuration, and extensive testing. The breadth and depth of these requirements, along with the need for maintainability and future extensibility, place this task at a high complexity level. Breaking it into at least 10 subtasks will ensure each major component and concern is addressed systematically, reducing risk and improving quality."
"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.",
"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."
}
]
}

View File

@@ -0,0 +1,77 @@
{
"meta": {
"generatedAt": "2025-08-06T12:39:03.250Z",
"tasksAnalyzed": 8,
"totalTasks": 11,
"analysisCount": 8,
"thresholdScore": 5,
"projectName": "Taskmaster",
"usedResearch": false
},
"complexityAnalysis": [
{
"taskId": 118,
"taskTitle": "Create AI Provider Base Architecture",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "Break down the implementation of BaseProvider abstract TypeScript class into subtasks focusing on: 1) Converting existing JavaScript base-provider.js to TypeScript with proper interface definitions, 2) Implementing the Template Method pattern with abstract methods, 3) Adding comprehensive error handling and retry logic with exponential backoff, 4) Creating proper TypeScript types for all method signatures and options, 5) Setting up comprehensive unit tests with MockProvider. Consider that the existing codebase uses JavaScript ES modules and Vercel AI SDK, so the TypeScript implementation needs to maintain compatibility while adding type safety.",
"reasoning": "This task requires significant architectural work including converting existing JavaScript code to TypeScript, creating new interfaces, implementing design patterns, and ensuring backward compatibility. The existing base-provider.js already implements a sophisticated provider pattern using Vercel AI SDK, so the TypeScript conversion needs careful consideration of type definitions and maintaining existing functionality."
},
{
"taskId": 119,
"taskTitle": "Implement Provider Factory with Dynamic Imports",
"complexityScore": 5,
"recommendedSubtasks": 5,
"expansionPrompt": "Break down the Provider Factory implementation into: 1) Creating the ProviderFactory class structure with proper TypeScript typing, 2) Implementing the switch statement for provider selection logic, 3) Adding dynamic imports for each provider to enable tree-shaking, 4) Handling provider instantiation with configuration passing, 5) Implementing comprehensive error handling for module loading failures. Note that the existing codebase already has a provider selection mechanism in the JavaScript files, so ensure the factory pattern integrates smoothly with existing infrastructure.",
"reasoning": "This is a moderate complexity task that involves creating a factory pattern with dynamic imports. The existing codebase already has provider management logic, so the main complexity is in creating a clean TypeScript implementation with proper dynamic imports while maintaining compatibility with the existing JavaScript module system."
},
{
"taskId": 120,
"taskTitle": "Implement Anthropic Provider",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "Implement the AnthropicProvider class in stages: 1) Set up the class structure extending BaseProvider with proper TypeScript imports and type definitions, 2) Implement constructor with Anthropic SDK client initialization and configuration handling, 3) Implement generateCompletion method with proper message format transformation and error handling, 4) Add token calculation methods and utility functions (getName, getModel, getDefaultModel), 5) Implement comprehensive error handling with custom error wrapping and type exports. The existing anthropic.js provider can serve as a reference but needs to be reimplemented to extend the new TypeScript BaseProvider.",
"reasoning": "This task involves integrating with an external SDK (@anthropic-ai/sdk) and implementing all abstract methods from BaseProvider. The existing JavaScript implementation provides a good reference, but the TypeScript version needs proper type definitions, error handling, and must work with the new abstract base class architecture."
},
{
"taskId": 121,
"taskTitle": "Create Prompt Builder and Task Parser",
"complexityScore": 8,
"recommendedSubtasks": 5,
"expansionPrompt": "Implement PromptBuilder and TaskParser with focus on: 1) Creating PromptBuilder class with template methods for building structured prompts with JSON format instructions, 2) Implementing TaskParser class structure with dependency injection of IAIProvider and IConfiguration, 3) Implementing parsePRD method with file reading, prompt generation, and AI provider integration, 4) Adding task enrichment logic with metadata, validation, and structure verification, 5) Implementing comprehensive error handling for all failure scenarios including file I/O, AI provider errors, and JSON parsing. The existing parse-prd.js provides complex logic that needs to be reimplemented with proper TypeScript types and cleaner architecture.",
"reasoning": "This is a complex task that involves multiple components working together: file I/O, AI provider integration, JSON parsing, and data validation. The existing parse-prd.js implementation is quite sophisticated with Zod schemas and complex task processing logic that needs to be reimplemented in TypeScript with proper separation of concerns."
},
{
"taskId": 122,
"taskTitle": "Implement Configuration Management",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "Create ConfigManager implementation focusing on: 1) Setting up Zod validation schema that matches the IConfiguration interface structure, 2) Implementing ConfigManager constructor with default values merging and storage initialization, 3) Creating validate method with Zod schema parsing and user-friendly error transformation, 4) Implementing type-safe get method using TypeScript generics and keyof operator, 5) Adding getAll method and ensuring proper immutability and module exports. The existing config-manager.js has complex configuration loading logic that can inform the TypeScript implementation but needs cleaner architecture.",
"reasoning": "This task involves creating a configuration management system with validation using Zod. The existing JavaScript config-manager.js is quite complex with multiple configuration sources, defaults, and validation logic. The TypeScript version needs to provide a cleaner API while maintaining the flexibility of the current system."
},
{
"taskId": 123,
"taskTitle": "Create Utility Functions and Error Handling",
"complexityScore": 4,
"recommendedSubtasks": 5,
"expansionPrompt": "Implement utilities and error handling in stages: 1) Create ID generation module with generateTaskId and generateSubtaskId functions using proper random generation, 2) Implement base TaskMasterError class extending Error with proper TypeScript typing, 3) Add error sanitization methods to prevent sensitive data exposure in production, 4) Implement development-only logging with environment detection, 5) Create specialized error subclasses (FileNotFoundError, ParseError, ValidationError, APIError) with appropriate error codes and formatting.",
"reasoning": "This is a relatively straightforward task involving utility functions and error class hierarchies. The main complexity is in ensuring proper error sanitization for production use and creating a well-structured error hierarchy that can be used throughout the application."
},
{
"taskId": 124,
"taskTitle": "Implement TaskMasterCore Facade",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "Build TaskMasterCore facade implementation: 1) Create class structure with proper TypeScript imports and type definitions for all subsystem interfaces, 2) Implement initialize method for lazy loading AI provider and parser instances based on configuration, 3) Create parsePRD method that coordinates parser, AI provider, and storage subsystems, 4) Implement getTasks and other facade methods for task retrieval and management, 5) Create createTaskMaster factory function and set up all module exports including type re-exports. Ensure proper ESM compatibility with .js extensions in imports.",
"reasoning": "This is a complex integration task that brings together all the other components into a cohesive facade. It requires understanding of the facade pattern, proper dependency management, lazy initialization, and careful module export structure for the public API."
},
{
"taskId": 125,
"taskTitle": "Create Placeholder Providers and Complete Testing",
"complexityScore": 5,
"recommendedSubtasks": 5,
"expansionPrompt": "Complete the implementation with placeholders and testing: 1) Create OpenAIProvider placeholder class extending BaseProvider with 'not yet implemented' errors, 2) Create GoogleProvider placeholder class with similar structure, 3) Implement MockProvider in tests/mocks directory with configurable responses and behavior simulation, 4) Write comprehensive unit tests for TaskParser covering all methods and edge cases, 5) Create integration tests for the complete parse-prd workflow ensuring 80% code coverage. Follow kebab-case naming convention for test files.",
"reasoning": "This task involves creating placeholder implementations and a comprehensive test suite. While the placeholder providers are simple, creating a good MockProvider and comprehensive tests requires understanding the entire system architecture and ensuring all edge cases are covered."
}
]
}

View File

@@ -0,0 +1,77 @@
{
"meta": {
"generatedAt": "2025-08-06T12:15:01.327Z",
"tasksAnalyzed": 8,
"totalTasks": 11,
"analysisCount": 8,
"thresholdScore": 5,
"projectName": "Taskmaster",
"usedResearch": false
},
"complexityAnalysis": [
{
"taskId": 118,
"taskTitle": "Create AI Provider Base Architecture",
"complexityScore": 4,
"recommendedSubtasks": 5,
"expansionPrompt": "Break down the conversion of base-provider.js to TypeScript BaseProvider class: 1) Convert to TypeScript and define IAIProvider interface, 2) Implement abstract class with core properties, 3) Define abstract methods and Template Method pattern, 4) Add retry logic with exponential backoff, 5) Implement validation and logging. Focus on maintaining compatibility with existing provider pattern while adding type safety.",
"reasoning": "The codebase already has a well-established BaseAIProvider class in JavaScript. Converting to TypeScript mainly involves adding type definitions and ensuring the existing pattern is preserved. The complexity is moderate because the pattern is already proven in the codebase."
},
{
"taskId": 119,
"taskTitle": "Implement Provider Factory with Dynamic Imports",
"complexityScore": 3,
"recommendedSubtasks": 5,
"expansionPrompt": "Create ProviderFactory implementation: 1) Set up class structure and types, 2) Implement provider selection switch statement, 3) Add dynamic imports for tree-shaking, 4) Handle provider instantiation with config, 5) Add comprehensive error handling. The existing PROVIDERS registry pattern should guide the implementation.",
"reasoning": "The codebase already uses a dual registry pattern (static PROVIDERS and dynamic ProviderRegistry). Creating a factory is straightforward as the provider registration patterns are well-established. Dynamic imports are already used in the codebase."
},
{
"taskId": 120,
"taskTitle": "Implement Anthropic Provider",
"complexityScore": 3,
"recommendedSubtasks": 5,
"expansionPrompt": "Implement AnthropicProvider following existing patterns: 1) Create class structure with imports, 2) Implement constructor and client initialization, 3) Add generateCompletion with Claude API integration, 4) Implement token calculation and utility methods, 5) Add error handling and exports. Use the existing anthropic.js provider as reference.",
"reasoning": "AnthropicProvider already exists in the codebase with full implementation. This task essentially involves adapting the existing implementation to match the new TypeScript architecture, making it relatively straightforward."
},
{
"taskId": 121,
"taskTitle": "Create Prompt Builder and Task Parser",
"complexityScore": 6,
"recommendedSubtasks": 5,
"expansionPrompt": "Build prompt system and parser: 1) Create PromptBuilder with template methods, 2) Implement TaskParser with dependency injection, 3) Add parsePRD core logic with file reading, 4) Implement task enrichment and metadata, 5) Add comprehensive error handling. Leverage the existing prompt management system in src/prompts/.",
"reasoning": "While the codebase has a sophisticated prompt management system, creating a new PromptBuilder and TaskParser requires understanding the existing prompt templates, JSON schema validation, and integration with the AI provider system. The task involves significant new code."
},
{
"taskId": 122,
"taskTitle": "Implement Configuration Management",
"complexityScore": 5,
"recommendedSubtasks": 5,
"expansionPrompt": "Create ConfigManager with validation: 1) Define Zod schema for IConfiguration, 2) Implement constructor with defaults, 3) Add validate method with error handling, 4) Create type-safe get method with generics, 5) Implement getAll and finalize exports. Reference existing config-manager.js for patterns.",
"reasoning": "The codebase has an existing config-manager.js with sophisticated configuration handling. Adding Zod validation and TypeScript generics adds complexity, but the existing patterns provide a solid foundation."
},
{
"taskId": 123,
"taskTitle": "Create Utility Functions and Error Handling",
"complexityScore": 2,
"recommendedSubtasks": 5,
"expansionPrompt": "Implement utilities and error handling: 1) Create ID generation module with unique formats, 2) Build TaskMasterError base class, 3) Add error sanitization for security, 4) Implement development-only logging, 5) Create specialized error subclasses. Keep implementation simple and focused.",
"reasoning": "This is a straightforward utility implementation task. The codebase already has error handling patterns, and ID generation is a simple algorithmic task. The main work is creating clean, reusable utilities."
},
{
"taskId": 124,
"taskTitle": "Implement TaskMasterCore Facade",
"complexityScore": 7,
"recommendedSubtasks": 5,
"expansionPrompt": "Create main facade class: 1) Set up TaskMasterCore structure with imports, 2) Implement lazy initialization logic, 3) Add parsePRD coordination method, 4) Implement getTasks and other facade methods, 5) Create factory function and exports. This ties together all other components into a cohesive API.",
"reasoning": "This is the most complex task as it requires understanding and integrating all other components. The facade must coordinate between configuration, providers, storage, and parsing while maintaining a clean API. It's the architectural keystone of the system."
},
{
"taskId": 125,
"taskTitle": "Create Placeholder Providers and Complete Testing",
"complexityScore": 5,
"recommendedSubtasks": 5,
"expansionPrompt": "Implement testing infrastructure: 1) Create OpenAIProvider placeholder, 2) Create GoogleProvider placeholder, 3) Build MockProvider for testing, 4) Write TaskParser unit tests, 5) Create integration tests for parse-prd flow. Follow the existing test patterns in tests/ directory.",
"reasoning": "While creating placeholder providers is simple, the testing infrastructure requires understanding Jest with ES modules, mocking patterns, and comprehensive test coverage. The existing test structure provides good examples to follow."
}
]
}

View File

@@ -1,6 +1,6 @@
{
"currentTag": "master",
"lastSwitched": "2025-07-22T13:32:03.558Z",
"lastSwitched": "2025-08-27T21:03:20.550Z",
"branchTagMapping": {
"v017-adds": "v017-adds",
"next": "next"

File diff suppressed because one or more lines are too long

15
.vscode/settings.json vendored
View File

@@ -10,5 +10,18 @@
},
"json.format.enable": true,
"json.validate.enable": true
"json.validate.enable": true,
"typescript.tsdk": "node_modules/typescript/lib",
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[json]": {
"editor.defaultFormatter": "biomejs.biome"
}
}

View File

@@ -1,5 +1,625 @@
# task-master-ai
## 0.26.0
### Minor Changes
- [#1133](https://github.com/eyaltoledano/claude-task-master/pull/1133) [`df26c65`](https://github.com/eyaltoledano/claude-task-master/commit/df26c65632000874a73504963b08f18c46283144) Thanks [@neonwatty](https://github.com/neonwatty)! - Restore Taskmaster claude-code commands and move clear commands under /remove to avoid collision with the claude-code /clear command.
- [#1163](https://github.com/eyaltoledano/claude-task-master/pull/1163) [`37af0f1`](https://github.com/eyaltoledano/claude-task-master/commit/37af0f191227a68d119b7f89a377bf932ee3ac66) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Enhanced Gemini CLI provider with codebase-aware task generation
Added automatic codebase analysis for Gemini CLI provider in parse-prd, and analyze-complexity, add-task, udpate-task, update, update-subtask commands
When using Gemini CLI as the AI provider, Task Master now instructs the AI to analyze the project structure, existing implementations, and patterns before generating tasks or subtasks
Tasks and subtasks generated by Claude Code are now informed by actual codebase analysis, resulting in more accurate and contextual outputs
- [#1165](https://github.com/eyaltoledano/claude-task-master/pull/1165) [`c4f92f6`](https://github.com/eyaltoledano/claude-task-master/commit/c4f92f6a0aee3435c56eb8d27d9aa9204284833e) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add configurable codebase analysis feature flag with multiple configuration sources
Users can now control whether codebase analysis features (Claude Code and Gemini CLI integration) are enabled through environment variables, MCP configuration, or project config files.
Priority order: .env > MCP session env > .taskmaster/config.json.
Set `TASKMASTER_ENABLE_CODEBASE_ANALYSIS=false` in `.env` to disable codebase analysis prompts and tool integration.
- [#1135](https://github.com/eyaltoledano/claude-task-master/pull/1135) [`8783708`](https://github.com/eyaltoledano/claude-task-master/commit/8783708e5e3389890a78fcf685d3da0580e73b3f) Thanks [@mm-parthy](https://github.com/mm-parthy)! - feat(move): improve cross-tag move UX and safety
- CLI: print "Next Steps" tips after cross-tag moves that used --ignore-dependencies (validate/fix guidance)
- CLI: show dedicated help block on ID collisions (destination tag already has the ID)
- Core: add structured suggestions to TASK_ALREADY_EXISTS errors
- MCP: map ID collision errors to TASK_ALREADY_EXISTS and include suggestions
- Tests: cover MCP options, error suggestions, CLI tips printing, and integration error payload suggestions
***
- [#1162](https://github.com/eyaltoledano/claude-task-master/pull/1162) [`4dad2fd`](https://github.com/eyaltoledano/claude-task-master/commit/4dad2fd613ceac56a65ae9d3c1c03092b8860ac9) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Enhanced Claude Code and Google CLI integration with automatic codebase analysis for task operations
When using Claude Code as the AI provider, task management commands now automatically analyze your codebase before generating or updating tasks. This provides more accurate, context-aware implementation details that align with your project's existing architecture and patterns.
Commands contextualised:
- add-task
- update-subtask
- update-task
- update
### Patch Changes
- [#1135](https://github.com/eyaltoledano/claude-task-master/pull/1135) [`8783708`](https://github.com/eyaltoledano/claude-task-master/commit/8783708e5e3389890a78fcf685d3da0580e73b3f) Thanks [@mm-parthy](https://github.com/mm-parthy)! - docs(move): clarify cross-tag move docs; deprecate "force"; add explicit --with-dependencies/--ignore-dependencies examples
## 0.26.0-rc.1
### Minor Changes
- [#1165](https://github.com/eyaltoledano/claude-task-master/pull/1165) [`c4f92f6`](https://github.com/eyaltoledano/claude-task-master/commit/c4f92f6a0aee3435c56eb8d27d9aa9204284833e) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add configurable codebase analysis feature flag with multiple configuration sources
Users can now control whether codebase analysis features (Claude Code and Gemini CLI integration) are enabled through environment variables, MCP configuration, or project config files.
Priority order: .env > MCP session env > .taskmaster/config.json.
Set `TASKMASTER_ENABLE_CODEBASE_ANALYSIS=false` in `.env` to disable codebase analysis prompts and tool integration.
## 0.26.0-rc.0
### Minor Changes
- [#1163](https://github.com/eyaltoledano/claude-task-master/pull/1163) [`37af0f1`](https://github.com/eyaltoledano/claude-task-master/commit/37af0f191227a68d119b7f89a377bf932ee3ac66) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Enhanced Gemini CLI provider with codebase-aware task generation
Added automatic codebase analysis for Gemini CLI provider in parse-prd, and analyze-complexity, add-task, udpate-task, update, update-subtask commands
When using Gemini CLI as the AI provider, Task Master now instructs the AI to analyze the project structure, existing implementations, and patterns before generating tasks or subtasks
Tasks and subtasks generated by Claude Code are now informed by actual codebase analysis, resulting in more accurate and contextual outputs
- [#1135](https://github.com/eyaltoledano/claude-task-master/pull/1135) [`8783708`](https://github.com/eyaltoledano/claude-task-master/commit/8783708e5e3389890a78fcf685d3da0580e73b3f) Thanks [@mm-parthy](https://github.com/mm-parthy)! - feat(move): improve cross-tag move UX and safety
- CLI: print "Next Steps" tips after cross-tag moves that used --ignore-dependencies (validate/fix guidance)
- CLI: show dedicated help block on ID collisions (destination tag already has the ID)
- Core: add structured suggestions to TASK_ALREADY_EXISTS errors
- MCP: map ID collision errors to TASK_ALREADY_EXISTS and include suggestions
- Tests: cover MCP options, error suggestions, CLI tips printing, and integration error payload suggestions
***
- [#1162](https://github.com/eyaltoledano/claude-task-master/pull/1162) [`4dad2fd`](https://github.com/eyaltoledano/claude-task-master/commit/4dad2fd613ceac56a65ae9d3c1c03092b8860ac9) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Enhanced Claude Code and Google CLI integration with automatic codebase analysis for task operations
When using Claude Code as the AI provider, task management commands now automatically analyze your codebase before generating or updating tasks. This provides more accurate, context-aware implementation details that align with your project's existing architecture and patterns.
Commands contextualised:
- add-task
- update-subtask
- update-task
- update
### Patch Changes
- [#1135](https://github.com/eyaltoledano/claude-task-master/pull/1135) [`8783708`](https://github.com/eyaltoledano/claude-task-master/commit/8783708e5e3389890a78fcf685d3da0580e73b3f) Thanks [@mm-parthy](https://github.com/mm-parthy)! - docs(move): clarify cross-tag move docs; deprecate "force"; add explicit --with-dependencies/--ignore-dependencies examples
## 0.25.1
### Patch Changes
- [#1152](https://github.com/eyaltoledano/claude-task-master/pull/1152) [`8933557`](https://github.com/eyaltoledano/claude-task-master/commit/89335578ffffc65504b2055c0c85aa7521e5e79b) Thanks [@ben-vargas](https://github.com/ben-vargas)! - fix(claude-code): prevent crash/hang when the optional `@anthropic-ai/claude-code` SDK is missing by guarding `AbortError instanceof` checks and adding explicit SDK presence checks in `doGenerate`/`doStream`. Also bump the optional dependency to `^1.0.88` for improved export consistency.
Related to JSON truncation handling in #920; this change addresses a separate error-path crash reported in #1142.
- [#1151](https://github.com/eyaltoledano/claude-task-master/pull/1151) [`db720a9`](https://github.com/eyaltoledano/claude-task-master/commit/db720a954d390bb44838cd021b8813dde8f3d8de) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Temporarily disable streaming for improved model compatibility - will be re-enabled in upcoming release
## 0.25.0
### Minor Changes
- [#1088](https://github.com/eyaltoledano/claude-task-master/pull/1088) [`04e11b5`](https://github.com/eyaltoledano/claude-task-master/commit/04e11b5e828597c0ba5b82ca7d5fb6f933e4f1e8) Thanks [@mm-parthy](https://github.com/mm-parthy)! - Add cross-tag task movement functionality for organizing tasks across different contexts.
This feature enables moving tasks between different tags (contexts) in your project, making it easier to organize work across different branches, environments, or project phases.
## CLI Usage Examples
Move a single task from one tag to another:
```bash
# Move task 5 from backlog tag to in-progress tag
task-master move --from=5 --from-tag=backlog --to-tag=feature-1
# Move task with its dependencies
task-master move --from=5 --from-tag=backlog --to-tag=feature-2 --with-dependencies
# Move task without checking dependencies
task-master move --from=5 --from-tag=backlog --to-tag=bug-3 --ignore-dependencies
```
Move multiple tasks at once:
```bash
# Move multiple tasks between tags
task-master move --from=5,6,7 --from-tag=backlog --to-tag=bug-4 --with-dependencies
```
- [#1040](https://github.com/eyaltoledano/claude-task-master/pull/1040) [`fc47714`](https://github.com/eyaltoledano/claude-task-master/commit/fc477143400fd11d953727bf1b4277af5ad308d1) Thanks [@DomVidja](https://github.com/DomVidja)! - "Add Kilo Code profile integration with custom modes and MCP configuration"
- [#1054](https://github.com/eyaltoledano/claude-task-master/pull/1054) [`782728f`](https://github.com/eyaltoledano/claude-task-master/commit/782728ff95aa2e3b766d48273b57f6c6753e8573) Thanks [@martincik](https://github.com/martincik)! - Add compact mode --compact / -c flag to the `tm list` CLI command
- outputs tasks in a minimal, git-style one-line format. This reduces verbose output from ~30+ lines of dashboards and tables to just 1 line per task, making it much easier to quickly scan available tasks.
- Git-style format: ID STATUS TITLE (PRIORITY) → DEPS
- Color-coded status, priority, and dependencies
- Smart title truncation and dependency abbreviation
- Subtask support with indentation
- Full backward compatibility with existing list options
- [#1048](https://github.com/eyaltoledano/claude-task-master/pull/1048) [`e3ed4d7`](https://github.com/eyaltoledano/claude-task-master/commit/e3ed4d7c14b56894d7da675eb2b757423bea8f9d) Thanks [@joedanz](https://github.com/joedanz)! - Add CLI & MCP progress tracking for parse-prd command.
- [#1124](https://github.com/eyaltoledano/claude-task-master/pull/1124) [`95640dc`](https://github.com/eyaltoledano/claude-task-master/commit/95640dcde87ce7879858c0a951399fb49f3b6397) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add support for ollama `gpt-oss:20b` and `gpt-oss:120b`
- [#1123](https://github.com/eyaltoledano/claude-task-master/pull/1123) [`311b243`](https://github.com/eyaltoledano/claude-task-master/commit/311b2433e23c771c8d3a4d3f5ac577302b8321e5) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Remove `clear` Taskmaster claude code commands since they were too close to the claude-code clear command
### Patch Changes
- [#1131](https://github.com/eyaltoledano/claude-task-master/pull/1131) [`3dee60d`](https://github.com/eyaltoledano/claude-task-master/commit/3dee60dc3d566e3cff650accb30f994b8bb3a15e) Thanks [@joedanz](https://github.com/joedanz)! - Update Cursor one-click install link to new URL format
- [#1088](https://github.com/eyaltoledano/claude-task-master/pull/1088) [`04e11b5`](https://github.com/eyaltoledano/claude-task-master/commit/04e11b5e828597c0ba5b82ca7d5fb6f933e4f1e8) Thanks [@mm-parthy](https://github.com/mm-parthy)! - Fix `add-tag --from-branch` command error where `projectRoot` was not properly referenced
The command was failing with "projectRoot is not defined" error because the code was directly referencing `projectRoot` instead of `context.projectRoot` in the git repository checks. This fix corrects the variable references to use the proper context object.
## 0.25.0-rc.0
### Minor Changes
- [#1088](https://github.com/eyaltoledano/claude-task-master/pull/1088) [`04e11b5`](https://github.com/eyaltoledano/claude-task-master/commit/04e11b5e828597c0ba5b82ca7d5fb6f933e4f1e8) Thanks [@mm-parthy](https://github.com/mm-parthy)! - Add cross-tag task movement functionality for organizing tasks across different contexts.
This feature enables moving tasks between different tags (contexts) in your project, making it easier to organize work across different branches, environments, or project phases.
## CLI Usage Examples
Move a single task from one tag to another:
```bash
# Move task 5 from backlog tag to in-progress tag
task-master move --from=5 --from-tag=backlog --to-tag=feature-1
# Move task with its dependencies
task-master move --from=5 --from-tag=backlog --to-tag=feature-2 --with-dependencies
# Move task without checking dependencies
task-master move --from=5 --from-tag=backlog --to-tag=bug-3 --ignore-dependencies
```
Move multiple tasks at once:
```bash
# Move multiple tasks between tags
task-master move --from=5,6,7 --from-tag=backlog --to-tag=bug-4 --with-dependencies
```
- [#1040](https://github.com/eyaltoledano/claude-task-master/pull/1040) [`fc47714`](https://github.com/eyaltoledano/claude-task-master/commit/fc477143400fd11d953727bf1b4277af5ad308d1) Thanks [@DomVidja](https://github.com/DomVidja)! - "Add Kilo Code profile integration with custom modes and MCP configuration"
- [#1054](https://github.com/eyaltoledano/claude-task-master/pull/1054) [`782728f`](https://github.com/eyaltoledano/claude-task-master/commit/782728ff95aa2e3b766d48273b57f6c6753e8573) Thanks [@martincik](https://github.com/martincik)! - Add compact mode --compact / -c flag to the `tm list` CLI command
- outputs tasks in a minimal, git-style one-line format. This reduces verbose output from ~30+ lines of dashboards and tables to just 1 line per task, making it much easier to quickly scan available tasks.
- Git-style format: ID STATUS TITLE (PRIORITY) → DEPS
- Color-coded status, priority, and dependencies
- Smart title truncation and dependency abbreviation
- Subtask support with indentation
- Full backward compatibility with existing list options
- [#1048](https://github.com/eyaltoledano/claude-task-master/pull/1048) [`e3ed4d7`](https://github.com/eyaltoledano/claude-task-master/commit/e3ed4d7c14b56894d7da675eb2b757423bea8f9d) Thanks [@joedanz](https://github.com/joedanz)! - Add CLI & MCP progress tracking for parse-prd command.
- [#1124](https://github.com/eyaltoledano/claude-task-master/pull/1124) [`95640dc`](https://github.com/eyaltoledano/claude-task-master/commit/95640dcde87ce7879858c0a951399fb49f3b6397) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add support for ollama `gpt-oss:20b` and `gpt-oss:120b`
- [#1123](https://github.com/eyaltoledano/claude-task-master/pull/1123) [`311b243`](https://github.com/eyaltoledano/claude-task-master/commit/311b2433e23c771c8d3a4d3f5ac577302b8321e5) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Remove `clear` Taskmaster claude code commands since they were too close to the claude-code clear command
### Patch Changes
- [#1131](https://github.com/eyaltoledano/claude-task-master/pull/1131) [`3dee60d`](https://github.com/eyaltoledano/claude-task-master/commit/3dee60dc3d566e3cff650accb30f994b8bb3a15e) Thanks [@joedanz](https://github.com/joedanz)! - Update Cursor one-click install link to new URL format
- [#1088](https://github.com/eyaltoledano/claude-task-master/pull/1088) [`04e11b5`](https://github.com/eyaltoledano/claude-task-master/commit/04e11b5e828597c0ba5b82ca7d5fb6f933e4f1e8) Thanks [@mm-parthy](https://github.com/mm-parthy)! - Fix `add-tag --from-branch` command error where `projectRoot` was not properly referenced
The command was failing with "projectRoot is not defined" error because the code was directly referencing `projectRoot` instead of `context.projectRoot` in the git repository checks. This fix corrects the variable references to use the proper context object.
## 0.24.0
### Minor Changes
- [#1098](https://github.com/eyaltoledano/claude-task-master/pull/1098) [`36468f3`](https://github.com/eyaltoledano/claude-task-master/commit/36468f3c93faf4035a5c442ccbc501077f3440f1) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Enhanced Claude Code provider with codebase-aware task generation
- Added automatic codebase analysis for Claude Code provider in `parse-prd`, `expand-task`, and `analyze-complexity` commands
- When using Claude Code as the AI provider, Task Master now instructs the AI to analyze the project structure, existing implementations, and patterns before generating tasks or subtasks
- Tasks and subtasks generated by Claude Code are now informed by actual codebase analysis, resulting in more accurate and contextual outputs
- [#1105](https://github.com/eyaltoledano/claude-task-master/pull/1105) [`75c514c`](https://github.com/eyaltoledano/claude-task-master/commit/75c514cf5b2ca47f95c0ad7fa92654a4f2a6be4b) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add GPT-5 support with proper parameter handling
- Added GPT-5 model to supported models configuration with SWE score of 0.749
- [#1091](https://github.com/eyaltoledano/claude-task-master/pull/1091) [`4bb6370`](https://github.com/eyaltoledano/claude-task-master/commit/4bb63706b80c28d1b2d782ba868a725326f916c7) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add Claude Code subagent support with task-orchestrator, task-executor, and task-checker
## New Claude Code Agents
Added specialized agents for Claude Code users to enable parallel task execution, intelligent task orchestration, and quality assurance:
### task-orchestrator
Coordinates and manages the execution of Task Master tasks with intelligent dependency analysis:
- Analyzes task dependencies to identify parallelizable work
- Deploys multiple task-executor agents for concurrent execution
- Monitors task completion and updates the dependency graph
- Automatically identifies and starts newly unblocked tasks
### task-executor
Handles the actual implementation of individual tasks:
- Executes specific tasks identified by the orchestrator
- Works on concrete implementation rather than planning
- Updates task status and logs progress
- Can work in parallel with other executors on independent tasks
### task-checker
Verifies that completed tasks meet their specifications:
- Reviews tasks marked as 'review' status
- Validates implementation against requirements
- Runs tests and checks for best practices
- Ensures quality before marking tasks as 'done'
## Installation
When using the Claude profile (`task-master rules add claude`), the agents are automatically installed to `.claude/agents/` directory.
## Usage Example
```bash
# In Claude Code, after initializing a project with tasks:
# Use task-orchestrator to analyze and coordinate work
# The orchestrator will:
# 1. Check task dependencies
# 2. Identify tasks that can run in parallel
# 3. Deploy executors for available work
# 4. Monitor progress and deploy new executors as tasks complete
# Use task-executor for specific task implementation
# When the orchestrator identifies task 2.3 needs work:
# The executor will implement that specific task
```
## Benefits
- **Parallel Execution**: Multiple independent tasks can be worked on simultaneously
- **Intelligent Scheduling**: Orchestrator understands dependencies and optimizes execution order
- **Separation of Concerns**: Planning (orchestrator) is separated from execution (executor)
- **Progress Tracking**: Real-time updates as tasks are completed
- **Automatic Progression**: As tasks complete, newly unblocked tasks are automatically started
### Patch Changes
- [#1094](https://github.com/eyaltoledano/claude-task-master/pull/1094) [`4357af3`](https://github.com/eyaltoledano/claude-task-master/commit/4357af3f13859d90bca8795215e5d5f1d94abde5) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix expand task generating unrelated generic subtasks
Fixed an issue where `task-master expand` would generate generic authentication-related subtasks regardless of the parent task context when using complexity reports. The expansion now properly includes the parent task details alongside any expansion guidance.
- [#1079](https://github.com/eyaltoledano/claude-task-master/pull/1079) [`e495b2b`](https://github.com/eyaltoledano/claude-task-master/commit/e495b2b55950ee54c7d0f1817d8530e28bd79c05) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix scope-up/down prompts to include all required fields for better AI model compatibility
- Added missing `priority` field to scope adjustment prompts to prevent validation errors with Claude-code and other models
- Ensures generated JSON includes all fields required by the schema
- [#1079](https://github.com/eyaltoledano/claude-task-master/pull/1079) [`e495b2b`](https://github.com/eyaltoledano/claude-task-master/commit/e495b2b55950ee54c7d0f1817d8530e28bd79c05) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix MCP scope-up/down tools not finding tasks
- Fixed task ID parsing in MCP layer - now correctly converts string IDs to numbers
- scope_up_task and scope_down_task MCP tools now work properly
- [#1079](https://github.com/eyaltoledano/claude-task-master/pull/1079) [`e495b2b`](https://github.com/eyaltoledano/claude-task-master/commit/e495b2b55950ee54c7d0f1817d8530e28bd79c05) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Improve AI provider compatibility for JSON generation
- Fixed schema compatibility issues between Perplexity and OpenAI o3 models
- Removed nullable/default modifiers from Zod schemas for broader compatibility
- Added automatic JSON repair for malformed AI responses (handles cases like missing array values)
- Perplexity now uses JSON mode for more reliable structured output
- Post-processing handles default values separately from schema validation
## 0.24.0-rc.2
### Minor Changes
- [#1105](https://github.com/eyaltoledano/claude-task-master/pull/1105) [`75c514c`](https://github.com/eyaltoledano/claude-task-master/commit/75c514cf5b2ca47f95c0ad7fa92654a4f2a6be4b) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add GPT-5 support with proper parameter handling
- Added GPT-5 model to supported models configuration with SWE score of 0.749
## 0.24.0-rc.1
### Minor Changes
- [#1093](https://github.com/eyaltoledano/claude-task-master/pull/1093) [`36468f3`](https://github.com/eyaltoledano/claude-task-master/commit/36468f3c93faf4035a5c442ccbc501077f3440f1) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Enhanced Claude Code provider with codebase-aware task generation
- Added automatic codebase analysis for Claude Code provider in `parse-prd`, `expand-task`, and `analyze-complexity` commands
- When using Claude Code as the AI provider, Task Master now instructs the AI to analyze the project structure, existing implementations, and patterns before generating tasks or subtasks
- Tasks and subtasks generated by Claude Code are now informed by actual codebase analysis, resulting in more accurate and contextual outputs
- [#1091](https://github.com/eyaltoledano/claude-task-master/pull/1091) [`4bb6370`](https://github.com/eyaltoledano/claude-task-master/commit/4bb63706b80c28d1b2d782ba868a725326f916c7) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add Claude Code subagent support with task-orchestrator, task-executor, and task-checker
## New Claude Code Agents
Added specialized agents for Claude Code users to enable parallel task execution, intelligent task orchestration, and quality assurance:
### task-orchestrator
Coordinates and manages the execution of Task Master tasks with intelligent dependency analysis:
- Analyzes task dependencies to identify parallelizable work
- Deploys multiple task-executor agents for concurrent execution
- Monitors task completion and updates the dependency graph
- Automatically identifies and starts newly unblocked tasks
### task-executor
Handles the actual implementation of individual tasks:
- Executes specific tasks identified by the orchestrator
- Works on concrete implementation rather than planning
- Updates task status and logs progress
- Can work in parallel with other executors on independent tasks
### task-checker
Verifies that completed tasks meet their specifications:
- Reviews tasks marked as 'review' status
- Validates implementation against requirements
- Runs tests and checks for best practices
- Ensures quality before marking tasks as 'done'
## Installation
When using the Claude profile (`task-master rules add claude`), the agents are automatically installed to `.claude/agents/` directory.
## Usage Example
```bash
# In Claude Code, after initializing a project with tasks:
# Use task-orchestrator to analyze and coordinate work
# The orchestrator will:
# 1. Check task dependencies
# 2. Identify tasks that can run in parallel
# 3. Deploy executors for available work
# 4. Monitor progress and deploy new executors as tasks complete
# Use task-executor for specific task implementation
# When the orchestrator identifies task 2.3 needs work:
# The executor will implement that specific task
```
## Benefits
- **Parallel Execution**: Multiple independent tasks can be worked on simultaneously
- **Intelligent Scheduling**: Orchestrator understands dependencies and optimizes execution order
- **Separation of Concerns**: Planning (orchestrator) is separated from execution (executor)
- **Progress Tracking**: Real-time updates as tasks are completed
- **Automatic Progression**: As tasks complete, newly unblocked tasks are automatically started
### Patch Changes
- [#1094](https://github.com/eyaltoledano/claude-task-master/pull/1094) [`4357af3`](https://github.com/eyaltoledano/claude-task-master/commit/4357af3f13859d90bca8795215e5d5f1d94abde5) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix expand task generating unrelated generic subtasks
Fixed an issue where `task-master expand` would generate generic authentication-related subtasks regardless of the parent task context when using complexity reports. The expansion now properly includes the parent task details alongside any expansion guidance.
## 0.23.1-rc.0
### Patch Changes
- [#1079](https://github.com/eyaltoledano/claude-task-master/pull/1079) [`e495b2b`](https://github.com/eyaltoledano/claude-task-master/commit/e495b2b55950ee54c7d0f1817d8530e28bd79c05) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix scope-up/down prompts to include all required fields for better AI model compatibility
- Added missing `priority` field to scope adjustment prompts to prevent validation errors with Claude-code and other models
- Ensures generated JSON includes all fields required by the schema
- [#1079](https://github.com/eyaltoledano/claude-task-master/pull/1079) [`e495b2b`](https://github.com/eyaltoledano/claude-task-master/commit/e495b2b55950ee54c7d0f1817d8530e28bd79c05) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix MCP scope-up/down tools not finding tasks
- Fixed task ID parsing in MCP layer - now correctly converts string IDs to numbers
- scope_up_task and scope_down_task MCP tools now work properly
- [#1079](https://github.com/eyaltoledano/claude-task-master/pull/1079) [`e495b2b`](https://github.com/eyaltoledano/claude-task-master/commit/e495b2b55950ee54c7d0f1817d8530e28bd79c05) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Improve AI provider compatibility for JSON generation
- Fixed schema compatibility issues between Perplexity and OpenAI o3 models
- Removed nullable/default modifiers from Zod schemas for broader compatibility
- Added automatic JSON repair for malformed AI responses (handles cases like missing array values)
- Perplexity now uses JSON mode for more reliable structured output
- Post-processing handles default values separately from schema validation
## 0.23.0
### Minor Changes
- [#1064](https://github.com/eyaltoledano/claude-task-master/pull/1064) [`53903f1`](https://github.com/eyaltoledano/claude-task-master/commit/53903f1e8eee23ac512eb13a6d81d8cbcfe658cb) Thanks [@eyaltoledano](https://github.com/eyaltoledano)! - Add new `scope-up` and `scope-down` commands for dynamic task complexity adjustment
This release introduces two powerful new commands that allow you to dynamically adjust the complexity of your tasks and subtasks without recreating them from scratch.
**New CLI Commands:**
- `task-master scope-up` - Increase task complexity (add more detail, requirements, or implementation steps)
- `task-master scope-down` - Decrease task complexity (simplify, remove unnecessary details, or streamline)
**Key Features:**
- **Multiple tasks**: Support comma-separated IDs to adjust multiple tasks at once (`--id=5,7,12`)
- **Strength levels**: Choose adjustment intensity with `--strength=light|regular|heavy` (defaults to regular)
- **Custom prompts**: Use `--prompt` flag to specify exactly how you want tasks adjusted
- **MCP integration**: Available as `scope_up_task` and `scope_down_task` tools in Cursor and other MCP environments
- **Smart context**: AI considers your project context and task dependencies when making adjustments
**Usage Examples:**
```bash
# Make a task more detailed
task-master scope-up --id=5
# Simplify multiple tasks with light touch
task-master scope-down --id=10,11,12 --strength=light
# Custom adjustment with specific instructions
task-master scope-up --id=7 --prompt="Add more error handling and edge cases"
```
**Why use this?**
- **Iterative refinement**: Adjust task complexity as your understanding evolves
- **Project phase adaptation**: Scale tasks up for implementation, down for planning
- **Team coordination**: Adjust complexity based on team member experience levels
- **Milestone alignment**: Fine-tune tasks to match project phase requirements
Perfect for agile workflows where task requirements change as you learn more about the problem space.
### Patch Changes
- [#1063](https://github.com/eyaltoledano/claude-task-master/pull/1063) [`2ae6e7e`](https://github.com/eyaltoledano/claude-task-master/commit/2ae6e7e6be3605c3c4d353f34666e54750dba973) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix for tasks not found when using string IDs
- [#1049](https://github.com/eyaltoledano/claude-task-master/pull/1049) [`45a14c3`](https://github.com/eyaltoledano/claude-task-master/commit/45a14c323d21071c15106335e89ad1f4a20976ab) Thanks [@ben-vargas](https://github.com/ben-vargas)! - Fix tag-specific complexity report detection in expand command
The expand command now correctly finds and uses tag-specific complexity reports (e.g., `task-complexity-report_feature-xyz.json`) when operating in a tag context. Previously, it would always look for the generic `task-complexity-report.json` file due to a default value in the CLI option definition.
## 0.23.0-rc.2
### Minor Changes
- [#1064](https://github.com/eyaltoledano/claude-task-master/pull/1064) [`53903f1`](https://github.com/eyaltoledano/claude-task-master/commit/53903f1e8eee23ac512eb13a6d81d8cbcfe658cb) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add new `scope-up` and `scope-down` commands for dynamic task complexity adjustment
This release introduces two powerful new commands that allow you to dynamically adjust the complexity of your tasks and subtasks without recreating them from scratch.
**New CLI Commands:**
- `task-master scope-up` - Increase task complexity (add more detail, requirements, or implementation steps)
- `task-master scope-down` - Decrease task complexity (simplify, remove unnecessary details, or streamline)
**Key Features:**
- **Multiple tasks**: Support comma-separated IDs to adjust multiple tasks at once (`--id=5,7,12`)
- **Strength levels**: Choose adjustment intensity with `--strength=light|regular|heavy` (defaults to regular)
- **Custom prompts**: Use `--prompt` flag to specify exactly how you want tasks adjusted
- **MCP integration**: Available as `scope_up_task` and `scope_down_task` tools in Cursor and other MCP environments
- **Smart context**: AI considers your project context and task dependencies when making adjustments
**Usage Examples:**
```bash
# Make a task more detailed
task-master scope-up --id=5
# Simplify multiple tasks with light touch
task-master scope-down --id=10,11,12 --strength=light
# Custom adjustment with specific instructions
task-master scope-up --id=7 --prompt="Add more error handling and edge cases"
```
**Why use this?**
- **Iterative refinement**: Adjust task complexity as your understanding evolves
- **Project phase adaptation**: Scale tasks up for implementation, down for planning
- **Team coordination**: Adjust complexity based on team member experience levels
- **Milestone alignment**: Fine-tune tasks to match project phase requirements
Perfect for agile workflows where task requirements change as you learn more about the problem space.
## 0.22.1-rc.1
### Patch Changes
- [#1069](https://github.com/eyaltoledano/claude-task-master/pull/1069) [`72ca68e`](https://github.com/eyaltoledano/claude-task-master/commit/72ca68edeb870ff7a3b0d2d632e09dae921dc16a) Thanks [@eyaltoledano](https://github.com/eyaltoledano)! - Add new `scope-up` and `scope-down` commands for dynamic task complexity adjustment
This release introduces two powerful new commands that allow you to dynamically adjust the complexity of your tasks and subtasks without recreating them from scratch.
**New CLI Commands:**
- `task-master scope-up` - Increase task complexity (add more detail, requirements, or implementation steps)
- `task-master scope-down` - Decrease task complexity (simplify, remove unnecessary details, or streamline)
**Key Features:**
- **Multiple tasks**: Support comma-separated IDs to adjust multiple tasks at once (`--id=5,7,12`)
- **Strength levels**: Choose adjustment intensity with `--strength=light|regular|heavy` (defaults to regular)
- **Custom prompts**: Use `--prompt` flag to specify exactly how you want tasks adjusted
- **MCP integration**: Available as `scope_up_task` and `scope_down_task` tools in Cursor and other MCP environments
- **Smart context**: AI considers your project context and task dependencies when making adjustments
**Usage Examples:**
```bash
# Make a task more detailed
task-master scope-up --id=5
# Simplify multiple tasks with light touch
task-master scope-down --id=10,11,12 --strength=light
# Custom adjustment with specific instructions
task-master scope-up --id=7 --prompt="Add more error handling and edge cases"
```
**Why use this?**
- **Iterative refinement**: Adjust task complexity as your understanding evolves
- **Project phase adaptation**: Scale tasks up for implementation, down for planning
- **Team coordination**: Adjust complexity based on team member experience levels
- **Milestone alignment**: Fine-tune tasks to match project phase requirements
Perfect for agile workflows where task requirements change as you learn more about the problem space.
## 0.22.1-rc.0
### Patch Changes
- [#1063](https://github.com/eyaltoledano/claude-task-master/pull/1063) [`2ae6e7e`](https://github.com/eyaltoledano/claude-task-master/commit/2ae6e7e6be3605c3c4d353f34666e54750dba973) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix for tasks not found when using string IDs
- [#1049](https://github.com/eyaltoledano/claude-task-master/pull/1049) [`45a14c3`](https://github.com/eyaltoledano/claude-task-master/commit/45a14c323d21071c15106335e89ad1f4a20976ab) Thanks [@ben-vargas](https://github.com/ben-vargas)! - Fix tag-specific complexity report detection in expand command
The expand command now correctly finds and uses tag-specific complexity reports (e.g., `task-complexity-report_feature-xyz.json`) when operating in a tag context. Previously, it would always look for the generic `task-complexity-report.json` file due to a default value in the CLI option definition.
## 0.22.0
### Minor Changes
- [#1043](https://github.com/eyaltoledano/claude-task-master/pull/1043) [`dc44ed9`](https://github.com/eyaltoledano/claude-task-master/commit/dc44ed9de8a57aca5d39d3a87565568bd0a82068) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Prompt to generate a complexity report when it is missing
- [#1032](https://github.com/eyaltoledano/claude-task-master/pull/1032) [`4423119`](https://github.com/eyaltoledano/claude-task-master/commit/4423119a5ec53958c9dffa8bf564da8be7a2827d) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add comprehensive Kiro IDE integration with autonomous task management hooks
- **Kiro Profile**: Added full support for Kiro IDE with automatic installation of 7 Taskmaster agent hooks
- **Hook-Driven Workflow**: Introduced natural language automation hooks that eliminate manual task status updates
- **Automatic Hook Installation**: Hooks are now automatically copied to `.kiro/hooks/` when running `task-master rules add kiro`
- **Language-Agnostic Support**: All hooks support multiple programming languages (JS, Python, Go, Rust, Java, etc.)
- **Frontmatter Transformation**: Kiro rules use simplified `inclusion: always` format instead of Cursor's complex frontmatter
- **Special Rule**: Added `taskmaster_hooks_workflow.md` that guides AI assistants to prefer hook-driven completion
Key hooks included:
- Task Dependency Auto-Progression: Automatically starts tasks when dependencies complete
- Code Change Task Tracker: Updates task progress as you save files
- Test Success Task Completer: Marks tasks done when tests pass
- Daily Standup Assistant: Provides personalized task status summaries
- PR Readiness Checker: Validates task completion before creating pull requests
- Complexity Analyzer: Auto-expands complex tasks into manageable subtasks
- Git Commit Task Linker: Links commits to tasks for better traceability
This creates a truly autonomous development workflow where task management happens naturally as you code!
### Patch Changes
- [#1033](https://github.com/eyaltoledano/claude-task-master/pull/1033) [`7b90568`](https://github.com/eyaltoledano/claude-task-master/commit/7b9056832653464f934c91c22997077065d738c4) Thanks [@ben-vargas](https://github.com/ben-vargas)! - Fix compatibility with @google/gemini-cli-core v0.1.12+ by updating ai-sdk-provider-gemini-cli to v0.1.1.
- [#1038](https://github.com/eyaltoledano/claude-task-master/pull/1038) [`77cc5e4`](https://github.com/eyaltoledano/claude-task-master/commit/77cc5e4537397642f2664f61940a101433ee6fb4) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix 'expand --all' and 'show' commands to correctly handle tag contexts for complexity reports and task display.
- [#1025](https://github.com/eyaltoledano/claude-task-master/pull/1025) [`8781794`](https://github.com/eyaltoledano/claude-task-master/commit/8781794c56d454697fc92c88a3925982d6b81205) Thanks [@joedanz](https://github.com/joedanz)! - Clean up remaining automatic task file generation calls
- [#1035](https://github.com/eyaltoledano/claude-task-master/pull/1035) [`fb7d588`](https://github.com/eyaltoledano/claude-task-master/commit/fb7d588137e8c53b0d0f54bd1dd8d387648583ee) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix max_tokens limits for OpenRouter and Groq models
- Add special handling in config-manager.js for custom OpenRouter models to use a conservative default of 32,768 max_tokens
- Update qwen/qwen-turbo model max_tokens from 1,000,000 to 32,768 to match OpenRouter's actual limits
- Fix moonshotai/kimi-k2-instruct max_tokens to 16,384 to match Groq's actual limit (fixes #1028)
- This prevents "maximum context length exceeded" errors when using OpenRouter models not in our supported models list
- [#1027](https://github.com/eyaltoledano/claude-task-master/pull/1027) [`6ae66b2`](https://github.com/eyaltoledano/claude-task-master/commit/6ae66b2afbfe911340fa25e0236c3db83deaa7eb) Thanks [@andreswebs](https://github.com/andreswebs)! - Fix VSCode profile generation to use correct rule file names (using `.instructions.md` extension instead of `.md`) and front-matter properties (removing the unsupported `alwaysApply` property from instructions files' front-matter).
## 0.22.0-rc.1
### Minor Changes
- [#1043](https://github.com/eyaltoledano/claude-task-master/pull/1043) [`dc44ed9`](https://github.com/eyaltoledano/claude-task-master/commit/dc44ed9de8a57aca5d39d3a87565568bd0a82068) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Prompt to generate a complexity report when it is missing
## 0.22.0-rc.0
### Minor Changes
- [#1032](https://github.com/eyaltoledano/claude-task-master/pull/1032) [`4423119`](https://github.com/eyaltoledano/claude-task-master/commit/4423119a5ec53958c9dffa8bf564da8be7a2827d) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add comprehensive Kiro IDE integration with autonomous task management hooks
- **Kiro Profile**: Added full support for Kiro IDE with automatic installation of 7 Taskmaster agent hooks
- **Hook-Driven Workflow**: Introduced natural language automation hooks that eliminate manual task status updates
- **Automatic Hook Installation**: Hooks are now automatically copied to `.kiro/hooks/` when running `task-master rules add kiro`
- **Language-Agnostic Support**: All hooks support multiple programming languages (JS, Python, Go, Rust, Java, etc.)
- **Frontmatter Transformation**: Kiro rules use simplified `inclusion: always` format instead of Cursor's complex frontmatter
- **Special Rule**: Added `taskmaster_hooks_workflow.md` that guides AI assistants to prefer hook-driven completion
Key hooks included:
- Task Dependency Auto-Progression: Automatically starts tasks when dependencies complete
- Code Change Task Tracker: Updates task progress as you save files
- Test Success Task Completer: Marks tasks done when tests pass
- Daily Standup Assistant: Provides personalized task status summaries
- PR Readiness Checker: Validates task completion before creating pull requests
- Complexity Analyzer: Auto-expands complex tasks into manageable subtasks
- Git Commit Task Linker: Links commits to tasks for better traceability
This creates a truly autonomous development workflow where task management happens naturally as you code!
### Patch Changes
- [#1033](https://github.com/eyaltoledano/claude-task-master/pull/1033) [`7b90568`](https://github.com/eyaltoledano/claude-task-master/commit/7b9056832653464f934c91c22997077065d738c4) Thanks [@ben-vargas](https://github.com/ben-vargas)! - Fix compatibility with @google/gemini-cli-core v0.1.12+ by updating ai-sdk-provider-gemini-cli to v0.1.1.
- [#1038](https://github.com/eyaltoledano/claude-task-master/pull/1038) [`77cc5e4`](https://github.com/eyaltoledano/claude-task-master/commit/77cc5e4537397642f2664f61940a101433ee6fb4) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix 'expand --all' and 'show' commands to correctly handle tag contexts for complexity reports and task display.
- [#1025](https://github.com/eyaltoledano/claude-task-master/pull/1025) [`8781794`](https://github.com/eyaltoledano/claude-task-master/commit/8781794c56d454697fc92c88a3925982d6b81205) Thanks [@joedanz](https://github.com/joedanz)! - Clean up remaining automatic task file generation calls
- [#1035](https://github.com/eyaltoledano/claude-task-master/pull/1035) [`fb7d588`](https://github.com/eyaltoledano/claude-task-master/commit/fb7d588137e8c53b0d0f54bd1dd8d387648583ee) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix max_tokens limits for OpenRouter and Groq models
- Add special handling in config-manager.js for custom OpenRouter models to use a conservative default of 32,768 max_tokens
- Update qwen/qwen-turbo model max_tokens from 1,000,000 to 32,768 to match OpenRouter's actual limits
- Fix moonshotai/kimi-k2-instruct max_tokens to 16,384 to match Groq's actual limit (fixes #1028)
- This prevents "maximum context length exceeded" errors when using OpenRouter models not in our supported models list
- [#1027](https://github.com/eyaltoledano/claude-task-master/pull/1027) [`6ae66b2`](https://github.com/eyaltoledano/claude-task-master/commit/6ae66b2afbfe911340fa25e0236c3db83deaa7eb) Thanks [@andreswebs](https://github.com/andreswebs)! - Fix VSCode profile generation to use correct rule file names (using `.instructions.md` extension instead of `.md`) and front-matter properties (removing the unsupported `alwaysApply` property from instructions files' front-matter).
## 0.21.0
### Minor Changes

View File

@@ -3,3 +3,7 @@
## Task Master AI Instructions
**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**
@./.taskmaster/CLAUDE.md
## Changeset Guidelines
- When creating changesets, remember that it's user-facing, meaning we don't have to get into the specifics of the code, but rather mention what the end-user is getting or fixing from this changeset.

View File

@@ -1,14 +1,39 @@
# Task Master [![GitHub stars](https://img.shields.io/github/stars/eyaltoledano/claude-task-master?style=social)](https://github.com/eyaltoledano/claude-task-master/stargazers)
<a name="readme-top"></a>
[![CI](https://github.com/eyaltoledano/claude-task-master/actions/workflows/ci.yml/badge.svg)](https://github.com/eyaltoledano/claude-task-master/actions/workflows/ci.yml) [![npm version](https://badge.fury.io/js/task-master-ai.svg)](https://badge.fury.io/js/task-master-ai) [![Discord](https://dcbadge.limes.pink/api/server/https://discord.gg/taskmasterai?style=flat)](https://discord.gg/taskmasterai) [![License: MIT with Commons Clause](https://img.shields.io/badge/license-MIT%20with%20Commons%20Clause-blue.svg)](LICENSE)
<div align='center'>
<a href="https://trendshift.io/repositories/13971" target="_blank"><img src="https://trendshift.io/api/badge/repositories/13971" alt="eyaltoledano%2Fclaude-task-master | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>
[![NPM Downloads](https://img.shields.io/npm/d18m/task-master-ai?style=flat)](https://www.npmjs.com/package/task-master-ai) [![NPM Downloads](https://img.shields.io/npm/dm/task-master-ai?style=flat)](https://www.npmjs.com/package/task-master-ai) [![NPM Downloads](https://img.shields.io/npm/dw/task-master-ai?style=flat)](https://www.npmjs.com/package/task-master-ai)
<p align="center">
<a href="https://task-master.dev"><img src="./images/logo.png?raw=true" alt="Taskmaster logo"></a>
</p>
## By [@eyaltoledano](https://x.com/eyaltoledano), [@RalphEcom](https://x.com/RalphEcom) & [@jasonzhou1993](https://x.com/jasonzhou1993)
<p align="center">
<b>Taskmaster</b>: A task management system for AI-driven development, designed to work seamlessly with any AI chat.
</p>
<p align="center">
<a href="https://discord.gg/taskmasterai" target="_blank"><img src="https://dcbadge.limes.pink/api/server/https://discord.gg/taskmasterai?style=flat" alt="Discord"></a> |
<a href="https://docs.task-master.dev" target="_blank">Docs</a>
</p>
<p align="center">
<a href="https://github.com/eyaltoledano/claude-task-master/actions/workflows/ci.yml"><img src="https://github.com/eyaltoledano/claude-task-master/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://github.com/eyaltoledano/claude-task-master/stargazers"><img src="https://img.shields.io/github/stars/eyaltoledano/claude-task-master?style=social" alt="GitHub stars"></a>
<a href="https://badge.fury.io/js/task-master-ai"><img src="https://badge.fury.io/js/task-master-ai.svg" alt="npm version"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT%20with%20Commons%20Clause-blue.svg" alt="License"></a>
</p>
<p align="center">
<a href="https://www.npmjs.com/package/task-master-ai"><img src="https://img.shields.io/npm/d18m/task-master-ai?style=flat" alt="NPM Downloads"></a>
<a href="https://www.npmjs.com/package/task-master-ai"><img src="https://img.shields.io/npm/dm/task-master-ai?style=flat" alt="NPM Downloads"></a>
<a href="https://www.npmjs.com/package/task-master-ai"><img src="https://img.shields.io/npm/dw/task-master-ai?style=flat" alt="NPM Downloads"></a>
</p>
## By [@eyaltoledano](https://x.com/eyaltoledano) & [@RalphEcom](https://x.com/RalphEcom)
[![Twitter Follow](https://img.shields.io/twitter/follow/eyaltoledano)](https://x.com/eyaltoledano)
[![Twitter Follow](https://img.shields.io/twitter/follow/RalphEcom)](https://x.com/RalphEcom)
[![Twitter Follow](https://img.shields.io/twitter/follow/jasonzhou1993)](https://x.com/jasonzhou1993)
A task management system for AI-driven development with Claude, designed to work seamlessly with Cursor AI.
@@ -31,7 +56,7 @@ The following documentation is also available in the `docs` directory:
#### Quick Install for Cursor 1.0+ (One-Click)
[![Add task-master-ai MCP server to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/install-mcp?name=task-master-ai&config=eyJjb21tYW5kIjoibnB4IC15IC0tcGFja2FnZT10YXNrLW1hc3Rlci1haSB0YXNrLW1hc3Rlci1haSIsImVudiI6eyJBTlRIUk9QSUNfQVBJX0tFWSI6IllPVVJfQU5USFJPUElDX0FQSV9LRVlfSEVSRSIsIlBFUlBMRVhJVFlfQVBJX0tFWSI6IllPVVJfUEVSUExFWElUWV9BUElfS0VZX0hFUkUiLCJPUEVOQUlfQVBJX0tFWSI6IllPVVJfT1BFTkFJX0tFWV9IRVJFIiwiR09PR0xFX0FQSV9LRVkiOiJZT1VSX0dPT0dMRV9LRVlfSEVSRSIsIk1JU1RSQUxfQVBJX0tFWSI6IllPVVJfTUlTVFJBTF9LRVlfSEVSRSIsIkdST1FfQVBJX0tFWSI6IllPVVJfR1JPUV9LRVlfSEVSRSIsIk9QRU5ST1VURVJfQVBJX0tFWSI6IllPVVJfT1BFTlJPVVRFUl9LRVlfSEVSRSIsIlhBSV9BUElfS0VZIjoiWU9VUl9YQUlfS0VZX0hFUkUiLCJBWlVSRV9PUEVOQUlfQVBJX0tFWSI6IllPVVJfQVpVUkVfS0VZX0hFUkUiLCJPTExBTUFfQVBJX0tFWSI6IllPVVJfT0xMQU1BX0FQSV9LRVlfSEVSRSJ9fQ%3D%3D)
[![Add task-master-ai MCP server to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=task-master-ai&config=eyJjb21tYW5kIjoibnB4IC15IC0tcGFja2FnZT10YXNrLW1hc3Rlci1haSB0YXNrLW1hc3Rlci1haSIsImVudiI6eyJBTlRIUk9QSUNfQVBJX0tFWSI6IllPVVJfQU5USFJPUElDX0FQSV9LRVlfSEVSRSIsIlBFUlBMRVhJVFlfQVBJX0tFWSI6IllPVVJfUEVSUExFWElUWV9BUElfS0VZX0hFUkUiLCJPUEVOQUlfQVBJX0tFWSI6IllPVVJfT1BFTkFJX0tFWV9IRVJFIiwiR09PR0xFX0FQSV9LRVkiOiJZT1VSX0dPT0dMRV9LRVlfSEVSRSIsIk1JU1RSQUxfQVBJX0tFWSI6IllPVVJfTUlTVFJBTF9LRVlfSEVSRSIsIkdST1FfQVBJX0tFWSI6IllPVVJfR1JPUV9LRVlfSEVSRSIsIk9QRU5ST1VURVJfQVBJX0tFWSI6IllPVVJfT1BFTlJPVVRFUl9LRVlfSEVSRSIsIlhBSV9BUElfS0VZIjoiWU9VUl9YQUlfS0VZX0hFUkUiLCJBWlVSRV9PUEVOQUlfQVBJX0tFWSI6IllPVVJfQVpVUkVfS0VZX0hFUkUiLCJPTExBTUFfQVBJX0tFWSI6IllPVVJfT0xMQU1BX0FQSV9LRVlfSEVSRSJ9fQ%3D%3D)
> **Note:** After clicking the link, you'll still need to add your API keys to the configuration. The link installs the MCP server with placeholder keys that you'll need to replace with your actual API keys.
@@ -230,6 +255,11 @@ task-master show 1,3,5
# Research fresh information with project context
task-master research "What are the latest best practices for JWT authentication?"
# Move tasks between tags (cross-tag movement)
task-master move --from=5 --from-tag=backlog --to-tag=in-progress
task-master move --from=5,6,7 --from-tag=backlog --to-tag=done --with-dependencies
task-master move --from=5 --from-tag=backlog --to-tag=in-progress --ignore-dependencies
# Generate task files
task-master generate

52
apps/cli/package.json Normal file
View File

@@ -0,0 +1,52 @@
{
"name": "@tm/cli",
"version": "1.0.0",
"description": "Task Master CLI - Command line interface for task management",
"type": "module",
"main": "./dist/index.js",
"types": "./src/index.ts",
"exports": {
".": "./src/index.ts"
},
"files": ["dist", "README.md"],
"scripts": {
"typecheck": "tsc --noEmit",
"lint": "biome check src",
"format": "biome format --write src",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:unit": "vitest run -t unit",
"test:integration": "vitest run -t integration",
"test:e2e": "vitest run --dir tests/e2e",
"test:ci": "vitest run --coverage --reporter=dot"
},
"dependencies": {
"@tm/core": "*",
"boxen": "^7.1.1",
"chalk": "5.6.2",
"cli-table3": "^0.6.5",
"commander": "^12.1.0",
"inquirer": "^9.2.10",
"ora": "^8.1.0"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@types/inquirer": "^9.0.3",
"@types/node": "^22.10.5",
"tsx": "^4.20.4",
"typescript": "^5.7.3",
"vitest": "^2.1.8"
},
"engines": {
"node": ">=18.0.0"
},
"keywords": ["task-master", "cli", "task-management", "productivity"],
"author": "",
"license": "MIT",
"typesVersions": {
"*": {
"*": ["src/*"]
}
}
}

View File

@@ -0,0 +1,514 @@
/**
* @fileoverview Auth command using Commander's native class pattern
* Extends Commander.Command for better integration with the framework
*/
import { Command } from 'commander';
import chalk from 'chalk';
import inquirer from 'inquirer';
import ora, { type Ora } from 'ora';
import open from 'open';
import {
AuthManager,
AuthenticationError,
type AuthCredentials
} from '@tm/core/auth';
import * as ui from '../utils/ui.js';
/**
* Result type from auth command
*/
export interface AuthResult {
success: boolean;
action: 'login' | 'logout' | 'status' | 'refresh';
credentials?: AuthCredentials;
message?: string;
}
/**
* AuthCommand extending Commander's Command class
* This is a thin presentation layer over @tm/core's AuthManager
*/
export class AuthCommand extends Command {
private authManager: AuthManager;
private lastResult?: AuthResult;
constructor(name?: string) {
super(name || 'auth');
// Initialize auth manager
this.authManager = AuthManager.getInstance();
// Configure the command with subcommands
this.description('Manage authentication with tryhamster.com');
// Add subcommands
this.addLoginCommand();
this.addLogoutCommand();
this.addStatusCommand();
this.addRefreshCommand();
// Default action shows help
this.action(() => {
this.help();
});
}
/**
* Add login subcommand
*/
private addLoginCommand(): void {
this.command('login')
.description('Authenticate with tryhamster.com')
.action(async () => {
await this.executeLogin();
});
}
/**
* Add logout subcommand
*/
private addLogoutCommand(): void {
this.command('logout')
.description('Logout and clear credentials')
.action(async () => {
await this.executeLogout();
});
}
/**
* Add status subcommand
*/
private addStatusCommand(): void {
this.command('status')
.description('Display authentication status')
.action(async () => {
await this.executeStatus();
});
}
/**
* Add refresh subcommand
*/
private addRefreshCommand(): void {
this.command('refresh')
.description('Refresh authentication token')
.action(async () => {
await this.executeRefresh();
});
}
/**
* Execute login command
*/
private async executeLogin(): Promise<void> {
try {
const result = await this.performInteractiveAuth();
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
// Exit cleanly after successful authentication
// Small delay to ensure all output is flushed
setTimeout(() => {
process.exit(0);
}, 100);
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Execute logout command
*/
private async executeLogout(): Promise<void> {
try {
const result = await this.performLogout();
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Execute status command
*/
private async executeStatus(): Promise<void> {
try {
const result = this.displayStatus();
this.setLastResult(result);
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Execute refresh command
*/
private async executeRefresh(): Promise<void> {
try {
const result = await this.refreshToken();
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Display authentication status
*/
private displayStatus(): AuthResult {
const credentials = this.authManager.getCredentials();
console.log(chalk.cyan('\n🔐 Authentication Status\n'));
if (credentials) {
console.log(chalk.green('✓ Authenticated'));
console.log(chalk.gray(` Email: ${credentials.email || 'N/A'}`));
console.log(chalk.gray(` User ID: ${credentials.userId}`));
console.log(
chalk.gray(` Token Type: ${credentials.tokenType || 'standard'}`)
);
if (credentials.expiresAt) {
const expiresAt = new Date(credentials.expiresAt);
const now = new Date();
const hoursRemaining = Math.floor(
(expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60)
);
if (hoursRemaining > 0) {
console.log(
chalk.gray(
` Expires: ${expiresAt.toLocaleString()} (${hoursRemaining} hours remaining)`
)
);
} else {
console.log(
chalk.yellow(` Token expired at: ${expiresAt.toLocaleString()}`)
);
}
} else {
console.log(chalk.gray(' Expires: Never (API key)'));
}
console.log(
chalk.gray(` Saved: ${new Date(credentials.savedAt).toLocaleString()}`)
);
return {
success: true,
action: 'status',
credentials,
message: 'Authenticated'
};
} else {
console.log(chalk.yellow('✗ Not authenticated'));
console.log(
chalk.gray('\n Run "task-master auth login" to authenticate')
);
return {
success: false,
action: 'status',
message: 'Not authenticated'
};
}
}
/**
* Perform logout
*/
private async performLogout(): Promise<AuthResult> {
try {
await this.authManager.logout();
ui.displaySuccess('Successfully logged out');
return {
success: true,
action: 'logout',
message: 'Successfully logged out'
};
} catch (error) {
const message = `Failed to logout: ${(error as Error).message}`;
ui.displayError(message);
return {
success: false,
action: 'logout',
message
};
}
}
/**
* Refresh authentication token
*/
private async refreshToken(): Promise<AuthResult> {
const spinner = ora('Refreshing authentication token...').start();
try {
const credentials = await this.authManager.refreshToken();
spinner.succeed('Token refreshed successfully');
console.log(
chalk.gray(
` New expiration: ${credentials.expiresAt ? new Date(credentials.expiresAt).toLocaleString() : 'Never'}`
)
);
return {
success: true,
action: 'refresh',
credentials,
message: 'Token refreshed successfully'
};
} catch (error) {
spinner.fail('Failed to refresh token');
if ((error as AuthenticationError).code === 'NO_REFRESH_TOKEN') {
ui.displayWarning(
'No refresh token available. Please re-authenticate.'
);
} else {
ui.displayError(`Refresh failed: ${(error as Error).message}`);
}
return {
success: false,
action: 'refresh',
message: `Failed to refresh: ${(error as Error).message}`
};
}
}
/**
* Perform interactive authentication
*/
private async performInteractiveAuth(): Promise<AuthResult> {
ui.displayBanner('Task Master Authentication');
// Check if already authenticated
if (this.authManager.isAuthenticated()) {
const { continueAuth } = await inquirer.prompt([
{
type: 'confirm',
name: 'continueAuth',
message:
'You are already authenticated. Do you want to re-authenticate?',
default: false
}
]);
if (!continueAuth) {
const credentials = this.authManager.getCredentials();
ui.displaySuccess('Using existing authentication');
if (credentials) {
console.log(chalk.gray(` Email: ${credentials.email || 'N/A'}`));
console.log(chalk.gray(` User ID: ${credentials.userId}`));
}
return {
success: true,
action: 'login',
credentials: credentials || undefined,
message: 'Using existing authentication'
};
}
}
try {
// Direct browser authentication - no menu needed
const credentials = await this.authenticateWithBrowser();
ui.displaySuccess('Authentication successful!');
console.log(
chalk.gray(` Logged in as: ${credentials.email || credentials.userId}`)
);
return {
success: true,
action: 'login',
credentials,
message: 'Authentication successful'
};
} catch (error) {
this.handleAuthError(error as AuthenticationError);
return {
success: false,
action: 'login',
message: `Authentication failed: ${(error as Error).message}`
};
}
}
/**
* Authenticate with browser using OAuth 2.0 with PKCE
*/
private async authenticateWithBrowser(): Promise<AuthCredentials> {
let authSpinner: Ora | null = null;
try {
// Use AuthManager's new unified OAuth flow method with callbacks
const credentials = await this.authManager.authenticateWithOAuth({
// Callback to handle browser opening
openBrowser: async (authUrl) => {
await open(authUrl);
},
timeout: 5 * 60 * 1000, // 5 minutes
// Callback when auth URL is ready
onAuthUrl: (authUrl) => {
// Display authentication instructions
console.log(chalk.blue.bold('\n🔐 Browser Authentication\n'));
console.log(chalk.white(' Opening your browser to authenticate...'));
console.log(chalk.gray(" If the browser doesn't open, visit:"));
console.log(chalk.cyan.underline(` ${authUrl}\n`));
},
// Callback when waiting for authentication
onWaitingForAuth: () => {
authSpinner = ora({
text: 'Waiting for authentication...',
spinner: 'dots'
}).start();
},
// Callback on success
onSuccess: () => {
if (authSpinner) {
authSpinner.succeed('Authentication successful!');
}
},
// Callback on error
onError: () => {
if (authSpinner) {
authSpinner.fail('Authentication failed');
}
}
});
return credentials;
} catch (error) {
throw error;
}
}
/**
* Handle authentication errors
*/
private handleAuthError(error: AuthenticationError): void {
console.error(chalk.red(`\n✗ ${error.message}`));
switch (error.code) {
case 'NETWORK_ERROR':
ui.displayWarning(
'Please check your internet connection and try again.'
);
break;
case 'INVALID_CREDENTIALS':
ui.displayWarning('Please check your credentials and try again.');
break;
case 'AUTH_EXPIRED':
ui.displayWarning(
'Your session has expired. Please authenticate again.'
);
break;
default:
if (process.env.DEBUG) {
console.error(chalk.gray(error.stack || ''));
}
}
}
/**
* Handle general errors
*/
private handleError(error: any): void {
if (error instanceof AuthenticationError) {
this.handleAuthError(error);
} else {
const msg = error?.getSanitizedDetails?.() ?? {
message: error?.message ?? String(error)
};
console.error(chalk.red(`Error: ${msg.message || 'Unexpected error'}`));
if (error.stack && process.env.DEBUG) {
console.error(chalk.gray(error.stack));
}
}
}
/**
* Set the last result for programmatic access
*/
private setLastResult(result: AuthResult): void {
this.lastResult = result;
}
/**
* Get the last result (for programmatic usage)
*/
getLastResult(): AuthResult | undefined {
return this.lastResult;
}
/**
* Get current authentication status (for programmatic usage)
*/
isAuthenticated(): boolean {
return this.authManager.isAuthenticated();
}
/**
* Get current credentials (for programmatic usage)
*/
getCredentials(): AuthCredentials | null {
return this.authManager.getCredentials();
}
/**
* Clean up resources
*/
async cleanup(): Promise<void> {
// No resources to clean up for auth command
// But keeping method for consistency with other commands
}
/**
* Static method to register this command on an existing program
* This is for gradual migration - allows commands.js to use this
*/
static registerOn(program: Command): Command {
const authCommand = new AuthCommand();
program.addCommand(authCommand);
return authCommand;
}
/**
* Alternative registration that returns the command for chaining
* Can also configure the command name if needed
*/
static register(program: Command, name?: string): AuthCommand {
const authCommand = new AuthCommand(name);
program.addCommand(authCommand);
return authCommand;
}
}

View File

@@ -0,0 +1,570 @@
/**
* @fileoverview Context command for managing org/brief selection
* Provides a clean interface for workspace context management
*/
import { Command } from 'commander';
import chalk from 'chalk';
import inquirer from 'inquirer';
import ora from 'ora';
import {
AuthManager,
AuthenticationError,
type UserContext
} from '@tm/core/auth';
import * as ui from '../utils/ui.js';
/**
* Result type from context command
*/
export interface ContextResult {
success: boolean;
action: 'show' | 'select-org' | 'select-brief' | 'clear' | 'set';
context?: UserContext;
message?: string;
}
/**
* ContextCommand extending Commander's Command class
* Manages user's workspace context (org/brief selection)
*/
export class ContextCommand extends Command {
private authManager: AuthManager;
private lastResult?: ContextResult;
constructor(name?: string) {
super(name || 'context');
// Initialize auth manager
this.authManager = AuthManager.getInstance();
// Configure the command
this.description(
'Manage workspace context (organization and brief selection)'
);
// Add subcommands
this.addOrgCommand();
this.addBriefCommand();
this.addClearCommand();
this.addSetCommand();
// Default action shows current context
this.action(async () => {
await this.executeShow();
});
}
/**
* Add org selection subcommand
*/
private addOrgCommand(): void {
this.command('org')
.description('Select an organization')
.action(async () => {
await this.executeSelectOrg();
});
}
/**
* Add brief selection subcommand
*/
private addBriefCommand(): void {
this.command('brief')
.description('Select a brief within the current organization')
.action(async () => {
await this.executeSelectBrief();
});
}
/**
* Add clear subcommand
*/
private addClearCommand(): void {
this.command('clear')
.description('Clear all context selections')
.action(async () => {
await this.executeClear();
});
}
/**
* Add set subcommand for direct context setting
*/
private addSetCommand(): void {
this.command('set')
.description('Set context directly')
.option('--org <id>', 'Organization ID')
.option('--org-name <name>', 'Organization name')
.option('--brief <id>', 'Brief ID')
.option('--brief-name <name>', 'Brief name')
.action(async (options) => {
await this.executeSet(options);
});
}
/**
* Execute show current context
*/
private async executeShow(): Promise<void> {
try {
const result = this.displayContext();
this.setLastResult(result);
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Display current context
*/
private displayContext(): ContextResult {
// Check authentication first
if (!this.authManager.isAuthenticated()) {
console.log(chalk.yellow('✗ Not authenticated'));
console.log(chalk.gray('\n Run "tm auth login" to authenticate first'));
return {
success: false,
action: 'show',
message: 'Not authenticated'
};
}
const context = this.authManager.getContext();
console.log(chalk.cyan('\n🌍 Workspace Context\n'));
if (context && (context.orgId || context.briefId)) {
if (context.orgName || context.orgId) {
console.log(chalk.green('✓ Organization'));
if (context.orgName) {
console.log(chalk.white(` ${context.orgName}`));
}
if (context.orgId) {
console.log(chalk.gray(` ID: ${context.orgId}`));
}
}
if (context.briefName || context.briefId) {
console.log(chalk.green('\n✓ Brief'));
if (context.briefName) {
console.log(chalk.white(` ${context.briefName}`));
}
if (context.briefId) {
console.log(chalk.gray(` ID: ${context.briefId}`));
}
}
if (context.updatedAt) {
console.log(
chalk.gray(
`\n Last updated: ${new Date(context.updatedAt).toLocaleString()}`
)
);
}
return {
success: true,
action: 'show',
context,
message: 'Context loaded'
};
} else {
console.log(chalk.yellow('✗ No context selected'));
console.log(
chalk.gray('\n Run "tm context org" to select an organization')
);
console.log(chalk.gray(' Run "tm context brief" to select a brief'));
return {
success: true,
action: 'show',
message: 'No context selected'
};
}
}
/**
* Execute org selection
*/
private async executeSelectOrg(): Promise<void> {
try {
// Check authentication
if (!this.authManager.isAuthenticated()) {
ui.displayError('Not authenticated. Run "tm auth login" first.');
process.exit(1);
}
const result = await this.selectOrganization();
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Select an organization interactively
*/
private async selectOrganization(): Promise<ContextResult> {
const spinner = ora('Fetching organizations...').start();
try {
// Fetch organizations from API
const organizations = await this.authManager.getOrganizations();
spinner.stop();
if (organizations.length === 0) {
ui.displayWarning('No organizations available');
return {
success: false,
action: 'select-org',
message: 'No organizations available'
};
}
// Prompt for selection
const { selectedOrg } = await inquirer.prompt([
{
type: 'list',
name: 'selectedOrg',
message: 'Select an organization:',
choices: organizations.map((org) => ({
name: org.name,
value: org
}))
}
]);
// Update context
await this.authManager.updateContext({
orgId: selectedOrg.id,
orgName: selectedOrg.name,
// Clear brief when changing org
briefId: undefined,
briefName: undefined
});
ui.displaySuccess(`Selected organization: ${selectedOrg.name}`);
return {
success: true,
action: 'select-org',
context: this.authManager.getContext() || undefined,
message: `Selected organization: ${selectedOrg.name}`
};
} catch (error) {
spinner.fail('Failed to fetch organizations');
throw error;
}
}
/**
* Execute brief selection
*/
private async executeSelectBrief(): Promise<void> {
try {
// Check authentication
if (!this.authManager.isAuthenticated()) {
ui.displayError('Not authenticated. Run "tm auth login" first.');
process.exit(1);
}
// Check if org is selected
const context = this.authManager.getContext();
if (!context?.orgId) {
ui.displayError(
'No organization selected. Run "tm context org" first.'
);
process.exit(1);
}
const result = await this.selectBrief(context.orgId);
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Select a brief within the current organization
*/
private async selectBrief(orgId: string): Promise<ContextResult> {
const spinner = ora('Fetching briefs...').start();
try {
// Fetch briefs from API
const briefs = await this.authManager.getBriefs(orgId);
spinner.stop();
if (briefs.length === 0) {
ui.displayWarning('No briefs available in this organization');
return {
success: false,
action: 'select-brief',
message: 'No briefs available'
};
}
// Prompt for selection
const { selectedBrief } = await inquirer.prompt([
{
type: 'list',
name: 'selectedBrief',
message: 'Select a brief:',
choices: [
{ name: '(No brief - organization level)', value: null },
...briefs.map((brief) => ({
name: `Brief ${brief.id.slice(0, 8)} (${new Date(brief.createdAt).toLocaleDateString()})`,
value: brief
}))
]
}
]);
if (selectedBrief) {
// Update context with brief
const briefName = `Brief ${selectedBrief.id.slice(0, 8)}`;
await this.authManager.updateContext({
briefId: selectedBrief.id,
briefName: briefName
});
ui.displaySuccess(`Selected brief: ${briefName}`);
return {
success: true,
action: 'select-brief',
context: this.authManager.getContext() || undefined,
message: `Selected brief: ${selectedBrief.name}`
};
} else {
// Clear brief selection
await this.authManager.updateContext({
briefId: undefined,
briefName: undefined
});
ui.displaySuccess('Cleared brief selection (organization level)');
return {
success: true,
action: 'select-brief',
context: this.authManager.getContext() || undefined,
message: 'Cleared brief selection'
};
}
} catch (error) {
spinner.fail('Failed to fetch briefs');
throw error;
}
}
/**
* Execute clear context
*/
private async executeClear(): Promise<void> {
try {
// Check authentication
if (!this.authManager.isAuthenticated()) {
ui.displayError('Not authenticated. Run "tm auth login" first.');
process.exit(1);
}
const result = await this.clearContext();
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Clear all context selections
*/
private async clearContext(): Promise<ContextResult> {
try {
await this.authManager.clearContext();
ui.displaySuccess('Context cleared');
return {
success: true,
action: 'clear',
message: 'Context cleared'
};
} catch (error) {
ui.displayError(`Failed to clear context: ${(error as Error).message}`);
return {
success: false,
action: 'clear',
message: `Failed to clear context: ${(error as Error).message}`
};
}
}
/**
* Execute set context with options
*/
private async executeSet(options: any): Promise<void> {
try {
// Check authentication
if (!this.authManager.isAuthenticated()) {
ui.displayError('Not authenticated. Run "tm auth login" first.');
process.exit(1);
}
const result = await this.setContext(options);
this.setLastResult(result);
if (!result.success) {
process.exit(1);
}
} catch (error: any) {
this.handleError(error);
process.exit(1);
}
}
/**
* Set context directly from options
*/
private async setContext(options: any): Promise<ContextResult> {
try {
const context: Partial<UserContext> = {};
if (options.org) {
context.orgId = options.org;
}
if (options.orgName) {
context.orgName = options.orgName;
}
if (options.brief) {
context.briefId = options.brief;
}
if (options.briefName) {
context.briefName = options.briefName;
}
if (Object.keys(context).length === 0) {
ui.displayWarning('No context options provided');
return {
success: false,
action: 'set',
message: 'No context options provided'
};
}
await this.authManager.updateContext(context);
ui.displaySuccess('Context updated');
// Display what was set
if (context.orgName || context.orgId) {
console.log(
chalk.gray(` Organization: ${context.orgName || context.orgId}`)
);
}
if (context.briefName || context.briefId) {
console.log(
chalk.gray(` Brief: ${context.briefName || context.briefId}`)
);
}
return {
success: true,
action: 'set',
context: this.authManager.getContext() || undefined,
message: 'Context updated'
};
} catch (error) {
ui.displayError(`Failed to set context: ${(error as Error).message}`);
return {
success: false,
action: 'set',
message: `Failed to set context: ${(error as Error).message}`
};
}
}
/**
* Handle errors
*/
private handleError(error: any): void {
if (error instanceof AuthenticationError) {
console.error(chalk.red(`\n✗ ${error.message}`));
if (error.code === 'NOT_AUTHENTICATED') {
ui.displayWarning('Please authenticate first: tm auth login');
}
} else {
const msg = error?.message ?? String(error);
console.error(chalk.red(`Error: ${msg}`));
if (error.stack && process.env.DEBUG) {
console.error(chalk.gray(error.stack));
}
}
}
/**
* Set the last result for programmatic access
*/
private setLastResult(result: ContextResult): void {
this.lastResult = result;
}
/**
* Get the last result (for programmatic usage)
*/
getLastResult(): ContextResult | undefined {
return this.lastResult;
}
/**
* Get current context (for programmatic usage)
*/
getContext(): UserContext | null {
return this.authManager.getContext();
}
/**
* Clean up resources
*/
async cleanup(): Promise<void> {
// No resources to clean up for context command
}
/**
* Static method to register this command on an existing program
*/
static registerOn(program: Command): Command {
const contextCommand = new ContextCommand();
program.addCommand(contextCommand);
return contextCommand;
}
/**
* Alternative registration that returns the command for chaining
*/
static register(program: Command, name?: string): ContextCommand {
const contextCommand = new ContextCommand(name);
program.addCommand(contextCommand);
return contextCommand;
}
}

View File

@@ -0,0 +1,488 @@
/**
* @fileoverview ListTasks command using Commander's native class pattern
* Extends Commander.Command for better integration with the framework
*/
import { Command } from 'commander';
import chalk from 'chalk';
import {
createTaskMasterCore,
type Task,
type TaskStatus,
type TaskMasterCore,
TASK_STATUSES,
OUTPUT_FORMATS,
STATUS_ICONS,
type OutputFormat
} from '@tm/core';
import type { StorageType } from '@tm/core/types';
import * as ui from '../utils/ui.js';
import {
displayHeader,
displayDashboards,
calculateTaskStatistics,
calculateSubtaskStatistics,
calculateDependencyStatistics,
getPriorityBreakdown,
displayRecommendedNextTask,
getTaskDescription,
displaySuggestedNextSteps,
type NextTaskInfo
} from '../ui/index.js';
/**
* Options interface for the list command
*/
export interface ListCommandOptions {
status?: string;
tag?: string;
withSubtasks?: boolean;
format?: OutputFormat;
silent?: boolean;
project?: string;
}
/**
* Result type from list command
*/
export interface ListTasksResult {
tasks: Task[];
total: number;
filtered: number;
tag?: string;
storageType: Exclude<StorageType, 'auto'>;
}
/**
* ListTasksCommand extending Commander's Command class
* This is a thin presentation layer over @tm/core
*/
export class ListTasksCommand extends Command {
private tmCore?: TaskMasterCore;
private lastResult?: ListTasksResult;
constructor(name?: string) {
super(name || 'list');
// Configure the command
this.description('List tasks with optional filtering')
.alias('ls')
.option('-s, --status <status>', 'Filter by status (comma-separated)')
.option('-t, --tag <tag>', 'Filter by tag')
.option('--with-subtasks', 'Include subtasks in the output')
.option(
'-f, --format <format>',
'Output format (text, json, compact)',
'text'
)
.option('--silent', 'Suppress output (useful for programmatic usage)')
.option('-p, --project <path>', 'Project root directory', process.cwd())
.action(async (options: ListCommandOptions) => {
await this.executeCommand(options);
});
}
/**
* Execute the list command
*/
private async executeCommand(options: ListCommandOptions): Promise<void> {
try {
// Validate options
if (!this.validateOptions(options)) {
process.exit(1);
}
// Initialize tm-core
await this.initializeCore(options.project || process.cwd());
// Get tasks from core
const result = await this.getTasks(options);
// Store result for programmatic access
this.setLastResult(result);
// Display results
if (!options.silent) {
this.displayResults(result, options);
}
} catch (error: any) {
const msg = error?.getSanitizedDetails?.() ?? {
message: error?.message ?? String(error)
};
console.error(chalk.red(`Error: ${msg.message || 'Unexpected error'}`));
if (error.stack && process.env.DEBUG) {
console.error(chalk.gray(error.stack));
}
process.exit(1);
}
}
/**
* Validate command options
*/
private validateOptions(options: ListCommandOptions): boolean {
// Validate format
if (
options.format &&
!OUTPUT_FORMATS.includes(options.format as OutputFormat)
) {
console.error(chalk.red(`Invalid format: ${options.format}`));
console.error(chalk.gray(`Valid formats: ${OUTPUT_FORMATS.join(', ')}`));
return false;
}
// Validate status
if (options.status) {
const statuses = options.status.split(',').map((s: string) => s.trim());
for (const status of statuses) {
if (status !== 'all' && !TASK_STATUSES.includes(status as TaskStatus)) {
console.error(chalk.red(`Invalid status: ${status}`));
console.error(
chalk.gray(`Valid statuses: ${TASK_STATUSES.join(', ')}`)
);
return false;
}
}
}
return true;
}
/**
* Initialize TaskMasterCore
*/
private async initializeCore(projectRoot: string): Promise<void> {
if (!this.tmCore) {
this.tmCore = await createTaskMasterCore({ projectPath: projectRoot });
}
}
/**
* Get tasks from tm-core
*/
private async getTasks(
options: ListCommandOptions
): Promise<ListTasksResult> {
if (!this.tmCore) {
throw new Error('TaskMasterCore not initialized');
}
// Build filter
const filter =
options.status && options.status !== 'all'
? {
status: options.status
.split(',')
.map((s: string) => s.trim() as TaskStatus)
}
: undefined;
// Call tm-core
const result = await this.tmCore.getTaskList({
tag: options.tag,
filter,
includeSubtasks: options.withSubtasks
});
return result as ListTasksResult;
}
/**
* Display results based on format
*/
private displayResults(
result: ListTasksResult,
options: ListCommandOptions
): void {
const format = (options.format || 'text') as OutputFormat | 'text';
switch (format) {
case 'json':
this.displayJson(result);
break;
case 'compact':
this.displayCompact(result.tasks, options.withSubtasks);
break;
case 'text':
default:
this.displayText(result, options.withSubtasks);
break;
}
}
/**
* Display in JSON format
*/
private displayJson(data: ListTasksResult): void {
console.log(
JSON.stringify(
{
tasks: data.tasks,
metadata: {
total: data.total,
filtered: data.filtered,
tag: data.tag,
storageType: data.storageType
}
},
null,
2
)
);
}
/**
* Display in compact format
*/
private displayCompact(tasks: Task[], withSubtasks?: boolean): void {
tasks.forEach((task) => {
const icon = STATUS_ICONS[task.status];
console.log(`${chalk.cyan(task.id)} ${icon} ${task.title}`);
if (withSubtasks && task.subtasks?.length) {
task.subtasks.forEach((subtask) => {
const subIcon = STATUS_ICONS[subtask.status];
console.log(
` ${chalk.gray(`${task.id}.${subtask.id}`)} ${subIcon} ${chalk.gray(subtask.title)}`
);
});
}
});
}
/**
* Display in text format with tables
*/
private displayText(data: ListTasksResult, withSubtasks?: boolean): void {
const { tasks, tag } = data;
// Get file path for display
const filePath = this.tmCore ? `.taskmaster/tasks/tasks.json` : undefined;
// Display header without banner (banner already shown by main CLI)
displayHeader({
tag: tag || 'master',
filePath: filePath
});
// No tasks message
if (tasks.length === 0) {
ui.displayWarning('No tasks found matching the criteria.');
return;
}
// Calculate statistics
const taskStats = calculateTaskStatistics(tasks);
const subtaskStats = calculateSubtaskStatistics(tasks);
const depStats = calculateDependencyStatistics(tasks);
const priorityBreakdown = getPriorityBreakdown(tasks);
// Find next task following the same logic as findNextTask
const nextTask = this.findNextTask(tasks);
// Display dashboard boxes
displayDashboards(
taskStats,
subtaskStats,
priorityBreakdown,
depStats,
nextTask
);
// Task table - no title, just show the table directly
console.log(
ui.createTaskTable(tasks, {
showSubtasks: withSubtasks,
showDependencies: true,
showComplexity: true // Enable complexity column
})
);
// Display recommended next task section immediately after table
if (nextTask) {
// Find the full task object to get description
const fullTask = tasks.find((t) => String(t.id) === String(nextTask.id));
const description = fullTask ? getTaskDescription(fullTask) : undefined;
displayRecommendedNextTask({
...nextTask,
status: 'pending', // Next task is typically pending
description
});
} else {
displayRecommendedNextTask(undefined);
}
// Display suggested next steps at the end
displaySuggestedNextSteps();
}
/**
* Set the last result for programmatic access
*/
private setLastResult(result: ListTasksResult): void {
this.lastResult = result;
}
/**
* Find the next task to work on
* Implements the same logic as scripts/modules/task-manager/find-next-task.js
*/
private findNextTask(tasks: Task[]): NextTaskInfo | undefined {
const priorityValues: Record<string, number> = {
critical: 4,
high: 3,
medium: 2,
low: 1
};
// Build set of completed task IDs (including subtasks)
const completedIds = new Set<string>();
tasks.forEach((t) => {
if (t.status === 'done' || t.status === 'completed') {
completedIds.add(String(t.id));
}
if (t.subtasks) {
t.subtasks.forEach((st) => {
if (st.status === 'done' || st.status === 'completed') {
completedIds.add(`${t.id}.${st.id}`);
}
});
}
});
// First, look for eligible subtasks in in-progress parent tasks
const candidateSubtasks: NextTaskInfo[] = [];
tasks
.filter(
(t) => t.status === 'in-progress' && t.subtasks && t.subtasks.length > 0
)
.forEach((parent) => {
parent.subtasks!.forEach((st) => {
const stStatus = (st.status || 'pending').toLowerCase();
if (stStatus !== 'pending' && stStatus !== 'in-progress') return;
// Check if dependencies are satisfied
const fullDeps =
st.dependencies?.map((d) => {
// Handle both numeric and string IDs
if (typeof d === 'string' && d.includes('.')) {
return d;
}
return `${parent.id}.${d}`;
}) ?? [];
const depsSatisfied =
fullDeps.length === 0 ||
fullDeps.every((depId) => completedIds.has(String(depId)));
if (depsSatisfied) {
candidateSubtasks.push({
id: `${parent.id}.${st.id}`,
title: st.title || `Subtask ${st.id}`,
priority: st.priority || parent.priority || 'medium',
dependencies: fullDeps.map((d) => String(d))
});
}
});
});
if (candidateSubtasks.length > 0) {
// Sort by priority, then by dependencies count, then by ID
candidateSubtasks.sort((a, b) => {
const pa = priorityValues[a.priority || 'medium'] ?? 2;
const pb = priorityValues[b.priority || 'medium'] ?? 2;
if (pb !== pa) return pb - pa;
const depCountA = a.dependencies?.length || 0;
const depCountB = b.dependencies?.length || 0;
if (depCountA !== depCountB) return depCountA - depCountB;
return String(a.id).localeCompare(String(b.id));
});
return candidateSubtasks[0];
}
// Fall back to finding eligible top-level tasks
const eligibleTasks = tasks.filter((task) => {
// Skip non-eligible statuses
const status = (task.status || 'pending').toLowerCase();
if (status !== 'pending' && status !== 'in-progress') return false;
// Check dependencies
const deps = task.dependencies || [];
const depsSatisfied =
deps.length === 0 ||
deps.every((depId) => completedIds.has(String(depId)));
return depsSatisfied;
});
if (eligibleTasks.length === 0) return undefined;
// Sort eligible tasks
eligibleTasks.sort((a, b) => {
// Priority (higher first)
const pa = priorityValues[a.priority || 'medium'] ?? 2;
const pb = priorityValues[b.priority || 'medium'] ?? 2;
if (pb !== pa) return pb - pa;
// Dependencies count (fewer first)
const depCountA = a.dependencies?.length || 0;
const depCountB = b.dependencies?.length || 0;
if (depCountA !== depCountB) return depCountA - depCountB;
// ID (lower first)
return Number(a.id) - Number(b.id);
});
const nextTask = eligibleTasks[0];
return {
id: nextTask.id,
title: nextTask.title,
priority: nextTask.priority,
dependencies: nextTask.dependencies?.map((d) => String(d))
};
}
/**
* Get the last result (for programmatic usage)
*/
getLastResult(): ListTasksResult | undefined {
return this.lastResult;
}
/**
* Clean up resources
*/
async cleanup(): Promise<void> {
if (this.tmCore) {
await this.tmCore.close();
this.tmCore = undefined;
}
}
/**
* Static method to register this command on an existing program
* This is for gradual migration - allows commands.js to use this
*/
static registerOn(program: Command): Command {
const listCommand = new ListTasksCommand();
program.addCommand(listCommand);
return listCommand;
}
/**
* Alternative registration that returns the command for chaining
* Can also configure the command name if needed
*/
static register(program: Command, name?: string): ListTasksCommand {
const listCommand = new ListTasksCommand(name);
program.addCommand(listCommand);
return listCommand;
}
}

View File

@@ -0,0 +1,383 @@
/**
* @fileoverview ShowCommand using Commander's native class pattern
* Extends Commander.Command for better integration with the framework
*/
import { Command } from 'commander';
import chalk from 'chalk';
import boxen from 'boxen';
import { createTaskMasterCore, type Task, type TaskMasterCore } from '@tm/core';
import type { StorageType } from '@tm/core/types';
import * as ui from '../utils/ui.js';
import {
displayTaskHeader,
displayTaskProperties,
displayImplementationDetails,
displayTestStrategy,
displaySubtasks,
displaySuggestedActions
} from '../ui/components/task-detail.component.js';
/**
* Options interface for the show command
*/
export interface ShowCommandOptions {
id?: string;
status?: string;
format?: 'text' | 'json';
silent?: boolean;
project?: string;
}
/**
* Result type from show command
*/
export interface ShowTaskResult {
task: Task | null;
found: boolean;
storageType: Exclude<StorageType, 'auto'>;
}
/**
* Result type for multiple tasks
*/
export interface ShowMultipleTasksResult {
tasks: Task[];
notFound: string[];
storageType: Exclude<StorageType, 'auto'>;
}
/**
* ShowCommand extending Commander's Command class
* This is a thin presentation layer over @tm/core
*/
export class ShowCommand extends Command {
private tmCore?: TaskMasterCore;
private lastResult?: ShowTaskResult | ShowMultipleTasksResult;
constructor(name?: string) {
super(name || 'show');
// Configure the command
this.description('Display detailed information about one or more tasks')
.argument('[id]', 'Task ID(s) to show (comma-separated for multiple)')
.option(
'-i, --id <id>',
'Task ID(s) to show (comma-separated for multiple)'
)
.option('-s, --status <status>', 'Filter subtasks by status')
.option('-f, --format <format>', 'Output format (text, json)', 'text')
.option('--silent', 'Suppress output (useful for programmatic usage)')
.option('-p, --project <path>', 'Project root directory', process.cwd())
.action(
async (taskId: string | undefined, options: ShowCommandOptions) => {
await this.executeCommand(taskId, options);
}
);
}
/**
* Execute the show command
*/
private async executeCommand(
taskId: string | undefined,
options: ShowCommandOptions
): Promise<void> {
try {
// Validate options
if (!this.validateOptions(options)) {
process.exit(1);
}
// Initialize tm-core
await this.initializeCore(options.project || process.cwd());
// Get the task ID from argument or option
const idArg = taskId || options.id;
if (!idArg) {
console.error(chalk.red('Error: Please provide a task ID'));
process.exit(1);
}
// Check if multiple IDs are provided (comma-separated)
const taskIds = idArg
.split(',')
.map((id) => id.trim())
.filter((id) => id.length > 0);
// Get tasks from core
const result =
taskIds.length > 1
? await this.getMultipleTasks(taskIds, options)
: await this.getSingleTask(taskIds[0], options);
// Store result for programmatic access
this.setLastResult(result);
// Display results
if (!options.silent) {
this.displayResults(result, options);
}
} catch (error: any) {
const msg = error?.getSanitizedDetails?.() ?? {
message: error?.message ?? String(error)
};
console.error(chalk.red(`Error: ${msg.message || 'Unexpected error'}`));
if (error.stack && process.env.DEBUG) {
console.error(chalk.gray(error.stack));
}
process.exit(1);
}
}
/**
* Validate command options
*/
private validateOptions(options: ShowCommandOptions): boolean {
// Validate format
if (options.format && !['text', 'json'].includes(options.format)) {
console.error(chalk.red(`Invalid format: ${options.format}`));
console.error(chalk.gray(`Valid formats: text, json`));
return false;
}
return true;
}
/**
* Initialize TaskMasterCore
*/
private async initializeCore(projectRoot: string): Promise<void> {
if (!this.tmCore) {
this.tmCore = await createTaskMasterCore({ projectPath: projectRoot });
}
}
/**
* Get a single task from tm-core
*/
private async getSingleTask(
taskId: string,
_options: ShowCommandOptions
): Promise<ShowTaskResult> {
if (!this.tmCore) {
throw new Error('TaskMasterCore not initialized');
}
// Get the task
const task = await this.tmCore.getTask(taskId);
// Get storage type
const storageType = this.tmCore.getStorageType();
return {
task,
found: task !== null,
storageType: storageType as Exclude<StorageType, 'auto'>
};
}
/**
* Get multiple tasks from tm-core
*/
private async getMultipleTasks(
taskIds: string[],
_options: ShowCommandOptions
): Promise<ShowMultipleTasksResult> {
if (!this.tmCore) {
throw new Error('TaskMasterCore not initialized');
}
const tasks: Task[] = [];
const notFound: string[] = [];
// Get each task individually
for (const taskId of taskIds) {
const task = await this.tmCore.getTask(taskId);
if (task) {
tasks.push(task);
} else {
notFound.push(taskId);
}
}
// Get storage type
const storageType = this.tmCore.getStorageType();
return {
tasks,
notFound,
storageType: storageType as Exclude<StorageType, 'auto'>
};
}
/**
* Display results based on format
*/
private displayResults(
result: ShowTaskResult | ShowMultipleTasksResult,
options: ShowCommandOptions
): void {
const format = options.format || 'text';
switch (format) {
case 'json':
this.displayJson(result);
break;
case 'text':
default:
if ('task' in result) {
// Single task result
this.displaySingleTask(result, options);
} else {
// Multiple tasks result
this.displayMultipleTasks(result, options);
}
break;
}
}
/**
* Display in JSON format
*/
private displayJson(result: ShowTaskResult | ShowMultipleTasksResult): void {
console.log(JSON.stringify(result, null, 2));
}
/**
* Display a single task in text format
*/
private displaySingleTask(
result: ShowTaskResult,
options: ShowCommandOptions
): void {
if (!result.found || !result.task) {
console.log(
boxen(chalk.yellow(`Task not found!`), {
padding: { top: 0, bottom: 0, left: 1, right: 1 },
borderColor: 'yellow',
borderStyle: 'round',
margin: { top: 1 }
})
);
return;
}
const task = result.task;
// Display header with tag
displayTaskHeader(task.id, task.title);
// Display task properties in table format
displayTaskProperties(task);
// Display implementation details if available
if (task.details) {
console.log(); // Empty line for spacing
displayImplementationDetails(task.details);
}
// Display test strategy if available
if ('testStrategy' in task && task.testStrategy) {
console.log(); // Empty line for spacing
displayTestStrategy(task.testStrategy as string);
}
// Display subtasks if available
if (task.subtasks && task.subtasks.length > 0) {
// Filter subtasks by status if provided
const filteredSubtasks = options.status
? task.subtasks.filter((sub) => sub.status === options.status)
: task.subtasks;
if (filteredSubtasks.length === 0 && options.status) {
console.log(
chalk.gray(` No subtasks with status '${options.status}'`)
);
} else {
displaySubtasks(filteredSubtasks, task.id);
}
}
// Display suggested actions
displaySuggestedActions(task.id);
}
/**
* Display multiple tasks in text format
*/
private displayMultipleTasks(
result: ShowMultipleTasksResult,
_options: ShowCommandOptions
): void {
// Header
ui.displayBanner(`Tasks (${result.tasks.length} found)`);
if (result.notFound.length > 0) {
console.log(chalk.yellow(`\n⚠ Not found: ${result.notFound.join(', ')}`));
}
if (result.tasks.length === 0) {
ui.displayWarning('No tasks found matching the criteria.');
return;
}
// Task table
console.log(chalk.blue.bold(`\n📋 Tasks:\n`));
console.log(
ui.createTaskTable(result.tasks, {
showSubtasks: true,
showDependencies: true
})
);
console.log(`\n${chalk.gray('Storage: ' + result.storageType)}`);
}
/**
* Set the last result for programmatic access
*/
private setLastResult(
result: ShowTaskResult | ShowMultipleTasksResult
): void {
this.lastResult = result;
}
/**
* Get the last result (for programmatic usage)
*/
getLastResult(): ShowTaskResult | ShowMultipleTasksResult | undefined {
return this.lastResult;
}
/**
* Clean up resources
*/
async cleanup(): Promise<void> {
if (this.tmCore) {
await this.tmCore.close();
this.tmCore = undefined;
}
}
/**
* Static method to register this command on an existing program
* This is for gradual migration - allows commands.js to use this
*/
static registerOn(program: Command): Command {
const showCommand = new ShowCommand();
program.addCommand(showCommand);
return showCommand;
}
/**
* Alternative registration that returns the command for chaining
* Can also configure the command name if needed
*/
static register(program: Command, name?: string): ShowCommand {
const showCommand = new ShowCommand(name);
program.addCommand(showCommand);
return showCommand;
}
}

21
apps/cli/src/index.ts Normal file
View File

@@ -0,0 +1,21 @@
/**
* @fileoverview Main entry point for @tm/cli package
* Exports all public APIs for the CLI presentation layer
*/
// Commands
export { ListTasksCommand } from './commands/list.command.js';
export { ShowCommand } from './commands/show.command.js';
export { AuthCommand } from './commands/auth.command.js';
export { ContextCommand } from './commands/context.command.js';
// UI utilities (for other commands to use)
export * as ui from './utils/ui.js';
// Re-export commonly used types from tm-core
export type {
Task,
TaskStatus,
TaskPriority,
TaskMasterCore
} from '@tm/core';

View File

@@ -0,0 +1,567 @@
/**
* @fileoverview Dashboard components for Task Master CLI
* Displays project statistics and dependency information
*/
import chalk from 'chalk';
import boxen from 'boxen';
import type { Task, TaskPriority } from '@tm/core/types';
/**
* Statistics for task collection
*/
export interface TaskStatistics {
total: number;
done: number;
inProgress: number;
pending: number;
blocked: number;
deferred: number;
cancelled: number;
review?: number;
completionPercentage: number;
}
/**
* Statistics for dependencies
*/
export interface DependencyStatistics {
tasksWithNoDeps: number;
tasksReadyToWork: number;
tasksBlockedByDeps: number;
mostDependedOnTaskId?: number;
mostDependedOnCount?: number;
avgDependenciesPerTask: number;
}
/**
* Next task information
*/
export interface NextTaskInfo {
id: string | number;
title: string;
priority?: TaskPriority;
dependencies?: (string | number)[];
complexity?: number | string;
}
/**
* Status breakdown for progress bars
*/
export interface StatusBreakdown {
'in-progress'?: number;
pending?: number;
blocked?: number;
deferred?: number;
cancelled?: number;
review?: number;
}
/**
* Create a progress bar with color-coded status segments
*/
function createProgressBar(
completionPercentage: number,
width: number = 30,
statusBreakdown?: StatusBreakdown
): string {
// If no breakdown provided, use simple green bar
if (!statusBreakdown) {
const filled = Math.round((completionPercentage / 100) * width);
const empty = width - filled;
return chalk.green('█').repeat(filled) + chalk.gray('░').repeat(empty);
}
// Build the bar with different colored sections
// Order matches the status display: Done, Cancelled, Deferred, In Progress, Review, Pending, Blocked
let bar = '';
let charsUsed = 0;
// 1. Green filled blocks for completed tasks (done)
const completedChars = Math.round((completionPercentage / 100) * width);
if (completedChars > 0) {
bar += chalk.green('█').repeat(completedChars);
charsUsed += completedChars;
}
// 2. Gray filled blocks for cancelled (won't be done)
if (statusBreakdown.cancelled && charsUsed < width) {
const cancelledChars = Math.round(
(statusBreakdown.cancelled / 100) * width
);
const actualChars = Math.min(cancelledChars, width - charsUsed);
if (actualChars > 0) {
bar += chalk.gray('█').repeat(actualChars);
charsUsed += actualChars;
}
}
// 3. Gray filled blocks for deferred (won't be done now)
if (statusBreakdown.deferred && charsUsed < width) {
const deferredChars = Math.round((statusBreakdown.deferred / 100) * width);
const actualChars = Math.min(deferredChars, width - charsUsed);
if (actualChars > 0) {
bar += chalk.gray('█').repeat(actualChars);
charsUsed += actualChars;
}
}
// 4. Blue filled blocks for in-progress (actively working)
if (statusBreakdown['in-progress'] && charsUsed < width) {
const inProgressChars = Math.round(
(statusBreakdown['in-progress'] / 100) * width
);
const actualChars = Math.min(inProgressChars, width - charsUsed);
if (actualChars > 0) {
bar += chalk.blue('█').repeat(actualChars);
charsUsed += actualChars;
}
}
// 5. Magenta empty blocks for review (almost done)
if (statusBreakdown.review && charsUsed < width) {
const reviewChars = Math.round((statusBreakdown.review / 100) * width);
const actualChars = Math.min(reviewChars, width - charsUsed);
if (actualChars > 0) {
bar += chalk.magenta('░').repeat(actualChars);
charsUsed += actualChars;
}
}
// 6. Yellow empty blocks for pending (ready to start)
if (statusBreakdown.pending && charsUsed < width) {
const pendingChars = Math.round((statusBreakdown.pending / 100) * width);
const actualChars = Math.min(pendingChars, width - charsUsed);
if (actualChars > 0) {
bar += chalk.yellow('░').repeat(actualChars);
charsUsed += actualChars;
}
}
// 7. Red empty blocks for blocked (can't start yet)
if (statusBreakdown.blocked && charsUsed < width) {
const blockedChars = Math.round((statusBreakdown.blocked / 100) * width);
const actualChars = Math.min(blockedChars, width - charsUsed);
if (actualChars > 0) {
bar += chalk.red('░').repeat(actualChars);
charsUsed += actualChars;
}
}
// Fill any remaining space with gray empty yellow blocks
if (charsUsed < width) {
bar += chalk.yellow('░').repeat(width - charsUsed);
}
return bar;
}
/**
* Calculate task statistics from a list of tasks
*/
export function calculateTaskStatistics(tasks: Task[]): TaskStatistics {
const stats: TaskStatistics = {
total: tasks.length,
done: 0,
inProgress: 0,
pending: 0,
blocked: 0,
deferred: 0,
cancelled: 0,
review: 0,
completionPercentage: 0
};
tasks.forEach((task) => {
switch (task.status) {
case 'done':
stats.done++;
break;
case 'in-progress':
stats.inProgress++;
break;
case 'pending':
stats.pending++;
break;
case 'blocked':
stats.blocked++;
break;
case 'deferred':
stats.deferred++;
break;
case 'cancelled':
stats.cancelled++;
break;
case 'review':
stats.review = (stats.review || 0) + 1;
break;
}
});
stats.completionPercentage =
stats.total > 0 ? Math.round((stats.done / stats.total) * 100) : 0;
return stats;
}
/**
* Calculate subtask statistics from tasks
*/
export function calculateSubtaskStatistics(tasks: Task[]): TaskStatistics {
const stats: TaskStatistics = {
total: 0,
done: 0,
inProgress: 0,
pending: 0,
blocked: 0,
deferred: 0,
cancelled: 0,
review: 0,
completionPercentage: 0
};
tasks.forEach((task) => {
if (task.subtasks && task.subtasks.length > 0) {
task.subtasks.forEach((subtask) => {
stats.total++;
switch (subtask.status) {
case 'done':
stats.done++;
break;
case 'in-progress':
stats.inProgress++;
break;
case 'pending':
stats.pending++;
break;
case 'blocked':
stats.blocked++;
break;
case 'deferred':
stats.deferred++;
break;
case 'cancelled':
stats.cancelled++;
break;
case 'review':
stats.review = (stats.review || 0) + 1;
break;
}
});
}
});
stats.completionPercentage =
stats.total > 0 ? Math.round((stats.done / stats.total) * 100) : 0;
return stats;
}
/**
* Calculate dependency statistics
*/
export function calculateDependencyStatistics(
tasks: Task[]
): DependencyStatistics {
const completedTaskIds = new Set(
tasks.filter((t) => t.status === 'done').map((t) => t.id)
);
const tasksWithNoDeps = tasks.filter(
(t) =>
t.status !== 'done' && (!t.dependencies || t.dependencies.length === 0)
).length;
const tasksWithAllDepsSatisfied = tasks.filter(
(t) =>
t.status !== 'done' &&
t.dependencies &&
t.dependencies.length > 0 &&
t.dependencies.every((depId) => completedTaskIds.has(depId))
).length;
const tasksBlockedByDeps = tasks.filter(
(t) =>
t.status !== 'done' &&
t.dependencies &&
t.dependencies.length > 0 &&
!t.dependencies.every((depId) => completedTaskIds.has(depId))
).length;
// Calculate most depended-on task
const dependencyCount: Record<string, number> = {};
tasks.forEach((task) => {
if (task.dependencies && task.dependencies.length > 0) {
task.dependencies.forEach((depId) => {
const key = String(depId);
dependencyCount[key] = (dependencyCount[key] || 0) + 1;
});
}
});
let mostDependedOnTaskId: number | undefined;
let mostDependedOnCount = 0;
for (const [taskId, count] of Object.entries(dependencyCount)) {
if (count > mostDependedOnCount) {
mostDependedOnCount = count;
mostDependedOnTaskId = parseInt(taskId);
}
}
// Calculate average dependencies
const totalDependencies = tasks.reduce(
(sum, task) => sum + (task.dependencies ? task.dependencies.length : 0),
0
);
const avgDependenciesPerTask =
tasks.length > 0 ? totalDependencies / tasks.length : 0;
return {
tasksWithNoDeps,
tasksReadyToWork: tasksWithNoDeps + tasksWithAllDepsSatisfied,
tasksBlockedByDeps,
mostDependedOnTaskId,
mostDependedOnCount,
avgDependenciesPerTask
};
}
/**
* Get priority counts
*/
export function getPriorityBreakdown(
tasks: Task[]
): Record<TaskPriority, number> {
const breakdown: Record<TaskPriority, number> = {
critical: 0,
high: 0,
medium: 0,
low: 0
};
tasks.forEach((task) => {
const priority = task.priority || 'medium';
breakdown[priority]++;
});
return breakdown;
}
/**
* Calculate status breakdown as percentages
*/
function calculateStatusBreakdown(stats: TaskStatistics): StatusBreakdown {
if (stats.total === 0) return {};
return {
'in-progress': (stats.inProgress / stats.total) * 100,
pending: (stats.pending / stats.total) * 100,
blocked: (stats.blocked / stats.total) * 100,
deferred: (stats.deferred / stats.total) * 100,
cancelled: (stats.cancelled / stats.total) * 100,
review: ((stats.review || 0) / stats.total) * 100
};
}
/**
* Format status counts in the correct order with colors
* @param stats - The statistics object containing counts
* @param isSubtask - Whether this is for subtasks (affects "Done" vs "Completed" label)
*/
function formatStatusLine(
stats: TaskStatistics,
isSubtask: boolean = false
): string {
const parts: string[] = [];
// Order: Done, Cancelled, Deferred, In Progress, Review, Pending, Blocked
if (isSubtask) {
parts.push(`Completed: ${chalk.green(`${stats.done}/${stats.total}`)}`);
} else {
parts.push(`Done: ${chalk.green(stats.done)}`);
}
parts.push(`Cancelled: ${chalk.gray(stats.cancelled)}`);
parts.push(`Deferred: ${chalk.gray(stats.deferred)}`);
// Add line break for second row
const firstLine = parts.join(' ');
parts.length = 0;
parts.push(`In Progress: ${chalk.blue(stats.inProgress)}`);
parts.push(`Review: ${chalk.magenta(stats.review || 0)}`);
parts.push(`Pending: ${chalk.yellow(stats.pending)}`);
parts.push(`Blocked: ${chalk.red(stats.blocked)}`);
const secondLine = parts.join(' ');
return firstLine + '\n' + secondLine;
}
/**
* Display the project dashboard box
*/
export function displayProjectDashboard(
taskStats: TaskStatistics,
subtaskStats: TaskStatistics,
priorityBreakdown: Record<TaskPriority, number>
): string {
// Calculate status breakdowns using the helper function
const taskStatusBreakdown = calculateStatusBreakdown(taskStats);
const subtaskStatusBreakdown = calculateStatusBreakdown(subtaskStats);
// Create progress bars with the breakdowns
const taskProgressBar = createProgressBar(
taskStats.completionPercentage,
30,
taskStatusBreakdown
);
const subtaskProgressBar = createProgressBar(
subtaskStats.completionPercentage,
30,
subtaskStatusBreakdown
);
const taskPercentage = `${taskStats.completionPercentage}% ${taskStats.done}/${taskStats.total}`;
const subtaskPercentage = `${subtaskStats.completionPercentage}% ${subtaskStats.done}/${subtaskStats.total}`;
const content =
chalk.white.bold('Project Dashboard') +
'\n' +
`Tasks Progress: ${taskProgressBar} ${chalk.yellow(taskPercentage)}\n` +
formatStatusLine(taskStats, false) +
'\n\n' +
`Subtasks Progress: ${subtaskProgressBar} ${chalk.cyan(subtaskPercentage)}\n` +
formatStatusLine(subtaskStats, true) +
'\n\n' +
chalk.cyan.bold('Priority Breakdown:') +
'\n' +
`${chalk.red('•')} ${chalk.white('High priority:')} ${priorityBreakdown.high}\n` +
`${chalk.yellow('•')} ${chalk.white('Medium priority:')} ${priorityBreakdown.medium}\n` +
`${chalk.green('•')} ${chalk.white('Low priority:')} ${priorityBreakdown.low}`;
return content;
}
/**
* Display the dependency dashboard box
*/
export function displayDependencyDashboard(
depStats: DependencyStatistics,
nextTask?: NextTaskInfo
): string {
const content =
chalk.white.bold('Dependency Status & Next Task') +
'\n' +
chalk.cyan.bold('Dependency Metrics:') +
'\n' +
`${chalk.green('•')} ${chalk.white('Tasks with no dependencies:')} ${depStats.tasksWithNoDeps}\n` +
`${chalk.green('•')} ${chalk.white('Tasks ready to work on:')} ${depStats.tasksReadyToWork}\n` +
`${chalk.yellow('•')} ${chalk.white('Tasks blocked by dependencies:')} ${depStats.tasksBlockedByDeps}\n` +
`${chalk.magenta('•')} ${chalk.white('Most depended-on task:')} ${
depStats.mostDependedOnTaskId
? chalk.cyan(
`#${depStats.mostDependedOnTaskId} (${depStats.mostDependedOnCount} dependents)`
)
: chalk.gray('None')
}\n` +
`${chalk.blue('•')} ${chalk.white('Avg dependencies per task:')} ${depStats.avgDependenciesPerTask.toFixed(1)}\n\n` +
chalk.cyan.bold('Next Task to Work On:') +
'\n' +
`ID: ${nextTask ? chalk.cyan(String(nextTask.id)) : chalk.gray('N/A')} - ${
nextTask
? chalk.white.bold(nextTask.title)
: chalk.yellow('No task available')
}\n` +
`Priority: ${nextTask?.priority || chalk.gray('N/A')} Dependencies: ${
nextTask?.dependencies?.length
? chalk.cyan(nextTask.dependencies.join(', '))
: chalk.gray('None')
}\n` +
`Complexity: ${nextTask?.complexity || chalk.gray('N/A')}`;
return content;
}
/**
* Display dashboard boxes side by side or stacked
*/
export function displayDashboards(
taskStats: TaskStatistics,
subtaskStats: TaskStatistics,
priorityBreakdown: Record<TaskPriority, number>,
depStats: DependencyStatistics,
nextTask?: NextTaskInfo
): void {
const projectDashboardContent = displayProjectDashboard(
taskStats,
subtaskStats,
priorityBreakdown
);
const dependencyDashboardContent = displayDependencyDashboard(
depStats,
nextTask
);
// Get terminal width
const terminalWidth = process.stdout.columns || 80;
const minDashboardWidth = 50;
const minDependencyWidth = 50;
const totalMinWidth = minDashboardWidth + minDependencyWidth + 4;
// If terminal is wide enough, show side by side
if (terminalWidth >= totalMinWidth) {
const halfWidth = Math.floor(terminalWidth / 2);
const boxContentWidth = halfWidth - 4;
const dashboardBox = boxen(projectDashboardContent, {
padding: 1,
borderColor: 'blue',
borderStyle: 'round',
width: boxContentWidth,
dimBorder: false
});
const dependencyBox = boxen(dependencyDashboardContent, {
padding: 1,
borderColor: 'magenta',
borderStyle: 'round',
width: boxContentWidth,
dimBorder: false
});
// Create side-by-side layout
const dashboardLines = dashboardBox.split('\n');
const dependencyLines = dependencyBox.split('\n');
const maxHeight = Math.max(dashboardLines.length, dependencyLines.length);
const combinedLines = [];
for (let i = 0; i < maxHeight; i++) {
const dashLine = i < dashboardLines.length ? dashboardLines[i] : '';
const depLine = i < dependencyLines.length ? dependencyLines[i] : '';
const paddedDashLine = dashLine.padEnd(halfWidth, ' ');
combinedLines.push(paddedDashLine + depLine);
}
console.log(combinedLines.join('\n'));
} else {
// Show stacked vertically
const dashboardBox = boxen(projectDashboardContent, {
padding: 1,
borderColor: 'blue',
borderStyle: 'round',
margin: { top: 0, bottom: 1 }
});
const dependencyBox = boxen(dependencyDashboardContent, {
padding: 1,
borderColor: 'magenta',
borderStyle: 'round',
margin: { top: 0, bottom: 1 }
});
console.log(dashboardBox);
console.log(dependencyBox);
}
}

View File

@@ -0,0 +1,45 @@
/**
* @fileoverview Task Master header component
* Displays the banner, version, project info, and file path
*/
import chalk from 'chalk';
/**
* Header configuration options
*/
export interface HeaderOptions {
title?: string;
tag?: string;
filePath?: string;
}
/**
* Display the Task Master header with project info
*/
export function displayHeader(options: HeaderOptions = {}): void {
const { filePath, tag } = options;
// Display tag and file path info
if (tag) {
let tagInfo = '';
if (tag && tag !== 'master') {
tagInfo = `🏷 tag: ${chalk.cyan(tag)}`;
} else {
tagInfo = `🏷 tag: ${chalk.cyan('master')}`;
}
console.log(tagInfo);
if (filePath) {
// Convert to absolute path if it's relative
const absolutePath = filePath.startsWith('/')
? filePath
: `${process.cwd()}/${filePath}`;
console.log(`Listing tasks from: ${chalk.dim(absolutePath)}`);
}
console.log(); // Empty line for spacing
}
}

View File

@@ -0,0 +1,9 @@
/**
* @fileoverview UI components exports
*/
export * from './header.component.js';
export * from './dashboard.component.js';
export * from './next-task.component.js';
export * from './suggested-steps.component.js';
export * from './task-detail.component.js';

View File

@@ -0,0 +1,134 @@
/**
* @fileoverview Next task recommendation component
* Displays detailed information about the recommended next task
*/
import chalk from 'chalk';
import boxen from 'boxen';
import type { Task } from '@tm/core/types';
/**
* Next task display options
*/
export interface NextTaskDisplayOptions {
id: string | number;
title: string;
priority?: string;
status?: string;
dependencies?: (string | number)[];
description?: string;
}
/**
* Display the recommended next task section
*/
export function displayRecommendedNextTask(
task: NextTaskDisplayOptions | undefined
): void {
if (!task) {
// If no task available, show a message
console.log(
boxen(
chalk.yellow(
'No tasks available to work on. All tasks are either completed, blocked by dependencies, or in progress.'
),
{
padding: 1,
borderStyle: 'round',
borderColor: 'yellow',
title: '⚠ NO TASKS AVAILABLE ⚠',
titleAlignment: 'center'
}
)
);
return;
}
// Build the content for the next task box
const content = [];
// Task header with ID and title
content.push(
`🔥 ${chalk.hex('#FF8800').bold('Next Task to Work On:')} ${chalk.yellow(`#${task.id}`)}${chalk.hex('#FF8800').bold(` - ${task.title}`)}`
);
content.push('');
// Priority and Status line
const statusLine = [];
if (task.priority) {
const priorityColor =
task.priority === 'high'
? chalk.red
: task.priority === 'medium'
? chalk.yellow
: chalk.gray;
statusLine.push(`Priority: ${priorityColor.bold(task.priority)}`);
}
if (task.status) {
const statusDisplay =
task.status === 'pending'
? chalk.yellow('○ pending')
: task.status === 'in-progress'
? chalk.blue('▶ in-progress')
: chalk.gray(task.status);
statusLine.push(`Status: ${statusDisplay}`);
}
content.push(statusLine.join(' '));
// Dependencies
const depsDisplay =
!task.dependencies || task.dependencies.length === 0
? chalk.gray('None')
: chalk.cyan(task.dependencies.join(', '));
content.push(`Dependencies: ${depsDisplay}`);
// Description if available
if (task.description) {
content.push('');
content.push(`Description: ${chalk.white(task.description)}`);
}
// Action commands
content.push('');
content.push(
`${chalk.cyan('Start working:')} ${chalk.yellow(`task-master set-status --id=${task.id} --status=in-progress`)}`
);
content.push(
`${chalk.cyan('View details:')} ${chalk.yellow(`task-master show ${task.id}`)}`
);
// Display in a styled box with orange border
console.log(
boxen(content.join('\n'), {
padding: 1,
margin: { top: 1, bottom: 1 },
borderStyle: 'round',
borderColor: '#FFA500', // Orange color
title: chalk.hex('#FFA500')('⚡ RECOMMENDED NEXT TASK ⚡'),
titleAlignment: 'center',
width: process.stdout.columns * 0.97,
fullscreen: false
})
);
}
/**
* Get task description from the full task object
*/
export function getTaskDescription(task: Task): string | undefined {
// Try to get description from the task
// This could be from task.description or the first line of task.details
if ('description' in task && task.description) {
return task.description as string;
}
if ('details' in task && task.details) {
// Take first sentence or line from details
const details = task.details as string;
const firstLine = details.split('\n')[0];
const firstSentence = firstLine.split('.')[0];
return firstSentence;
}
return undefined;
}

View File

@@ -0,0 +1,31 @@
/**
* @fileoverview Suggested next steps component
* Displays helpful command suggestions at the end of the list
*/
import chalk from 'chalk';
import boxen from 'boxen';
/**
* Display suggested next steps section
*/
export function displaySuggestedNextSteps(): void {
const steps = [
`${chalk.cyan('1.')} Run ${chalk.yellow('task-master next')} to see what to work on next`,
`${chalk.cyan('2.')} Run ${chalk.yellow('task-master expand --id=<id>')} to break down a task into subtasks`,
`${chalk.cyan('3.')} Run ${chalk.yellow('task-master set-status --id=<id> --status=done')} to mark a task as complete`
];
console.log(
boxen(
chalk.white.bold('Suggested Next Steps:') + '\n\n' + steps.join('\n'),
{
padding: 1,
margin: { top: 0, bottom: 1 },
borderStyle: 'round',
borderColor: 'gray',
width: process.stdout.columns * 0.97
}
)
);
}

View File

@@ -0,0 +1,264 @@
/**
* @fileoverview Task detail component for show command
* Displays detailed task information in a structured format
*/
import chalk from 'chalk';
import boxen from 'boxen';
import Table from 'cli-table3';
import { marked, MarkedExtension } from 'marked';
import { markedTerminal } from 'marked-terminal';
import type { Task } from '@tm/core/types';
import { getStatusWithColor, getPriorityWithColor } from '../../utils/ui.js';
// Configure marked to use terminal renderer with subtle colors
marked.use(
markedTerminal({
// More subtle colors that match the overall design
code: (code: string) => {
// Custom code block handler to preserve formatting
return code
.split('\n')
.map((line) => ' ' + chalk.cyan(line))
.join('\n');
},
blockquote: chalk.gray.italic,
html: chalk.gray,
heading: chalk.white.bold, // White bold for headings
hr: chalk.gray,
listitem: chalk.white, // White for list items
paragraph: chalk.white, // White for paragraphs (default text color)
strong: chalk.white.bold, // White bold for strong text
em: chalk.white.italic, // White italic for emphasis
codespan: chalk.cyan, // Cyan for inline code (no background)
del: chalk.dim.strikethrough,
link: chalk.blue,
href: chalk.blue.underline,
// Add more explicit code block handling
showSectionPrefix: false,
unescape: true,
emoji: false,
// Try to preserve whitespace in code blocks
tab: 4,
width: 120
}) as MarkedExtension
);
// Also set marked options to preserve whitespace
marked.setOptions({
breaks: true,
gfm: true
});
/**
* Display the task header with tag
*/
export function displayTaskHeader(
taskId: string | number,
title: string
): void {
// Display task header box
console.log(
boxen(chalk.white.bold(`Task: #${taskId} - ${title}`), {
padding: { top: 0, bottom: 0, left: 1, right: 1 },
borderColor: 'blue',
borderStyle: 'round'
})
);
}
/**
* Display task properties in a table format
*/
export function displayTaskProperties(task: Task): void {
const terminalWidth = process.stdout.columns * 0.95 || 100;
// Create table for task properties - simple 2-column layout
const table = new Table({
head: [],
style: {
head: [],
border: ['grey']
},
colWidths: [
Math.floor(terminalWidth * 0.2),
Math.floor(terminalWidth * 0.8)
],
wordWrap: true
});
const deps =
task.dependencies && task.dependencies.length > 0
? task.dependencies.map((d) => String(d)).join(', ')
: 'None';
// Build the left column (labels) and right column (values)
const labels = [
chalk.cyan('ID:'),
chalk.cyan('Title:'),
chalk.cyan('Status:'),
chalk.cyan('Priority:'),
chalk.cyan('Dependencies:'),
chalk.cyan('Complexity:'),
chalk.cyan('Description:')
].join('\n');
const values = [
String(task.id),
task.title,
getStatusWithColor(task.status),
getPriorityWithColor(task.priority),
deps,
'N/A',
task.description || ''
].join('\n');
table.push([labels, values]);
console.log(table.toString());
}
/**
* Display implementation details in a box
*/
export function displayImplementationDetails(details: string): void {
// Handle all escaped characters properly
const cleanDetails = details
.replace(/\\n/g, '\n') // Convert \n to actual newlines
.replace(/\\t/g, '\t') // Convert \t to actual tabs
.replace(/\\"/g, '"') // Convert \" to actual quotes
.replace(/\\\\/g, '\\'); // Convert \\ to single backslash
const terminalWidth = process.stdout.columns * 0.95 || 100;
// Parse markdown to terminal-friendly format
const markdownResult = marked(cleanDetails);
const formattedDetails =
typeof markdownResult === 'string' ? markdownResult.trim() : cleanDetails; // Fallback to original if Promise
console.log(
boxen(
chalk.white.bold('Implementation Details:') + '\n\n' + formattedDetails,
{
padding: 1,
borderStyle: 'round',
borderColor: 'cyan', // Changed to cyan to match the original
width: terminalWidth // Fixed width to match the original
}
)
);
}
/**
* Display test strategy in a box
*/
export function displayTestStrategy(testStrategy: string): void {
// Handle all escaped characters properly (same as implementation details)
const cleanStrategy = testStrategy
.replace(/\\n/g, '\n') // Convert \n to actual newlines
.replace(/\\t/g, '\t') // Convert \t to actual tabs
.replace(/\\"/g, '"') // Convert \" to actual quotes
.replace(/\\\\/g, '\\'); // Convert \\ to single backslash
const terminalWidth = process.stdout.columns * 0.95 || 100;
// Parse markdown to terminal-friendly format (same as implementation details)
const markdownResult = marked(cleanStrategy);
const formattedStrategy =
typeof markdownResult === 'string' ? markdownResult.trim() : cleanStrategy; // Fallback to original if Promise
console.log(
boxen(chalk.white.bold('Test Strategy:') + '\n\n' + formattedStrategy, {
padding: 1,
borderStyle: 'round',
borderColor: 'cyan', // Changed to cyan to match implementation details
width: terminalWidth
})
);
}
/**
* Display subtasks in a table format
*/
export function displaySubtasks(
subtasks: Array<{
id: string | number;
title: string;
status: any;
description?: string;
dependencies?: string[];
}>,
parentId: string | number
): void {
const terminalWidth = process.stdout.columns * 0.95 || 100;
// Display subtasks header
console.log(
boxen(chalk.magenta.bold('Subtasks'), {
padding: { top: 0, bottom: 0, left: 1, right: 1 },
borderColor: 'magenta',
borderStyle: 'round',
margin: { top: 1, bottom: 0 }
})
);
// Create subtasks table
const table = new Table({
head: [
chalk.magenta.bold('ID'),
chalk.magenta.bold('Status'),
chalk.magenta.bold('Title'),
chalk.magenta.bold('Deps')
],
style: {
head: [],
border: ['grey']
},
colWidths: [
Math.floor(terminalWidth * 0.1),
Math.floor(terminalWidth * 0.15),
Math.floor(terminalWidth * 0.6),
Math.floor(terminalWidth * 0.15)
],
wordWrap: true
});
subtasks.forEach((subtask) => {
const subtaskId = `${parentId}.${subtask.id}`;
// Format dependencies
const deps =
subtask.dependencies && subtask.dependencies.length > 0
? subtask.dependencies.join(', ')
: 'None';
table.push([
subtaskId,
getStatusWithColor(subtask.status),
subtask.title,
deps
]);
});
console.log(table.toString());
}
/**
* Display suggested actions
*/
export function displaySuggestedActions(taskId: string | number): void {
console.log(
boxen(
chalk.white.bold('Suggested Actions:') +
'\n\n' +
`${chalk.cyan('1.')} Run ${chalk.yellow(`task-master set-status --id=${taskId} --status=in-progress`)} to start working\n` +
`${chalk.cyan('2.')} Run ${chalk.yellow(`task-master expand --id=${taskId}`)} to break down into subtasks\n` +
`${chalk.cyan('3.')} Run ${chalk.yellow(`task-master update-task --id=${taskId} --prompt="..."`)} to update details`,
{
padding: 1,
margin: { top: 1 },
borderStyle: 'round',
borderColor: 'green',
width: process.stdout.columns * 0.95 || 100
}
)
);
}

9
apps/cli/src/ui/index.ts Normal file
View File

@@ -0,0 +1,9 @@
/**
* @fileoverview Main UI exports
*/
// Export all components
export * from './components/index.js';
// Re-export existing UI utilities
export * from '../utils/ui.js';

362
apps/cli/src/utils/ui.ts Normal file
View File

@@ -0,0 +1,362 @@
/**
* @fileoverview UI utilities for Task Master CLI
* Provides formatting, display, and visual components for the command line interface
*/
import chalk from 'chalk';
import boxen from 'boxen';
import Table from 'cli-table3';
import type { Task, TaskStatus, TaskPriority } from '@tm/core/types';
/**
* Get colored status display with ASCII icons (matches scripts/modules/ui.js style)
*/
export function getStatusWithColor(
status: TaskStatus,
forTable: boolean = false
): string {
const statusConfig = {
done: {
color: chalk.green,
icon: '✓',
tableIcon: '✓'
},
pending: {
color: chalk.yellow,
icon: '○',
tableIcon: '○'
},
'in-progress': {
color: chalk.hex('#FFA500'),
icon: '▶',
tableIcon: '▶'
},
deferred: {
color: chalk.gray,
icon: 'x',
tableIcon: 'x'
},
review: {
color: chalk.magenta,
icon: '?',
tableIcon: '?'
},
cancelled: {
color: chalk.gray,
icon: 'x',
tableIcon: 'x'
},
blocked: {
color: chalk.red,
icon: '!',
tableIcon: '!'
},
completed: {
color: chalk.green,
icon: '✓',
tableIcon: '✓'
}
};
const config = statusConfig[status] || {
color: chalk.red,
icon: 'X',
tableIcon: 'X'
};
const icon = forTable ? config.tableIcon : config.icon;
return config.color(`${icon} ${status}`);
}
/**
* Get colored priority display
*/
export function getPriorityWithColor(priority: TaskPriority): string {
const priorityColors: Record<TaskPriority, (text: string) => string> = {
critical: chalk.red.bold,
high: chalk.red,
medium: chalk.yellow,
low: chalk.gray
};
const colorFn = priorityColors[priority] || chalk.white;
return colorFn(priority);
}
/**
* Get colored complexity display
*/
export function getComplexityWithColor(complexity: number | string): string {
const score =
typeof complexity === 'string' ? parseInt(complexity, 10) : complexity;
if (isNaN(score)) {
return chalk.gray('N/A');
}
if (score >= 8) {
return chalk.red.bold(`${score} (High)`);
} else if (score >= 5) {
return chalk.yellow(`${score} (Medium)`);
} else {
return chalk.green(`${score} (Low)`);
}
}
/**
* Truncate text to specified length
*/
export function truncate(text: string, maxLength: number): string {
if (text.length <= maxLength) {
return text;
}
return text.substring(0, maxLength - 3) + '...';
}
/**
* Create a progress bar
*/
export function createProgressBar(
completed: number,
total: number,
width: number = 30
): string {
if (total === 0) {
return chalk.gray('No tasks');
}
const percentage = Math.round((completed / total) * 100);
const filled = Math.round((completed / total) * width);
const empty = width - filled;
const bar = chalk.green('█').repeat(filled) + chalk.gray('░').repeat(empty);
return `${bar} ${chalk.cyan(`${percentage}%`)} (${completed}/${total})`;
}
/**
* Display a fancy banner
*/
export function displayBanner(title: string = 'Task Master'): void {
console.log(
boxen(chalk.white.bold(title), {
padding: 1,
margin: { top: 1, bottom: 1 },
borderStyle: 'round',
borderColor: 'blue',
textAlignment: 'center'
})
);
}
/**
* Display an error message (matches scripts/modules/ui.js style)
*/
export function displayError(message: string, details?: string): void {
console.error(
boxen(
chalk.red.bold('X Error: ') +
chalk.white(message) +
(details ? '\n\n' + chalk.gray(details) : ''),
{
padding: 1,
borderStyle: 'round',
borderColor: 'red'
}
)
);
}
/**
* Display a success message
*/
export function displaySuccess(message: string): void {
console.log(
boxen(
chalk.green.bold(String.fromCharCode(8730) + ' ') + chalk.white(message),
{
padding: 1,
borderStyle: 'round',
borderColor: 'green'
}
)
);
}
/**
* Display a warning message
*/
export function displayWarning(message: string): void {
console.log(
boxen(chalk.yellow.bold('⚠ ') + chalk.white(message), {
padding: 1,
borderStyle: 'round',
borderColor: 'yellow'
})
);
}
/**
* Display info message
*/
export function displayInfo(message: string): void {
console.log(
boxen(chalk.blue.bold('i ') + chalk.white(message), {
padding: 1,
borderStyle: 'round',
borderColor: 'blue'
})
);
}
/**
* Format dependencies with their status
*/
export function formatDependenciesWithStatus(
dependencies: string[] | number[],
tasks: Task[]
): string {
if (!dependencies || dependencies.length === 0) {
return chalk.gray('none');
}
const taskMap = new Map(tasks.map((t) => [t.id.toString(), t]));
return dependencies
.map((depId) => {
const task = taskMap.get(depId.toString());
if (!task) {
return chalk.red(`${depId} (not found)`);
}
const statusIcon =
task.status === 'done'
? '✓'
: task.status === 'in-progress'
? '►'
: '○';
return `${depId}${statusIcon}`;
})
.join(', ');
}
/**
* Create a task table for display
*/
export function createTaskTable(
tasks: Task[],
options?: {
showSubtasks?: boolean;
showComplexity?: boolean;
showDependencies?: boolean;
}
): string {
const {
showSubtasks = false,
showComplexity = false,
showDependencies = true
} = options || {};
// Calculate dynamic column widths based on terminal width
const terminalWidth = process.stdout.columns * 0.9 || 100;
// Adjust column widths to better match the original layout
const baseColWidths = showComplexity
? [
Math.floor(terminalWidth * 0.06),
Math.floor(terminalWidth * 0.4),
Math.floor(terminalWidth * 0.15),
Math.floor(terminalWidth * 0.12),
Math.floor(terminalWidth * 0.2),
Math.floor(terminalWidth * 0.12)
] // ID, Title, Status, Priority, Dependencies, Complexity
: [
Math.floor(terminalWidth * 0.08),
Math.floor(terminalWidth * 0.4),
Math.floor(terminalWidth * 0.18),
Math.floor(terminalWidth * 0.12),
Math.floor(terminalWidth * 0.2)
]; // ID, Title, Status, Priority, Dependencies
const headers = [
chalk.blue.bold('ID'),
chalk.blue.bold('Title'),
chalk.blue.bold('Status'),
chalk.blue.bold('Priority')
];
const colWidths = baseColWidths.slice(0, 4);
if (showDependencies) {
headers.push(chalk.blue.bold('Dependencies'));
colWidths.push(baseColWidths[4]);
}
if (showComplexity) {
headers.push(chalk.blue.bold('Complexity'));
colWidths.push(baseColWidths[5] || 12);
}
const table = new Table({
head: headers,
style: { head: [], border: [] },
colWidths,
wordWrap: true
});
tasks.forEach((task) => {
const row: string[] = [
chalk.cyan(task.id.toString()),
truncate(task.title, colWidths[1] - 3),
getStatusWithColor(task.status, true), // Use table version
getPriorityWithColor(task.priority)
];
if (showDependencies) {
// For table display, show simple format without status icons
if (!task.dependencies || task.dependencies.length === 0) {
row.push(chalk.gray('None'));
} else {
row.push(
chalk.cyan(task.dependencies.map((d) => String(d)).join(', '))
);
}
}
if (showComplexity) {
// Show N/A if no complexity score
row.push(chalk.gray('N/A'));
}
table.push(row);
// Add subtasks if requested
if (showSubtasks && task.subtasks && task.subtasks.length > 0) {
task.subtasks.forEach((subtask) => {
const subRow: string[] = [
chalk.gray(` └─ ${subtask.id}`),
chalk.gray(truncate(subtask.title, colWidths[1] - 6)),
chalk.gray(getStatusWithColor(subtask.status, true)),
chalk.gray(subtask.priority || 'medium')
];
if (showDependencies) {
subRow.push(
chalk.gray(
subtask.dependencies && subtask.dependencies.length > 0
? subtask.dependencies.map((dep) => String(dep)).join(', ')
: 'None'
)
);
}
if (showComplexity) {
subRow.push(chalk.gray('--'));
}
table.push(subRow);
});
}
});
return table.toString();
}

36
apps/cli/tsconfig.json Normal file
View File

@@ -0,0 +1,36 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"lib": ["ES2022"],
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"baseUrl": ".",
"rootDir": "./src",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "NodeNext",
"moduleDetection": "force",
"types": ["node"],
"resolveJsonModule": true,
"isolatedModules": true,
"allowImportingTsExtensions": false
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "tests", "**/*.test.ts", "**/*.spec.ts"]
}

5
apps/docs/CHANGELOG.md Normal file
View File

@@ -0,0 +1,5 @@
# docs
## 0.0.2
## 0.0.1

22
apps/docs/README.md Normal file
View File

@@ -0,0 +1,22 @@
# Task Master Documentation
Welcome to the Task Master documentation. Use the links below to navigate to the information you need:
## Getting Started
- [Configuration Guide](archive/configuration.md) - Set up environment variables and customize Task Master
- [Tutorial](archive/ctutorial.md) - Step-by-step guide to getting started with Task Master
## Reference
- [Command Reference](archive/ccommand-reference.md) - Complete list of all available commands
- [Task Structure](archive/ctask-structure.md) - Understanding the task format and features
## Examples & Licensing
- [Example Interactions](archive/cexamples.md) - Common Cursor AI interaction examples
- [Licensing Information](archive/clicensing.md) - Detailed information about the license
## Need More Help?
If you can't find what you're looking for in these docs, please check the [main README](../README.md) or visit our [GitHub repository](https://github.com/eyaltoledano/claude-task-master).

View File

@@ -0,0 +1,114 @@
---
title: "Installation(2)"
description: "This guide walks you through setting up Task Master in your development environment."
---
## Initial Setup
<Tip>
MCP (Model Control Protocol) provides the easiest way to get started with Task Master directly in your editor.
</Tip>
<AccordionGroup>
<Accordion title="Option 1: Using MCP (Recommended)" icon="sparkles">
<Steps>
<Step title="Add the MCP config to your editor">
<Link href="https://cursor.sh">Cursor</Link> recommended, but it works with other text editors
```json
{
"mcpServers": {
"taskmaster-ai": {
"command": "npx",
"args": ["-y", "--package", "task-master-ai", "task-master-mcp"],
"env": {
"ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY_HERE",
"PERPLEXITY_API_KEY": "YOUR_PERPLEXITY_API_KEY_HERE",
"MODEL": "claude-3-7-sonnet-20250219",
"PERPLEXITY_MODEL": "sonar-pro",
"MAX_TOKENS": 128000,
"TEMPERATURE": 0.2,
"DEFAULT_SUBTASKS": 5,
"DEFAULT_PRIORITY": "medium"
}
}
}
}
```
</Step>
<Step title="Enable the MCP in your editor settings">
</Step>
<Step title="Prompt the AI to initialize Task Master">
> "Can you please initialize taskmaster-ai into my project?"
**The AI will:**
1. Create necessary project structure
2. Set up initial configuration files
3. Guide you through the rest of the process
4. Place your PRD document in the `scripts/` directory (e.g., `scripts/prd.txt`)
5. **Use natural language commands** to interact with Task Master:
> "Can you parse my PRD at scripts/prd.txt?"
>
> "What's the next task I should work on?"
>
> "Can you help me implement task 3?"
</Step>
</Steps>
</Accordion>
<Accordion title="Option 2: Manual Installation">
If you prefer to use the command line interface directly:
<Steps>
<Step title="Install">
<CodeGroup>
```bash Global
npm install -g task-master-ai
```
```bash Local
npm install task-master-ai
```
</CodeGroup>
</Step>
<Step title="Initialize a new project">
<CodeGroup>
```bash Global
task-master init
```
```bash Local
npx task-master-init
```
</CodeGroup>
</Step>
</Steps>
This will prompt you for project details and set up a new project with the necessary files and structure.
</Accordion>
</AccordionGroup>
## Common Commands
<Tip>
After setting up Task Master, you can use these commands (either via AI prompts or CLI)
</Tip>
```bash
# Parse a PRD and generate tasks
task-master parse-prd your-prd.txt
# List all tasks
task-master list
# Show the next task to work on
task-master next
# Generate task files
task-master generate

View File

@@ -0,0 +1,263 @@
---
title: "AI Client Utilities for MCP Tools"
description: "This document provides examples of how to use the new AI client utilities with AsyncOperationManager in MCP tools."
---
## Examples
<AccordionGroup>
<Accordion title="Basic Usage with Direct Functions">
```javascript
// In your direct function implementation:
import {
getAnthropicClientForMCP,
getModelConfig,
handleClaudeError
} from '../utils/ai-client-utils.js';
export async function someAiOperationDirect(args, log, context) {
try {
// Initialize Anthropic client with session from context
const client = getAnthropicClientForMCP(context.session, log);
// Get model configuration with defaults or session overrides
const modelConfig = getModelConfig(context.session);
// Make API call with proper error handling
try {
const response = await client.messages.create({
model: modelConfig.model,
max_tokens: modelConfig.maxTokens,
temperature: modelConfig.temperature,
messages: [{ role: 'user', content: 'Your prompt here' }]
});
return {
success: true,
data: response
};
} catch (apiError) {
// Use helper to get user-friendly error message
const friendlyMessage = handleClaudeError(apiError);
return {
success: false,
error: {
code: 'AI_API_ERROR',
message: friendlyMessage
}
};
}
} catch (error) {
// Handle client initialization errors
return {
success: false,
error: {
code: 'AI_CLIENT_ERROR',
message: error.message
}
};
}
}
```
</Accordion>
<Accordion title="Integration with AsyncOperationManager">
```javascript
// In your MCP tool implementation:
import {
AsyncOperationManager,
StatusCodes
} from '../../utils/async-operation-manager.js';
import { someAiOperationDirect } from '../../core/direct-functions/some-ai-operation.js';
export async function someAiOperation(args, context) {
const { session, mcpLog } = context;
const log = mcpLog || console;
try {
// Create operation description
const operationDescription = `AI operation: ${args.someParam}`;
// Start async operation
const operation = AsyncOperationManager.createOperation(
operationDescription,
async (reportProgress) => {
try {
// Initial progress report
reportProgress({
progress: 0,
status: 'Starting AI operation...'
});
// Call direct function with session and progress reporting
const result = await someAiOperationDirect(args, log, {
reportProgress,
mcpLog: log,
session
});
// Final progress update
reportProgress({
progress: 100,
status: result.success ? 'Operation completed' : 'Operation failed',
result: result.data,
error: result.error
});
return result;
} catch (error) {
// Handle errors in the operation
reportProgress({
progress: 100,
status: 'Operation failed',
error: {
message: error.message,
code: error.code || 'OPERATION_FAILED'
}
});
throw error;
}
}
);
// Return immediate response with operation ID
return {
status: StatusCodes.ACCEPTED,
body: {
success: true,
message: 'Operation started',
operationId: operation.id
}
};
} catch (error) {
// Handle errors in the MCP tool
log.error(`Error in someAiOperation: ${error.message}`);
return {
status: StatusCodes.INTERNAL_SERVER_ERROR,
body: {
success: false,
error: {
code: 'OPERATION_FAILED',
message: error.message
}
}
};
}
}
```
</Accordion>
<Accordion title="Using Research Capabilities with Perplexity">
```javascript
// In your direct function:
import {
getPerplexityClientForMCP,
getBestAvailableAIModel
} from '../utils/ai-client-utils.js';
export async function researchOperationDirect(args, log, context) {
try {
// Get the best AI model for this operation based on needs
const { type, client } = await getBestAvailableAIModel(
context.session,
{ requiresResearch: true },
log
);
// Report which model we're using
if (context.reportProgress) {
await context.reportProgress({
progress: 10,
status: `Using ${type} model for research...`
});
}
// Make API call based on the model type
if (type === 'perplexity') {
// Call Perplexity
const response = await client.chat.completions.create({
model: context.session?.env?.PERPLEXITY_MODEL || 'sonar-medium-online',
messages: [{ role: 'user', content: args.researchQuery }],
temperature: 0.1
});
return {
success: true,
data: response.choices[0].message.content
};
} else {
// Call Claude as fallback
// (Implementation depends on specific needs)
// ...
}
} catch (error) {
// Handle errors
return {
success: false,
error: {
code: 'RESEARCH_ERROR',
message: error.message
}
};
}
}
```
</Accordion>
<Accordion title="Model Configuration Override">
```javascript
// In your direct function:
import { getModelConfig } from '../utils/ai-client-utils.js';
// Using custom defaults for a specific operation
const operationDefaults = {
model: 'claude-3-haiku-20240307', // Faster, smaller model
maxTokens: 1000, // Lower token limit
temperature: 0.2 // Lower temperature for more deterministic output
};
// Get model config with operation-specific defaults
const modelConfig = getModelConfig(context.session, operationDefaults);
// Now use modelConfig in your API calls
const response = await client.messages.create({
model: modelConfig.model,
max_tokens: modelConfig.maxTokens,
temperature: modelConfig.temperature
// Other parameters...
});
```
</Accordion>
</AccordionGroup>
## Best Practices
<AccordionGroup>
<Accordion title="Error Handling">
- Always use try/catch blocks around both client initialization and API calls
- Use `handleClaudeError` to provide user-friendly error messages
- Return standardized error objects with code and message
</Accordion>
<Accordion title="Progress Reporting">
- Report progress at key points (starting, processing, completing)
- Include meaningful status messages
- Include error details in progress reports when failures occur
</Accordion>
<Accordion title="Session Handling">
- Always pass the session from the context to the AI client getters
- Use `getModelConfig` to respect user settings from session
</Accordion>
<Accordion title="Model Selection">
- Use `getBestAvailableAIModel` when you need to select between different models
- Set `requiresResearch: true` when you need Perplexity capabilities
</Accordion>
<Accordion title="AsyncOperationManager Integration">
- Create descriptive operation names
- Handle all errors within the operation function
- Return standardized results from direct functions
- Return immediate responses with operation IDs
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,180 @@
---
title: "AI Development Workflow"
description: "Learn how Task Master and Cursor AI work together to streamline your development workflow"
---
<Tip>The Cursor agent is pre-configured (via the rules file) to follow this workflow</Tip>
<AccordionGroup>
<Accordion title="1. Task Discovery and Selection">
Ask the agent to list available tasks:
```
What tasks are available to work on next?
```
The agent will:
- Run `task-master list` to see all tasks
- Run `task-master next` to determine the next task to work on
- Analyze dependencies to determine which tasks are ready to be worked on
- Prioritize tasks based on priority level and ID order
- Suggest the next task(s) to implement
</Accordion>
<Accordion title="2. Task Implementation">
When implementing a task, the agent will:
- Reference the task's details section for implementation specifics
- Consider dependencies on previous tasks
- Follow the project's coding standards
- Create appropriate tests based on the task's testStrategy
You can ask:
```
Let's implement task 3. What does it involve?
```
</Accordion>
<Accordion title="3. Task Verification">
Before marking a task as complete, verify it according to:
- The task's specified testStrategy
- Any automated tests in the codebase
- Manual verification if required
</Accordion>
<Accordion title="4. Task Completion">
When a task is completed, tell the agent:
```
Task 3 is now complete. Please update its status.
```
The agent will execute:
```bash
task-master set-status --id=3 --status=done
```
</Accordion>
<Accordion title="5. Handling Implementation Drift">
If during implementation, you discover that:
- The current approach differs significantly from what was planned
- Future tasks need to be modified due to current implementation choices
- New dependencies or requirements have emerged
Tell the agent:
```
We've changed our approach. We're now using Express instead of Fastify. Please update all future tasks to reflect this change.
```
The agent will execute:
```bash
task-master update --from=4 --prompt="Now we are using Express instead of Fastify."
```
This will rewrite or re-scope subsequent tasks in tasks.json while preserving completed work.
</Accordion>
<Accordion title="6. Breaking Down Complex Tasks">
For complex tasks that need more granularity:
```
Task 5 seems complex. Can you break it down into subtasks?
```
The agent will execute:
```bash
task-master expand --id=5 --num=3
```
You can provide additional context:
```
Please break down task 5 with a focus on security considerations.
```
The agent will execute:
```bash
task-master expand --id=5 --prompt="Focus on security aspects"
```
You can also expand all pending tasks:
```
Please break down all pending tasks into subtasks.
```
The agent will execute:
```bash
task-master expand --all
```
For research-backed subtask generation using Perplexity AI:
```
Please break down task 5 using research-backed generation.
```
The agent will execute:
```bash
task-master expand --id=5 --research
```
</Accordion>
</AccordionGroup>
## Example Cursor AI Interactions
<AccordionGroup>
<Accordion title="Starting a new project">
```
I've just initialized a new project with Claude Task Master. I have a PRD at scripts/prd.txt.
Can you help me parse it and set up the initial tasks?
```
</Accordion>
<Accordion title="Working on tasks">
```
What's the next task I should work on? Please consider dependencies and priorities.
```
</Accordion>
<Accordion title="Implementing a specific task">
```
I'd like to implement task 4. Can you help me understand what needs to be done and how to approach it?
```
</Accordion>
<Accordion title="Managing subtasks">
```
I need to regenerate the subtasks for task 3 with a different approach. Can you help me clear and regenerate them?
```
</Accordion>
<Accordion title="Handling changes">
```
We've decided to use MongoDB instead of PostgreSQL. Can you update all future tasks to reflect this change?
```
</Accordion>
<Accordion title="Completing work">
```
I've finished implementing the authentication system described in task 2. All tests are passing.
Please mark it as complete and tell me what I should work on next.
```
</Accordion>
<Accordion title="Analyzing complexity">
```
Can you analyze the complexity of our tasks to help me understand which ones need to be broken down further?
```
</Accordion>
<Accordion title="Viewing complexity report">
```
Can you show me the complexity report in a more readable format?
```
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,208 @@
---
title: "Task Master Commands"
description: "A comprehensive reference of all available Task Master commands"
---
<AccordionGroup>
<Accordion title="Parse PRD">
```bash
# Parse a PRD file and generate tasks
task-master parse-prd <prd-file.txt>
# Limit the number of tasks generated
task-master parse-prd <prd-file.txt> --num-tasks=10
```
</Accordion>
<Accordion title="List Tasks">
```bash
# List all tasks
task-master list
# List tasks with a specific status
task-master list --status=<status>
# List tasks with subtasks
task-master list --with-subtasks
# List tasks with a specific status and include subtasks
task-master list --status=<status> --with-subtasks
```
</Accordion>
<Accordion title="Show Next Task">
```bash
# Show the next task to work on based on dependencies and status
task-master next
```
</Accordion>
<Accordion title="Show Specific Task">
```bash
# Show details of a specific task
task-master show <id>
# or
task-master show --id=<id>
# View a specific subtask (e.g., subtask 2 of task 1)
task-master show 1.2
```
</Accordion>
<Accordion title="Update Tasks">
```bash
# Update tasks from a specific ID and provide context
task-master update --from=<id> --prompt="<prompt>"
```
</Accordion>
<Accordion title="Update a Specific Task">
```bash
# Update a single task by ID with new information
task-master update-task --id=<id> --prompt="<prompt>"
# Use research-backed updates with Perplexity AI
task-master update-task --id=<id> --prompt="<prompt>" --research
```
</Accordion>
<Accordion title="Update a Subtask">
```bash
# Append additional information to a specific subtask
task-master update-subtask --id=<parentId.subtaskId> --prompt="<prompt>"
# Example: Add details about API rate limiting to subtask 2 of task 5
task-master update-subtask --id=5.2 --prompt="Add rate limiting of 100 requests per minute"
# Use research-backed updates with Perplexity AI
task-master update-subtask --id=<parentId.subtaskId> --prompt="<prompt>" --research
```
Unlike the `update-task` command which replaces task information, the `update-subtask` command _appends_ new information to the existing subtask details, marking it with a timestamp. This is useful for iteratively enhancing subtasks while preserving the original content.
</Accordion>
<Accordion title="Generate Task Files">
```bash
# Generate individual task files from tasks.json
task-master generate
```
</Accordion>
<Accordion title="Set Task Status">
```bash
# Set status of a single task
task-master set-status --id=<id> --status=<status>
# Set status for multiple tasks
task-master set-status --id=1,2,3 --status=<status>
# Set status for subtasks
task-master set-status --id=1.1,1.2 --status=<status>
```
When marking a task as "done", all of its subtasks will automatically be marked as "done" as well.
</Accordion>
<Accordion title="Expand Tasks">
```bash
# Expand a specific task with subtasks
task-master expand --id=<id> --num=<number>
# Expand with additional context
task-master expand --id=<id> --prompt="<context>"
# Expand all pending tasks
task-master expand --all
# Force regeneration of subtasks for tasks that already have them
task-master expand --all --force
# Research-backed subtask generation for a specific task
task-master expand --id=<id> --research
# Research-backed generation for all tasks
task-master expand --all --research
```
</Accordion>
<Accordion title="Clear Subtasks">
```bash
# Clear subtasks from a specific task
task-master clear-subtasks --id=<id>
# Clear subtasks from multiple tasks
task-master clear-subtasks --id=1,2,3
# Clear subtasks from all tasks
task-master clear-subtasks --all
```
</Accordion>
<Accordion title="Analyze Task Complexity">
```bash
# Analyze complexity of all tasks
task-master analyze-complexity
# Save report to a custom location
task-master analyze-complexity --output=my-report.json
# Use a specific LLM model
task-master analyze-complexity --model=claude-3-opus-20240229
# Set a custom complexity threshold (1-10)
task-master analyze-complexity --threshold=6
# Use an alternative tasks file
task-master analyze-complexity --file=custom-tasks.json
# Use Perplexity AI for research-backed complexity analysis
task-master analyze-complexity --research
```
</Accordion>
<Accordion title="View Complexity Report">
```bash
# Display the task complexity analysis report
task-master complexity-report
# View a report at a custom location
task-master complexity-report --file=my-report.json
```
</Accordion>
<Accordion title="Managing Task Dependencies">
```bash
# Add a dependency to a task
task-master add-dependency --id=<id> --depends-on=<id>
# Remove a dependency from a task
task-master remove-dependency --id=<id> --depends-on=<id>
# Validate dependencies without fixing them
task-master validate-dependencies
# Find and fix invalid dependencies automatically
task-master fix-dependencies
```
</Accordion>
<Accordion title="Add a New Task">
```bash
# Add a new task using AI
task-master add-task --prompt="Description of the new task"
# Add a task with dependencies
task-master add-task --prompt="Description" --dependencies=1,2,3
# Add a task with priority
task-master add-task --prompt="Description" --priority=high
```
</Accordion>
<Accordion title="Initialize a Project">
```bash
# Initialize a new project with Task Master structure
task-master init
```
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,80 @@
---
title: "Configuration"
description: "Configure Task Master through environment variables in a .env file"
---
## Required Configuration
<Note>
Task Master requires an Anthropic API key to function. Add this to your `.env` file:
```bash
ANTHROPIC_API_KEY=sk-ant-api03-your-api-key
```
You can obtain an API key from the [Anthropic Console](https://console.anthropic.com/).
</Note>
## Optional Configuration
| Variable | Default Value | Description | Example |
| --- | --- | --- | --- |
| `MODEL` | `"claude-3-7-sonnet-20250219"` | Claude model to use | `MODEL=claude-3-opus-20240229` |
| `MAX_TOKENS` | `"4000"` | Maximum tokens for responses | `MAX_TOKENS=8000` |
| `TEMPERATURE` | `"0.7"` | Temperature for model responses | `TEMPERATURE=0.5` |
| `DEBUG` | `"false"` | Enable debug logging | `DEBUG=true` |
| `LOG_LEVEL` | `"info"` | Console output level | `LOG_LEVEL=debug` |
| `DEFAULT_SUBTASKS` | `"3"` | Default subtask count | `DEFAULT_SUBTASKS=5` |
| `DEFAULT_PRIORITY` | `"medium"` | Default priority | `DEFAULT_PRIORITY=high` |
| `PROJECT_NAME` | `"MCP SaaS MVP"` | Project name in metadata | `PROJECT_NAME=My Awesome Project` |
| `PROJECT_VERSION` | `"1.0.0"` | Version in metadata | `PROJECT_VERSION=2.1.0` |
| `PERPLEXITY_API_KEY` | - | For research-backed features | `PERPLEXITY_API_KEY=pplx-...` |
| `PERPLEXITY_MODEL` | `"sonar-medium-online"` | Perplexity model | `PERPLEXITY_MODEL=sonar-large-online` |
## Example .env File
```
# Required
ANTHROPIC_API_KEY=sk-ant-api03-your-api-key
# Optional - Claude Configuration
MODEL=claude-3-7-sonnet-20250219
MAX_TOKENS=4000
TEMPERATURE=0.7
# Optional - Perplexity API for Research
PERPLEXITY_API_KEY=pplx-your-api-key
PERPLEXITY_MODEL=sonar-medium-online
# Optional - Project Info
PROJECT_NAME=My Project
PROJECT_VERSION=1.0.0
# Optional - Application Configuration
DEFAULT_SUBTASKS=3
DEFAULT_PRIORITY=medium
DEBUG=false
LOG_LEVEL=info
```
## Troubleshooting
### If `task-master init` doesn't respond:
Try running it with Node directly:
```bash
node node_modules/claude-task-master/scripts/init.js
```
Or clone the repository and run:
```bash
git clone https://github.com/eyaltoledano/claude-task-master.git
cd claude-task-master
node scripts/init.js
```
<Note>
For advanced configuration options and detailed customization, see our [Advanced Configuration Guide] page.
</Note>

View File

@@ -0,0 +1,95 @@
---
title: "Cursor AI Integration"
description: "Learn how to set up and use Task Master with Cursor AI"
---
## Setting up Cursor AI Integration
<Check>
Task Master is designed to work seamlessly with [Cursor AI](https://www.cursor.so/), providing a structured workflow for AI-driven development.
</Check>
<AccordionGroup>
<Accordion title="Using Cursor with MCP (Recommended)" icon="sparkles">
If you've already set up Task Master with MCP in Cursor, the integration is automatic. You can simply use natural language to interact with Task Master:
```
What tasks are available to work on next?
Can you analyze the complexity of our tasks?
I'd like to implement task 4. What does it involve?
```
</Accordion>
<Accordion title="Manual Cursor Setup">
If you're not using MCP, you can still set up Cursor integration:
<Steps>
<Step title="After initializing your project, open it in Cursor">
The `.cursor/rules/dev_workflow.mdc` file is automatically loaded by Cursor, providing the AI with knowledge about the task management system
</Step>
<Step title="Place your PRD document in the scripts/ directory (e.g., scripts/prd.txt)">
</Step>
<Step title="Open Cursor's AI chat and switch to Agent mode">
</Step>
</Steps>
</Accordion>
<Accordion title="Alternative MCP Setup in Cursor">
<Steps>
<Step title="Go to Cursor settings">
</Step>
<Step title="Navigate to the MCP section">
</Step>
<Step title="Click on 'Add New MCP Server'">
</Step>
<Step title="Configure with the following details:">
- Name: "Task Master"
- Type: "Command"
- Command: "npx -y --package task-master-ai task-master-mcp"
</Step>
<Step title="Save Settings">
</Step>
</Steps>
Once configured, you can interact with Task Master's task management commands directly through Cursor's interface, providing a more integrated experience.
</Accordion>
</AccordionGroup>
## Initial Task Generation
In Cursor's AI chat, instruct the agent to generate tasks from your PRD:
```
Please use the task-master parse-prd command to generate tasks from my PRD. The PRD is located at scripts/prd.txt.
```
The agent will execute:
```bash
task-master parse-prd scripts/prd.txt
```
This will:
- Parse your PRD document
- Generate a structured `tasks.json` file with tasks, dependencies, priorities, and test strategies
- The agent will understand this process due to the Cursor rules
### Generate Individual Task Files
Next, ask the agent to generate individual task files:
```
Please generate individual task files from tasks.json
```
The agent will execute:
```bash
task-master generate
```
This creates individual task files in the `tasks/` directory (e.g., `task_001.txt`, `task_002.txt`), making it easier to reference specific tasks.

View File

@@ -0,0 +1,56 @@
---
title: "Example Cursor AI Interactions"
description: "Below are some common interactions with Cursor AI when using Task Master"
---
<AccordionGroup>
<Accordion title="Starting a new project">
```
I've just initialized a new project with Claude Task Master. I have a PRD at scripts/prd.txt.
Can you help me parse it and set up the initial tasks?
```
</Accordion>
<Accordion title="Working on tasks">
```
What's the next task I should work on? Please consider dependencies and priorities.
```
</Accordion>
<Accordion title="Implementing a specific task">
```
I'd like to implement task 4. Can you help me understand what needs to be done and how to approach it?
```
</Accordion>
<Accordion title="Managing subtasks">
```
I need to regenerate the subtasks for task 3 with a different approach. Can you help me clear and regenerate them?
```
</Accordion>
<Accordion title="Handling changes">
```
We've decided to use MongoDB instead of PostgreSQL. Can you update all future tasks to reflect this change?
```
</Accordion>
<Accordion title="Completing work">
```
I've finished implementing the authentication system described in task 2. All tests are passing.
Please mark it as complete and tell me what I should work on next.
```
</Accordion>
<Accordion title="Analyzing complexity">
```
Can you analyze the complexity of our tasks to help me understand which ones need to be broken down further?
```
</Accordion>
<Accordion title="Viewing complexity report">
```
Can you show me the complexity report in a more readable format?
```
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,227 @@
---
title: Advanced Tasks
sidebarTitle: "Advanced Tasks"
---
## AI-Driven Development Workflow
The Cursor agent is pre-configured (via the rules file) to follow this workflow:
### 1. Task Discovery and Selection
Ask the agent to list available tasks:
```
What tasks are available to work on next?
```
```
Can you show me tasks 1, 3, and 5 to understand their current status?
```
The agent will:
- Run `task-master list` to see all tasks
- Run `task-master next` to determine the next task to work on
- Run `task-master show 1,3,5` to display multiple tasks with interactive options
- Analyze dependencies to determine which tasks are ready to be worked on
- Prioritize tasks based on priority level and ID order
- Suggest the next task(s) to implement
### 2. Task Implementation
When implementing a task, the agent will:
- Reference the task's details section for implementation specifics
- Consider dependencies on previous tasks
- Follow the project's coding standards
- Create appropriate tests based on the task's testStrategy
You can ask:
```
Let's implement task 3. What does it involve?
```
### 2.1. Viewing Multiple Tasks
For efficient context gathering and batch operations:
```
Show me tasks 5, 7, and 9 so I can plan my implementation approach.
```
The agent will:
- Run `task-master show 5,7,9` to display a compact summary table
- Show task status, priority, and progress indicators
- Provide an interactive action menu with batch operations
- Allow you to perform group actions like marking multiple tasks as in-progress
### 3. Task Verification
Before marking a task as complete, verify it according to:
- The task's specified testStrategy
- Any automated tests in the codebase
- Manual verification if required
### 4. Task Completion
When a task is completed, tell the agent:
```
Task 3 is now complete. Please update its status.
```
The agent will execute:
```bash
task-master set-status --id=3 --status=done
```
### 5. Handling Implementation Drift
If during implementation, you discover that:
- The current approach differs significantly from what was planned
- Future tasks need to be modified due to current implementation choices
- New dependencies or requirements have emerged
Tell the agent:
```
We've decided to use MongoDB instead of PostgreSQL. Can you update all future tasks (from ID 4) to reflect this change?
```
The agent will execute:
```bash
task-master update --from=4 --prompt="Now we are using MongoDB instead of PostgreSQL."
# OR, if research is needed to find best practices for MongoDB:
task-master update --from=4 --prompt="Update to use MongoDB, researching best practices" --research
```
This will rewrite or re-scope subsequent tasks in tasks.json while preserving completed work.
### 6. Reorganizing Tasks
If you need to reorganize your task structure:
```
I think subtask 5.2 would fit better as part of task 7 instead. Can you move it there?
```
The agent will execute:
```bash
task-master move --from=5.2 --to=7.3
```
You can reorganize tasks in various ways:
- Moving a standalone task to become a subtask: `--from=5 --to=7`
- Moving a subtask to become a standalone task: `--from=5.2 --to=7`
- Moving a subtask to a different parent: `--from=5.2 --to=7.3`
- Reordering subtasks within the same parent: `--from=5.2 --to=5.4`
- Moving a task to a new ID position: `--from=5 --to=25` (even if task 25 doesn't exist yet)
- Moving multiple tasks at once: `--from=10,11,12 --to=16,17,18` (must have same number of IDs, Taskmaster will look through each position)
#### Cross-Tag Move Safety (v0.26.0+)
For moves between different tags, use the enhanced dependency handling:
```bash
# Move with all dependencies (safest)
task-master move --from=5 --to=3 --with-dependencies --tag-from=feature --tag-to=main
# Move ignoring dependencies (shows safety tips)
task-master move --from=5 --to=3 --ignore-dependencies --tag-from=feature --tag-to=main
```
**Enhanced Safety Features:**
- **Next Steps Guidance**: After cross-tag moves with `--ignore-dependencies`, the CLI provides "Next Steps" tips with validation and fix guidance
- **ID Collision Help**: Dedicated help blocks appear when destination tags already have the target ID, with structured suggestions
- **Better Error Messages**: Task collision errors now include actionable suggestions for resolution
When moving tasks to new IDs:
- The system automatically creates placeholder tasks for non-existent destination IDs
- This prevents accidental data loss during reorganization
- Any tasks that depend on moved tasks will have their dependencies updated
- When moving a parent task, all its subtasks are automatically moved with it and renumbered
This is particularly useful as your project understanding evolves and you need to refine your task structure.
### 7. Resolving Merge Conflicts with Tasks
When working with a team, you might encounter merge conflicts in your tasks.json file if multiple team members create tasks on different branches. The move command makes resolving these conflicts straightforward:
```
I just merged the main branch and there's a conflict with tasks.json. My teammates created tasks 10-15 while I created tasks 10-12 on my branch. Can you help me resolve this?
```
The agent will help you:
1. Keep your teammates' tasks (10-15)
2. Move your tasks to new positions to avoid conflicts:
```bash
# Move your tasks to new positions (e.g., 16-18)
task-master move --from=10 --to=16
task-master move --from=11 --to=17
task-master move --from=12 --to=18
```
This approach preserves everyone's work while maintaining a clean task structure, making it much easier to handle task conflicts than trying to manually merge JSON files.
### 8. Breaking Down Complex Tasks
For complex tasks that need more granularity:
```
Task 5 seems complex. Can you break it down into subtasks?
```
The agent will execute:
```bash
task-master expand --id=5 --num=3
```
You can provide additional context:
```
Please break down task 5 with a focus on security considerations.
```
The agent will execute:
```bash
task-master expand --id=5 --prompt="Focus on security aspects"
```
You can also expand all pending tasks:
```
Please break down all pending tasks into subtasks.
```
The agent will execute:
```bash
task-master expand --all
```
For research-backed subtask generation using the configured research model:
```
Please break down task 5 using research-backed generation.
```
The agent will execute:
```bash
task-master expand --id=5 --research
```

View File

@@ -0,0 +1,351 @@
---
title: Advanced Configuration
sidebarTitle: "Advanced Configuration"
---
Taskmaster uses two primary methods for configuration:
1. **`.taskmaster/config.json` File (Recommended - New Structure)**
- This JSON file stores most configuration settings, including AI model selections, parameters, logging levels, and project defaults.
- **Location:** This file is created in the `.taskmaster/` directory when you run the `task-master models --setup` interactive setup or initialize a new project with `task-master init`.
- **Migration:** Existing projects with `.taskmasterconfig` in the root will continue to work, but should be migrated to the new structure using `task-master migrate`.
- **Management:** Use the `task-master models --setup` command (or `models` MCP tool) to interactively create and manage this file. You can also set specific models directly using `task-master models --set-<role>=<model_id>`, adding `--ollama` or `--openrouter` flags for custom models. Manual editing is possible but not recommended unless you understand the structure.
- **Example Structure:**
```json
{
"models": {
"main": {
"provider": "anthropic",
"modelId": "claude-3-7-sonnet-20250219",
"maxTokens": 64000,
"temperature": 0.2,
"baseURL": "https://api.anthropic.com/v1"
},
"research": {
"provider": "perplexity",
"modelId": "sonar-pro",
"maxTokens": 8700,
"temperature": 0.1,
"baseURL": "https://api.perplexity.ai/v1"
},
"fallback": {
"provider": "anthropic",
"modelId": "claude-3-5-sonnet",
"maxTokens": 64000,
"temperature": 0.2
}
},
"global": {
"logLevel": "info",
"debug": false,
"defaultSubtasks": 5,
"defaultPriority": "medium",
"defaultTag": "master",
"projectName": "Your Project Name",
"ollamaBaseURL": "http://localhost:11434/api",
"azureBaseURL": "https://your-endpoint.azure.com/openai/deployments",
"vertexProjectId": "your-gcp-project-id",
"vertexLocation": "us-central1"
}
}
```
2. **Legacy `.taskmasterconfig` File (Backward Compatibility)**
- For projects that haven't migrated to the new structure yet.
- **Location:** Project root directory.
- **Migration:** Use `task-master migrate` to move this to `.taskmaster/config.json`.
- **Deprecation:** While still supported, you'll see warnings encouraging migration to the new structure.
## Environment Variables (`.env` file or MCP `env` block - For API Keys Only)
- Used **exclusively** for sensitive API keys and specific endpoint URLs.
- **Location:**
- For CLI usage: Create a `.env` file in your project root.
- For MCP/Cursor usage: Configure keys in the `env` section of your `.cursor/mcp.json` file.
- **Required API Keys (Depending on configured providers):**
- `ANTHROPIC_API_KEY`: Your Anthropic API key.
- `PERPLEXITY_API_KEY`: Your Perplexity API key.
- `OPENAI_API_KEY`: Your OpenAI API key.
- `GOOGLE_API_KEY`: Your Google API key (also used for Vertex AI provider).
- `MISTRAL_API_KEY`: Your Mistral API key.
- `AZURE_OPENAI_API_KEY`: Your Azure OpenAI API key (also requires `AZURE_OPENAI_ENDPOINT`).
- `OPENROUTER_API_KEY`: Your OpenRouter API key.
- `XAI_API_KEY`: Your X-AI API key.
- **Optional Endpoint Overrides:**
- **Per-role `baseURL` in `.taskmasterconfig`:** You can add a `baseURL` property to any model role (`main`, `research`, `fallback`) to override the default API endpoint for that provider. If omitted, the provider's standard endpoint is used.
- **Environment Variable Overrides (`<PROVIDER>_BASE_URL`):** For greater flexibility, especially with third-party services, you can set an environment variable like `OPENAI_BASE_URL` or `MISTRAL_BASE_URL`. This will override any `baseURL` set in the configuration file for that provider. This is the recommended way to connect to OpenAI-compatible APIs.
- `AZURE_OPENAI_ENDPOINT`: Required if using Azure OpenAI key (can also be set as `baseURL` for the Azure model role).
- `OLLAMA_BASE_URL`: Override the default Ollama API URL (Default: `http://localhost:11434/api`).
- `VERTEX_PROJECT_ID`: Your Google Cloud project ID for Vertex AI. Required when using the 'vertex' provider.
- `VERTEX_LOCATION`: Google Cloud region for Vertex AI (e.g., 'us-central1'). Default is 'us-central1'.
- `GOOGLE_APPLICATION_CREDENTIALS`: Path to service account credentials JSON file for Google Cloud auth (alternative to API key for Vertex AI).
- `TASKMASTER_ENABLE_CODEBASE_ANALYSIS`: Control codebase analysis features (Claude Code and Gemini CLI integration). Set to 'false' to disable. Default: enabled.
**Important:** Settings like model ID selections (`main`, `research`, `fallback`), `maxTokens`, `temperature`, `logLevel`, `defaultSubtasks`, `defaultPriority`, and `projectName` are **managed in `.taskmaster/config.json`** (or `.taskmasterconfig` for unmigrated projects), not environment variables.
## Codebase Analysis Configuration
Task Master includes advanced codebase analysis features that enhance task generation by analyzing your project structure, existing implementations, and patterns. This is particularly useful when integrated with Claude Code or using Gemini CLI provider.
### Configuration Options
**Environment Variable Control (Priority Order: `.env` > MCP session env > `.taskmaster/config.json`)**
```bash
# In .env file
TASKMASTER_ENABLE_CODEBASE_ANALYSIS=false # Disable codebase analysis features
```
When enabled, the following commands benefit from codebase analysis:
- `parse-prd`: Generates tasks informed by project structure
- `analyze-complexity`: Considers existing codebase complexity
- `add-task`: Creates tasks aligned with project patterns
- `update-task`: Updates tasks with relevant codebase context
- `update-subtask`: Enhances subtasks based on implementation details
- `expand`: Generates subtasks informed by existing code patterns
### Integration with Claude Code
When Task Master detects it's running within Claude Code, it automatically provides codebase context to generate more accurate and relevant task details. This feature can be disabled using the environment variable above.
### Gemini CLI Provider Enhancement
The Gemini CLI provider includes automatic codebase analysis when generating or updating tasks, resulting in more contextually accurate outputs aligned with your project's architecture.
## Tagged Task Lists Configuration (v0.17+)
Taskmaster includes a tagged task lists system for multi-context task management.
### Global Tag Settings
```json
"global": {
"defaultTag": "master"
}
```
- **`defaultTag`** (string): Default tag context for new operations (default: "master")
### Git Integration
Task Master provides manual git integration through the `--from-branch` option:
- **Manual Tag Creation**: Use `task-master add-tag --from-branch` to create a tag based on your current git branch name
- **User Control**: No automatic tag switching - you control when and how tags are created
- **Flexible Workflow**: Supports any git workflow without imposing rigid branch-tag mappings
## State Management File
Taskmaster uses `.taskmaster/state.json` to track tagged system runtime information:
```json
{
"currentTag": "master",
"lastSwitched": "2025-06-11T20:26:12.598Z",
"migrationNoticeShown": true
}
```
- **`currentTag`**: Currently active tag context
- **`lastSwitched`**: Timestamp of last tag switch
- **`migrationNoticeShown`**: Whether migration notice has been displayed
This file is automatically created during tagged system migration and should not be manually edited.
## Example `.env` File (for API Keys)
```
# Required API keys for providers configured in .taskmaster/config.json
ANTHROPIC_API_KEY=sk-ant-api03-your-key-here
PERPLEXITY_API_KEY=pplx-your-key-here
# OPENAI_API_KEY=sk-your-key-here
# GOOGLE_API_KEY=AIzaSy...
# AZURE_OPENAI_API_KEY=your-azure-openai-api-key-here
# etc.
# Optional Endpoint Overrides
# Use a specific provider's base URL, e.g., for an OpenAI-compatible API
# OPENAI_BASE_URL=https://api.third-party.com/v1
#
# Azure OpenAI Configuration
# AZURE_OPENAI_ENDPOINT=https://your-resource-name.openai.azure.com/ or https://your-endpoint-name.cognitiveservices.azure.com/openai/deployments
# OLLAMA_BASE_URL=http://custom-ollama-host:11434/api
# Google Vertex AI Configuration (Required if using 'vertex' provider)
# VERTEX_PROJECT_ID=your-gcp-project-id
# Feature Control
# TASKMASTER_ENABLE_CODEBASE_ANALYSIS=false # Disable codebase analysis features
```
## Troubleshooting
### Configuration Errors
- If Task Master reports errors about missing configuration or cannot find the config file, run `task-master models --setup` in your project root to create or repair the file.
- For new projects, config will be created at `.taskmaster/config.json`. For legacy projects, you may want to use `task-master migrate` to move to the new structure.
- Ensure API keys are correctly placed in your `.env` file (for CLI) or `.cursor/mcp.json` (for MCP) and are valid for the providers selected in your config file.
### If `task-master init` doesn't respond:
Try running it with Node directly:
```bash
node node_modules/claude-task-master/scripts/init.js
```
Or clone the repository and run:
```bash
git clone https://github.com/eyaltoledano/claude-task-master.git
cd claude-task-master
node scripts/init.js
```
## Provider-Specific Configuration
### Google Vertex AI Configuration
Google Vertex AI is Google Cloud's enterprise AI platform and requires specific configuration:
1. **Prerequisites**:
- A Google Cloud account with Vertex AI API enabled
- Either a Google API key with Vertex AI permissions OR a service account with appropriate roles
- A Google Cloud project ID
2. **Authentication Options**:
- **API Key**: Set the `GOOGLE_API_KEY` environment variable
- **Service Account**: Set `GOOGLE_APPLICATION_CREDENTIALS` to point to your service account JSON file
3. **Required Configuration**:
- Set `VERTEX_PROJECT_ID` to your Google Cloud project ID
- Set `VERTEX_LOCATION` to your preferred Google Cloud region (default: us-central1)
4. **Example Setup**:
```bash
# In .env file
GOOGLE_API_KEY=AIzaSyXXXXXXXXXXXXXXXXXXXXXXXXX
VERTEX_PROJECT_ID=my-gcp-project-123
VERTEX_LOCATION=us-central1
```
Or using service account:
```bash
# In .env file
GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
VERTEX_PROJECT_ID=my-gcp-project-123
VERTEX_LOCATION=us-central1
```
5. **In .taskmaster/config.json**:
```json
"global": {
"vertexProjectId": "my-gcp-project-123",
"vertexLocation": "us-central1"
}
```
### Azure OpenAI Configuration
Azure OpenAI provides enterprise-grade OpenAI models through Microsoft's Azure cloud platform and requires specific configuration:
1. **Prerequisites**:
- An Azure account with an active subscription
- Azure OpenAI service resource created in the Azure portal
- Azure OpenAI API key and endpoint URL
- Deployed models (e.g., gpt-4o, gpt-4o-mini, gpt-4.1, etc) in your Azure OpenAI resource
2. **Authentication**:
- Set the `AZURE_OPENAI_API_KEY` environment variable with your Azure OpenAI API key
- Configure the endpoint URL using one of the methods below
3. **Configuration Options**:
**Option 1: Using Global Azure Base URL (affects all Azure models)**
```json
// In .taskmaster/config.json
{
"models": {
"main": {
"provider": "azure",
"modelId": "gpt-4o",
"maxTokens": 16000,
"temperature": 0.7
},
"fallback": {
"provider": "azure",
"modelId": "gpt-4o-mini",
"maxTokens": 10000,
"temperature": 0.7
}
},
"global": {
"azureBaseURL": "https://your-resource-name.azure.com/openai/deployments"
}
}
```
**Option 2: Using Per-Model Base URLs (recommended for flexibility)**
```json
// In .taskmaster/config.json
{
"models": {
"main": {
"provider": "azure",
"modelId": "gpt-4o",
"maxTokens": 16000,
"temperature": 0.7,
"baseURL": "https://your-resource-name.azure.com/openai/deployments"
},
"research": {
"provider": "perplexity",
"modelId": "sonar-pro",
"maxTokens": 8700,
"temperature": 0.1
},
"fallback": {
"provider": "azure",
"modelId": "gpt-4o-mini",
"maxTokens": 10000,
"temperature": 0.7,
"baseURL": "https://your-resource-name.azure.com/openai/deployments"
}
}
}
```
4. **Environment Variables**:
```bash
# In .env file
AZURE_OPENAI_API_KEY=your-azure-openai-api-key-here
# Optional: Override endpoint for all Azure models
AZURE_OPENAI_ENDPOINT=https://your-resource-name.azure.com/openai/deployments
```
5. **Important Notes**:
- **Model Deployment Names**: The `modelId` in your configuration should match the **deployment name** you created in Azure OpenAI Studio, not the underlying model name
- **Base URL Priority**: Per-model `baseURL` settings override the global `azureBaseURL` setting
- **Endpoint Format**: When using per-model `baseURL`, use the full path including `/openai/deployments`
6. **Troubleshooting**:
**"Resource not found" errors:**
- Ensure your `baseURL` includes the full path: `https://your-resource-name.openai.azure.com/openai/deployments`
- Verify that your deployment name in `modelId` exactly matches what's configured in Azure OpenAI Studio
- Check that your Azure OpenAI resource is in the correct region and properly deployed
**Authentication errors:**
- Verify your `AZURE_OPENAI_API_KEY` is correct and has not expired
- Ensure your Azure OpenAI resource has the necessary permissions
- Check that your subscription has not been suspended or reached quota limits
**Model availability errors:**
- Confirm the model is deployed in your Azure OpenAI resource
- Verify the deployment name matches your configuration exactly (case-sensitive)
- Ensure the model deployment is in a "Succeeded" state in Azure OpenAI Studio
- Ensure youre not getting rate limited by `maxTokens` maintain appropriate Tokens per Minute Rate Limit (TPM) in your deployment.

View File

@@ -0,0 +1,8 @@
---
title: Intro to Advanced Usage
sidebarTitle: "Advanced Usage"
---
# Best Practices
Explore advanced tips, recommended workflows, and best practices for getting the most out of Task Master.

View File

@@ -0,0 +1,230 @@
---
title: CLI Commands
sidebarTitle: "CLI Commands"
---
<AccordionGroup>
<Accordion title="Parse PRD">
```bash
# Parse a PRD file and generate tasks
task-master parse-prd <prd-file.txt>
# Limit the number of tasks generated
task-master parse-prd <prd-file.txt> --num-tasks=10
```
</Accordion>
<Accordion title="List Tasks">
```bash
# List all tasks
task-master list
# List tasks with a specific status
task-master list --status=<status>
# List tasks with subtasks
task-master list --with-subtasks
# List tasks with a specific status and include subtasks
task-master list --status=<status> --with-subtasks
```
</Accordion>
<Accordion title="Show Next Task">
```bash
# Show the next task to work on based on dependencies and status
task-master next
```
</Accordion>
<Accordion title="Show Specific Task">
```bash
# Show details of a specific task
task-master show <id>
# or
task-master show --id=<id>
# View a specific subtask (e.g., subtask 2 of task 1)
task-master show 1.2
```
</Accordion>
<Accordion title="Update Tasks">
```bash
# Update tasks from a specific ID and provide context
task-master update --from=<id> --prompt="<prompt>"
```
</Accordion>
<Accordion title="Update a Specific Task">
```bash
# Update a single task by ID with new information
task-master update-task --id=<id> --prompt="<prompt>"
# Use research-backed updates with Perplexity AI
task-master update-task --id=<id> --prompt="<prompt>" --research
```
</Accordion>
<Accordion title="Update a Subtask">
```bash
# Append additional information to a specific subtask
task-master update-subtask --id=<parentId.subtaskId> --prompt="<prompt>"
# Example: Add details about API rate limiting to subtask 2 of task 5
task-master update-subtask --id=5.2 --prompt="Add rate limiting of 100 requests per minute"
# Use research-backed updates with Perplexity AI
task-master update-subtask --id=<parentId.subtaskId> --prompt="<prompt>" --research
```
Unlike the `update-task` command which replaces task information, the `update-subtask` command _appends_ new information to the existing subtask details, marking it with a timestamp. This is useful for iteratively enhancing subtasks while preserving the original content.
</Accordion>
<Accordion title="Generate Task Files">
```bash
# Generate individual task files from tasks.json
task-master generate
```
</Accordion>
<Accordion title="Set Task Status">
```bash
# Set status of a single task
task-master set-status --id=<id> --status=<status>
# Set status for multiple tasks
task-master set-status --id=1,2,3 --status=<status>
# Set status for subtasks
task-master set-status --id=1.1,1.2 --status=<status>
```
When marking a task as "done", all of its subtasks will automatically be marked as "done" as well.
</Accordion>
<Accordion title="Expand Tasks">
```bash
# Expand a specific task with subtasks
task-master expand --id=<id> --num=<number>
# Expand with additional context
task-master expand --id=<id> --prompt="<context>"
# Expand all pending tasks
task-master expand --all
# Force regeneration of subtasks for tasks that already have them
task-master expand --all --force
# Research-backed subtask generation for a specific task
task-master expand --id=<id> --research
# Research-backed generation for all tasks
task-master expand --all --research
```
</Accordion>
<Accordion title="Clear Subtasks">
```bash
# Clear subtasks from a specific task
task-master clear-subtasks --id=<id>
# Clear subtasks from multiple tasks
task-master clear-subtasks --id=1,2,3
# Clear subtasks from all tasks
task-master clear-subtasks --all
```
</Accordion>
<Accordion title="Analyze Task Complexity">
```bash
# Analyze complexity of all tasks
task-master analyze-complexity
# Save report to a custom location
task-master analyze-complexity --output=my-report.json
# Use a specific LLM model
task-master analyze-complexity --model=claude-3-opus-20240229
# Set a custom complexity threshold (1-10)
task-master analyze-complexity --threshold=6
# Use an alternative tasks file
task-master analyze-complexity --file=custom-tasks.json
# Use Perplexity AI for research-backed complexity analysis
task-master analyze-complexity --research
```
</Accordion>
<Accordion title="View Complexity Report">
```bash
# Display the task complexity analysis report
task-master complexity-report
# View a report at a custom location
task-master complexity-report --file=my-report.json
```
</Accordion>
<Accordion title="Managing Task Dependencies">
```bash
# Add a dependency to a task
task-master add-dependency --id=<id> --depends-on=<id>
# Remove a dependency from a task
task-master remove-dependency --id=<id> --depends-on=<id>
# Validate dependencies without fixing them
task-master validate-dependencies
# Find and fix invalid dependencies automatically
task-master fix-dependencies
```
</Accordion>
<Accordion title="Add a New Task">
```bash
# Add a new task using AI
task-master add-task --prompt="Description of the new task"
# Add a task with dependencies
task-master add-task --prompt="Description" --dependencies=1,2,3
# Add a task with priority
task-master add-task --prompt="Description" --priority=high
```
</Accordion>
<Accordion title="Initialize a Project">
```bash
# Initialize a new project with Task Master structure
task-master init
```
</Accordion>
<Accordion title="Move Tasks">
```bash
# Move a task or subtask to a new position
task-master move --from=<id> --to=<id>
# Move multiple tasks at once (same number of IDs required)
task-master move --from=1,2,3 --to=7,8,9
# Cross-tag moves with dependency handling
task-master move --from=5 --to=3 --with-dependencies --tag-from=feature --tag-to=main
task-master move --from=5 --to=3 --ignore-dependencies --tag-from=feature --tag-to=main
# Note: --force flag is deprecated, use --with-dependencies or --ignore-dependencies instead
```
**Cross-tag Move Safety Features:**
- CLI shows "Next Steps" guidance after moves that ignore dependencies
- Dedicated help is displayed for ID collisions with structured suggestions
- Better error handling with actionable suggestions for resolution
</Accordion>
</AccordionGroup>

View File

@@ -0,0 +1,241 @@
---
title: Technical Capabilities
sidebarTitle: "Technical Capabilities"
---
# Capabilities (Technical)
Discover the technical capabilities of Task Master, including supported models, integrations, and more.
# CLI Interface Synopsis
This document outlines the command-line interface (CLI) for the Task Master application, as defined in `bin/task-master.js` and the `scripts/modules/commands.js` file (which I will assume exists based on the context). This guide is intended for those writing user-facing documentation to understand how users interact with the application from the command line.
## Entry Point
The main entry point for the CLI is the `task-master` command, which is an executable script that spawns the main application logic in `scripts/dev.js`.
## Global Options
The following options are available for all commands:
- `-h, --help`: Display help information.
- `--version`: Display the application's version.
## Commands
The CLI is organized into a series of commands, each with its own set of options. The following is a summary of the available commands, categorized by their functionality.
### 1. Task and Subtask Management
- **`add`**: Creates a new task using an AI-powered prompt.
- `--prompt <prompt>`: The prompt to use for generating the task.
- `--dependencies <dependencies>`: A comma-separated list of task IDs that this task depends on.
- `--priority <priority>`: The priority of the task (e.g., `high`, `medium`, `low`).
- **`add-subtask`**: Adds a subtask to a parent task.
- `--parent-id <parentId>`: The ID of the parent task.
- `--task-id <taskId>`: The ID of an existing task to convert to a subtask.
- `--title <title>`: The title of the new subtask.
- **`remove`**: Removes one or more tasks or subtasks.
- `--ids <ids>`: A comma-separated list of task or subtask IDs to remove.
- **`remove-subtask`**: Removes a subtask from its parent.
- `--id <subtaskId>`: The ID of the subtask to remove (in the format `parentId.subtaskId`).
- `--convert-to-task`: Converts the subtask to a standalone task.
- **`update`**: Updates multiple tasks starting from a specific ID.
- `--from <fromId>`: The ID of the task to start updating from.
- `--prompt <prompt>`: The new context to apply to the tasks.
- **`update-task`**: Updates a single task.
- `--id <taskId>`: The ID of the task to update.
- `--prompt <prompt>`: The new context to apply to the task.
- **`update-subtask`**: Appends information to a subtask.
- `--id <subtaskId>`: The ID of the subtask to update (in the format `parentId.subtaskId`).
- `--prompt <prompt>`: The information to append to the subtask.
- **`move`**: Moves a task or subtask.
- `--from <sourceId>`: The ID of the task or subtask to move.
- `--to <destinationId>`: The destination ID.
- **`clear-subtasks`**: Clears all subtasks from one or more tasks.
- `--ids <ids>`: A comma-separated list of task IDs.
### 2. Task Information and Status
- **`list`**: Lists all tasks.
- `--status <status>`: Filters tasks by status.
- `--with-subtasks`: Includes subtasks in the list.
- **`show`**: Shows the details of a specific task.
- `--id <taskId>`: The ID of the task to show.
- **`next`**: Shows the next task to work on.
- **`set-status`**: Sets the status of a task or subtask.
- `--id <id>`: The ID of the task or subtask.
- `--status <status>`: The new status.
### 3. Task Analysis and Expansion
- **`parse-prd`**: Parses a PRD to generate tasks.
- `--file <file>`: The path to the PRD file.
- `--num-tasks <numTasks>`: The number of tasks to generate.
- **`expand`**: Expands a task into subtasks.
- `--id <taskId>`: The ID of the task to expand.
- `--num-subtasks <numSubtasks>`: The number of subtasks to generate.
- **`expand-all`**: Expands all eligible tasks.
- `--num-subtasks <numSubtasks>`: The number of subtasks to generate for each task.
- **`analyze-complexity`**: Analyzes task complexity.
- `--file <file>`: The path to the tasks file.
- **`complexity-report`**: Displays the complexity analysis report.
### 4. Project and Configuration
- **`init`**: Initializes a new project.
- **`generate`**: Generates individual task files.
- **`migrate`**: Migrates a project to the new directory structure.
- **`research`**: Performs AI-powered research.
- `--query <query>`: The research query.
This synopsis provides a comprehensive overview of the CLI commands and their options, which should be helpful for creating user-facing documentation.
# Core Implementation Synopsis
This document provides a high-level overview of the core implementation of the Task Master application, focusing on the functionalities exposed through `scripts/modules/task-manager.js`. This serves as a guide for understanding the application's capabilities when writing user-facing documentation.
## Core Concepts
The application revolves around the management of tasks and subtasks, which are stored in a `tasks.json` file. The core logic provides functionalities to create, read, update, and delete tasks and subtasks, as well as manage their dependencies and statuses.
### Task Structure
A task is a JSON object with the following key properties:
- `id`: A unique number identifying the task.
- `title`: A string representing the task's title.
- `description`: A string providing a brief description of the task.
- `details`: A string containing detailed information about the task.
- `testStrategy`: A string describing how to test the task.
- `status`: A string representing the task's current status (e.g., `pending`, `in-progress`, `done`).
- `dependencies`: An array of task IDs that this task depends on.
- `priority`: A string representing the task's priority (e.g., `high`, `medium`, `low`).
- `subtasks`: An array of subtask objects.
A subtask has a similar structure to a task but is nested within a parent task.
## Feature Categories
The core functionalities can be categorized as follows:
### 1. Task and Subtask Management
These functions are the bread and butter of the application, allowing for the creation, modification, and deletion of tasks and subtasks.
- **`addTask(prompt, dependencies, priority)`**: Creates a new task using an AI-powered prompt to generate the title, description, details, and test strategy. It can also be used to create a task manually by providing the task data directly.
- **`addSubtask(parentId, existingTaskId, newSubtaskData)`**: Adds a subtask to a parent task. It can either convert an existing task into a subtask or create a new subtask from scratch.
- **`removeTask(taskIds)`**: Removes one or more tasks or subtasks.
- **`removeSubtask(subtaskId, convertToTask)`**: Removes a subtask from its parent. It can optionally convert the subtask into a standalone task.
- **`updateTaskById(taskId, prompt)`**: Updates a task's information based on a prompt.
- **`updateSubtaskById(subtaskId, prompt)`**: Appends additional information to a subtask's details.
- **`updateTasks(fromId, prompt)`**: Updates multiple tasks starting from a specific ID based on a new context.
- **`moveTask(sourceId, destinationId)`**: Moves a task or subtask to a new position.
- **`clearSubtasks(taskIds)`**: Clears all subtasks from one or more tasks.
### 2. Task Information and Status
These functions are used to retrieve information about tasks and manage their status.
- **`listTasks(statusFilter, withSubtasks)`**: Lists all tasks, with options to filter by status and include subtasks.
- **`findTaskById(taskId)`**: Finds a task by its ID.
- **`taskExists(taskId)`**: Checks if a task with a given ID exists.
- **`setTaskStatus(taskIdInput, newStatus)`**: Sets the status of a task or subtask.
-al
- **`updateSingleTaskStatus(taskIdInput, newStatus)`**: A helper function to update the status of a single task or subtask.
- **`findNextTask()`**: Determines the next task to work on based on dependencies and status.
### 3. Task Analysis and Expansion
These functions leverage AI to analyze and break down tasks.
- **`parsePRD(prdPath, numTasks)`**: Parses a Product Requirements Document (PRD) to generate an initial set of tasks.
- **`expandTask(taskId, numSubtasks)`**: Expands a task into a specified number of subtasks using AI.
- **`expandAllTasks(numSubtasks)`**: Expands all eligible pending or in-progress tasks.
- **`analyzeTaskComplexity(options)`**: Analyzes the complexity of tasks and generates recommendations for expansion.
- **`readComplexityReport()`**: Reads the complexity analysis report.
### 4. Dependency Management
These functions are crucial for managing the relationships between tasks.
- **`isTaskDependentOn(task, targetTaskId)`**: Checks if a task has a direct or indirect dependency on another task.
### 5. Project and Configuration
These functions are for managing the project and its configuration.
- **`generateTaskFiles()`**: Generates individual task files from `tasks.json`.
- **`migrateProject()`**: Migrates the project to the new `.taskmaster` directory structure.
- **`performResearch(query, options)`**: Performs AI-powered research with project context.
This overview should provide a solid foundation for creating user-facing documentation. For more detailed information on each function, refer to the source code in `scripts/modules/task-manager/`.
# MCP Interface Synopsis
This document provides an overview of the MCP (Machine-to-Machine Communication Protocol) interface for the Task Master application. The MCP interface is defined in the `mcp-server/` directory and exposes the application's core functionalities as a set of tools that can be called remotely.
## Core Concepts
The MCP interface is built on top of the `fastmcp` library and registers a set of tools that correspond to the core functionalities of the Task Master application. These tools are defined in the `mcp-server/src/tools/` directory and are registered with the MCP server in `mcp-server/src/tools/index.js`.
Each tool is defined with a name, a description, and a set of parameters that are validated using the `zod` library. The `execute` function of each tool calls the corresponding core logic function from `scripts/modules/task-manager.js`.
## Tool Categories
The MCP tools can be categorized in the same way as the core functionalities:
### 1. Task and Subtask Management
- **`add_task`**: Creates a new task.
- **`add_subtask`**: Adds a subtask to a parent task.
- **`remove_task`**: Removes one or more tasks or subtasks.
- **`remove_subtask`**: Removes a subtask from its parent.
- **`update_task`**: Updates a single task.
- **`update_subtask`**: Appends information to a subtask.
- **`update`**: Updates multiple tasks.
- **`move_task`**: Moves a task or subtask.
- **`clear_subtasks`**: Clears all subtasks from one or more tasks.
### 2. Task Information and Status
- **`get_tasks`**: Lists all tasks.
- **`get_task`**: Shows the details of a specific task.
- **`next_task`**: Shows the next task to work on.
- **`set_task_status`**: Sets the status of a task or subtask.
### 3. Task Analysis and Expansion
- **`parse_prd`**: Parses a PRD to generate tasks.
- **`expand_task`**: Expands a task into subtasks.
- **`expand_all`**: Expands all eligible tasks.
- **`analyze_project_complexity`**: Analyzes task complexity.
- **`complexity_report`**: Displays the complexity analysis report.
### 4. Dependency Management
- **`add_dependency`**: Adds a dependency to a task.
- **`remove_dependency`**: Removes a dependency from a task.
- **`validate_dependencies`**: Validates the dependencies of all tasks.
- **`fix_dependencies`**: Fixes any invalid dependencies.
### 5. Project and Configuration
- **`initialize_project`**: Initializes a new project.
- **`generate`**: Generates individual task files.
- **`models`**: Manages AI model configurations.
- **`research`**: Performs AI-powered research.
### 6. Tag Management
- **`add_tag`**: Creates a new tag.
- **`delete_tag`**: Deletes a tag.
- **`list_tags`**: Lists all tags.
- **`use_tag`**: Switches to a different tag.
- **`rename_tag`**: Renames a tag.
- **`copy_tag`**: Copies a tag.
This synopsis provides a clear overview of the MCP interface and its available tools, which will be valuable for anyone writing documentation for developers who need to interact with the Task Master application programmatically.

View File

@@ -0,0 +1,68 @@
---
title: MCP Tools
sidebarTitle: "MCP Tools"
---
# MCP Tools
This document provides an overview of the MCP (Machine-to-Machine Communication Protocol) interface for the Task Master application. The MCP interface is defined in the `mcp-server/` directory and exposes the application's core functionalities as a set of tools that can be called remotely.
## Core Concepts
The MCP interface is built on top of the `fastmcp` library and registers a set of tools that correspond to the core functionalities of the Task Master application. These tools are defined in the `mcp-server/src/tools/` directory and are registered with the MCP server in `mcp-server/src/tools/index.js`.
Each tool is defined with a name, a description, and a set of parameters that are validated using the `zod` library. The `execute` function of each tool calls the corresponding core logic function from `scripts/modules/task-manager.js`.
## Tool Categories
The MCP tools can be categorized in the same way as the core functionalities:
### 1. Task and Subtask Management
- **`add_task`**: Creates a new task.
- **`add_subtask`**: Adds a subtask to a parent task.
- **`remove_task`**: Removes one or more tasks or subtasks.
- **`remove_subtask`**: Removes a subtask from its parent.
- **`update_task`**: Updates a single task.
- **`update_subtask`**: Appends information to a subtask.
- **`update`**: Updates multiple tasks.
- **`move_task`**: Moves a task or subtask.
- **`clear_subtasks`**: Clears all subtasks from one or more tasks.
### 2. Task Information and Status
- **`get_tasks`**: Lists all tasks.
- **`get_task`**: Shows the details of a specific task.
- **`next_task`**: Shows the next task to work on.
- **`set_task_status`**: Sets the status of a task or subtask.
### 3. Task Analysis and Expansion
- **`parse_prd`**: Parses a PRD to generate tasks.
- **`expand_task`**: Expands a task into subtasks.
- **`expand_all`**: Expands all eligible tasks.
- **`analyze_project_complexity`**: Analyzes task complexity.
- **`complexity_report`**: Displays the complexity analysis report.
### 4. Dependency Management
- **`add_dependency`**: Adds a dependency to a task.
- **`remove_dependency`**: Removes a dependency from a task.
- **`validate_dependencies`**: Validates the dependencies of all tasks.
- **`fix_dependencies`**: Fixes any invalid dependencies.
### 5. Project and Configuration
- **`initialize_project`**: Initializes a new project.
- **`generate`**: Generates individual task files.
- **`models`**: Manages AI model configurations.
- **`research`**: Performs AI-powered research.
### 6. Tag Management
- **`add_tag`**: Creates a new tag.
- **`delete_tag`**: Deletes a tag.
- **`list_tags`**: Lists all tags.
- **`use_tag`**: Switches to a different tag.
- **`rename_tag`**: Renames a tag.
- **`copy_tag`**: Copies a tag.

View File

@@ -0,0 +1,163 @@
---
title: "Task Structure"
sidebarTitle: "Task Structure"
description: "Tasks in Task Master follow a specific format designed to provide comprehensive information for both humans and AI assistants."
---
## Task Fields in tasks.json
Tasks in tasks.json have the following structure:
| Field | Description | Example |
| -------------- | ---------------------------------------------- | ------------------------------------------------------ |
| `id` | Unique identifier for the task. | `1` |
| `title` | Brief, descriptive title. | `"Initialize Repo"` |
| `description` | What the task involves. | `"Create a new repository, set up initial structure."` |
| `status` | Current state. | `"pending"`, `"done"`, `"deferred"` |
| `dependencies` | Prerequisite task IDs. ✅ Completed, ⏱️ Pending | `[1, 2]` |
| `priority` | Task importance. | `"high"`, `"medium"`, `"low"` |
| `details` | Implementation instructions. | `"Use GitHub client ID/secret, handle callback..."` |
| `testStrategy` | How to verify success. | `"Deploy and confirm 'Hello World' response."` |
| `subtasks` | Nested subtasks related to the main task. | `[{"id": 1, "title": "Configure OAuth", ...}]` |
## Task File Format
Individual task files follow this format:
```
# Task ID: <id>
# Title: <title>
# Status: <status>
# Dependencies: <comma-separated list of dependency IDs>
# Priority: <priority>
# Description: <brief description>
# Details:
<detailed implementation notes>
# Test Strategy:
<verification approach>
```
## Features in Detail
<AccordionGroup>
<Accordion title="Analyzing Task Complexity">
The `analyze-complexity` command:
- Analyzes each task using AI to assess its complexity on a scale of 1-10
- Recommends optimal number of subtasks based on configured DEFAULT_SUBTASKS
- Generates tailored prompts for expanding each task
- Creates a comprehensive JSON report with ready-to-use commands
- Saves the report to scripts/task-complexity-report.json by default
The generated report contains:
- Complexity analysis for each task (scored 1-10)
- Recommended number of subtasks based on complexity
- AI-generated expansion prompts customized for each task
- Ready-to-run expansion commands directly within each task analysis
</Accordion>
<Accordion title="Viewing Complexity Report">
The `complexity-report` command:
- Displays a formatted, easy-to-read version of the complexity analysis report
- Shows tasks organized by complexity score (highest to lowest)
- Provides complexity distribution statistics (low, medium, high)
- Highlights tasks recommended for expansion based on threshold score
- Includes ready-to-use expansion commands for each complex task
- If no report exists, offers to generate one on the spot
</Accordion>
<Accordion title="Smart Task Expansion">
The `expand` command automatically checks for and uses the complexity report:
When a complexity report exists:
- Tasks are automatically expanded using the recommended subtask count and prompts
- When expanding all tasks, they're processed in order of complexity (highest first)
- Research-backed generation is preserved from the complexity analysis
- You can still override recommendations with explicit command-line options
Example workflow:
```bash
# Generate the complexity analysis report with research capabilities
task-master analyze-complexity --research
# Review the report in a readable format
task-master complexity-report
# Expand tasks using the optimized recommendations
task-master expand --id=8
# or expand all tasks
task-master expand --all
```
</Accordion>
<Accordion title="Finding the Next Task">
The `next` command:
- Identifies tasks that are pending/in-progress and have all dependencies satisfied
- Prioritizes tasks by priority level, dependency count, and task ID
- Displays comprehensive information about the selected task:
- Basic task details (ID, title, priority, dependencies)
- Implementation details
- Subtasks (if they exist)
- Provides contextual suggested actions:
- Command to mark the task as in-progress
- Command to mark the task as done
- Commands for working with subtasks
</Accordion>
<Accordion title="Viewing Specific Task Details">
The `show` command:
- Displays comprehensive details about a specific task or subtask
- Shows task status, priority, dependencies, and detailed implementation notes
- For parent tasks, displays all subtasks and their status
- For subtasks, shows parent task relationship
- Provides contextual action suggestions based on the task's state
- Works with both regular tasks and subtasks (using the format taskId.subtaskId)
</Accordion>
</AccordionGroup>
## Best Practices for AI-Driven Development
<CardGroup cols={2}>
<Card title="📝 Detailed PRD" icon="lightbulb">
The more detailed your PRD, the better the generated tasks will be.
</Card>
<Card title="👀 Review Tasks" icon="magnifying-glass">
After parsing the PRD, review the tasks to ensure they make sense and have appropriate dependencies.
</Card>
<Card title="📊 Analyze Complexity" icon="chart-line">
Use the complexity analysis feature to identify which tasks should be broken down further.
</Card>
<Card title="⛓️ Follow Dependencies" icon="link">
Always respect task dependencies - the Cursor agent will help with this.
</Card>
<Card title="🔄 Update As You Go" icon="arrows-rotate">
If your implementation diverges from the plan, use the update command to keep future tasks aligned.
</Card>
<Card title="📦 Break Down Tasks" icon="boxes-stacked">
Use the expand command to break down complex tasks into manageable subtasks.
</Card>
<Card title="🔄 Regenerate Files" icon="file-arrow-up">
After any updates to tasks.json, regenerate the task files to keep them in sync.
</Card>
<Card title="💬 Provide Context" icon="comment">
When asking the Cursor agent to help with a task, provide context about what you're trying to achieve.
</Card>
<Card title="✅ Validate Dependencies" icon="circle-check">
Periodically run the validate-dependencies command to check for invalid or circular dependencies.
</Card>
</CardGroup>

83
apps/docs/docs.json Normal file
View File

@@ -0,0 +1,83 @@
{
"$schema": "https://mintlify.com/docs.json",
"theme": "mint",
"name": "Task Master",
"colors": {
"primary": "#3366CC",
"light": "#6699FF",
"dark": "#24478F"
},
"favicon": "/favicon.svg",
"navigation": {
"tabs": [
{
"tab": "Task Master Documentation",
"groups": [
{
"group": "Welcome",
"pages": ["introduction"]
},
{
"group": "Getting Started",
"pages": [
{
"group": "Quick Start",
"pages": [
"getting-started/quick-start/quick-start",
"getting-started/quick-start/requirements",
"getting-started/quick-start/installation",
"getting-started/quick-start/configuration-quick",
"getting-started/quick-start/prd-quick",
"getting-started/quick-start/tasks-quick",
"getting-started/quick-start/execute-quick"
]
},
"getting-started/faq",
"getting-started/contribute"
]
},
{
"group": "Best Practices",
"pages": [
"best-practices/index",
"best-practices/configuration-advanced",
"best-practices/advanced-tasks"
]
},
{
"group": "Technical Capabilities",
"pages": [
"capabilities/mcp",
"capabilities/cli-root-commands",
"capabilities/task-structure"
]
}
]
}
],
"global": {
"anchors": [
{
"anchor": "Github",
"href": "https://github.com/eyaltoledano/claude-task-master",
"icon": "github"
},
{
"anchor": "Discord",
"href": "https://discord.gg/fWJkU7rf",
"icon": "discord"
}
]
}
},
"logo": {
"light": "/logo/task-master-logo.png",
"dark": "/logo/task-master-logo.png"
},
"footer": {
"socials": {
"x": "https://x.com/TaskmasterAI",
"github": "https://github.com/eyaltoledano/claude-task-master"
}
}
}

9
apps/docs/favicon.svg Normal file
View File

@@ -0,0 +1,9 @@
<svg width="100" height="100" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<!-- Blue form with check from logo -->
<rect x="16" y="10" width="68" height="80" rx="9" fill="#3366CC"/>
<polyline points="33,44 41,55 56,29" fill="none" stroke="#FFFFFF" stroke-width="6"/>
<circle cx="33" cy="64" r="4" fill="#FFFFFF"/>
<rect x="43" y="61" width="27" height="6" fill="#FFFFFF"/>
<circle cx="33" cy="77" r="4" fill="#FFFFFF"/>
<rect x="43" y="75" width="27" height="6" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 513 B

View File

@@ -0,0 +1,335 @@
# Contributing to Task Master
Thank you for your interest in contributing to Task Master! We're excited to work with you and appreciate your help in making this project better. 🚀
## 🤝 Our Collaborative Approach
We're a **PR-friendly team** that values collaboration:
- ✅ **We review PRs quickly** - Usually within hours, not days
- ✅ **We're super reactive** - Expect fast feedback and engagement
- ✅ **We sometimes take over PRs** - If your contribution is valuable but needs cleanup, we might jump in to help finish it
- ✅ **We're open to all contributions** - From bug fixes to major features
**We don't mind AI-generated code**, but we do expect you to:
- ✅ **Review and understand** what the AI generated
- ✅ **Test the code thoroughly** before submitting
- ✅ **Ensure it's well-written** and follows our patterns
- ❌ **Don't submit "AI slop"** - untested, unreviewed AI output
> **Why this matters**: We spend significant time reviewing PRs. Help us help you by submitting quality contributions that save everyone time!
## 🚀 Quick Start for Contributors
### 1. Fork and Clone
```bash
git clone https://github.com/YOUR_USERNAME/claude-task-master.git
cd claude-task-master
npm install
```
### 2. Create a Feature Branch
**Important**: Always target the `next` branch, not `main`:
```bash
git checkout next
git pull origin next
git checkout -b feature/your-feature-name
```
### 3. Make Your Changes
Follow our development guidelines below.
### 4. Test Everything Yourself
**Before submitting your PR**, ensure:
```bash
# Run all tests
npm test
# Check formatting
npm run format-check
# Fix formatting if needed
npm run format
```
### 5. Create a Changeset
**Required for most changes**:
```bash
npm run changeset
```
See the [Changeset Guidelines](#changeset-guidelines) below for details.
### 6. Submit Your PR
- Target the `next` branch
- Write a clear description
- Reference any related issues
## 📋 Development Guidelines
### Branch Strategy
- **`main`**: Production-ready code
- **`next`**: Development branch - **target this for PRs**
- **Feature branches**: `feature/description` or `fix/description`
### Code Quality Standards
1. **Write tests** for new functionality
2. **Follow existing patterns** in the codebase
3. **Add JSDoc comments** for functions
4. **Keep functions focused** and single-purpose
### Testing Requirements
Your PR **must pass all CI checks**:
- ✅ **Unit tests**: `npm test`
- ✅ **Format check**: `npm run format-check`
**Test your changes locally first** - this saves review time and shows you care about quality.
## 📦 Changeset Guidelines
We use [Changesets](https://github.com/changesets/changesets) to manage versioning and generate changelogs.
### When to Create a Changeset
**Always create a changeset for**:
- ✅ New features
- ✅ Bug fixes
- ✅ Breaking changes
- ✅ Performance improvements
- ✅ User-facing documentation updates
- ✅ Dependency updates that affect functionality
**Skip changesets for**:
- ❌ Internal documentation only
- ❌ Test-only changes
- ❌ Code formatting/linting
- ❌ Development tooling that doesn't affect users
### How to Create a Changeset
1. **After making your changes**:
```bash
npm run changeset
```
2. **Choose the bump type**:
- **Major**: Breaking changes
- **Minor**: New features
- **Patch**: Bug fixes, docs, performance improvements
3. **Write a clear summary**:
```
Add support for custom AI models in MCP configuration
```
4. **Commit the changeset file** with your changes:
```bash
git add .changeset/*.md
git commit -m "feat: add custom AI model support"
```
### Changeset vs Git Commit Messages
- **Changeset summary**: User-facing, goes in CHANGELOG.md
- **Git commit**: Developer-facing, explains the technical change
Example:
```bash
# Changeset summary (user-facing)
"Add support for custom Ollama models"
# Git commit message (developer-facing)
"feat(models): implement custom Ollama model validation
- Add model validation for custom Ollama endpoints
- Update configuration schema to support custom models
- Add tests for new validation logic"
```
## 🔧 Development Setup
### Prerequisites
- Node.js 18+
- npm or yarn
### Environment Setup
1. **Copy environment template**:
```bash
cp .env.example .env
```
2. **Add your API keys** (for testing AI features):
```bash
ANTHROPIC_API_KEY=your_key_here
OPENAI_API_KEY=your_key_here
# Add others as needed
```
### Running Tests
```bash
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run with coverage
npm run test:coverage
# Run E2E tests
npm run test:e2e
```
### Code Formatting
We use Prettier for consistent formatting:
```bash
# Check formatting
npm run format-check
# Fix formatting
npm run format
```
## 📝 PR Guidelines
### Before Submitting
- [ ] **Target the `next` branch**
- [ ] **Test everything locally**
- [ ] **Run the full test suite**
- [ ] **Check code formatting**
- [ ] **Create a changeset** (if needed)
- [ ] **Re-read your changes** - ensure they're clean and well-thought-out
### PR Description Template
```markdown
## Description
Brief description of what this PR does.
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing
- [ ] I have tested this locally
- [ ] All existing tests pass
- [ ] I have added tests for new functionality
## Changeset
- [ ] I have created a changeset (or this change doesn't need one)
## Additional Notes
Any additional context or notes for reviewers.
```
### What We Look For
✅ **Good PRs**:
- Clear, focused changes
- Comprehensive testing
- Good commit messages
- Proper changeset (when needed)
- Self-reviewed code
❌ **Avoid**:
- Massive PRs that change everything
- Untested code
- Formatting issues
- Missing changesets for user-facing changes
- AI-generated code that wasn't reviewed
## 🏗️ Project Structure
```
claude-task-master/
├── bin/ # CLI executables
├── mcp-server/ # MCP server implementation
├── scripts/ # Core task management logic
├── src/ # Shared utilities and providers and well refactored code (we are slowly moving everything here)
├── tests/ # Test files
├── docs/ # Documentation
└── .cursor/ # Cursor IDE rules and configuration
└── assets/ # Assets like rules and configuration for all IDEs
```
### Key Areas for Contribution
- **CLI Commands**: `scripts/modules/commands.js`
- **MCP Tools**: `mcp-server/src/tools/`
- **Core Logic**: `scripts/modules/task-manager/`
- **AI Providers**: `src/ai-providers/`
- **Tests**: `tests/`
## 🐛 Reporting Issues
### Bug Reports
Include:
- Task Master version
- Node.js version
- Operating system
- Steps to reproduce
- Expected vs actual behavior
- Error messages/logs
### Feature Requests
Include:
- Clear description of the feature
- Use case/motivation
- Proposed implementation (if you have ideas)
- Willingness to contribute
## 💬 Getting Help
- **Discord**: [Join our community](https://discord.gg/taskmasterai)
- **Issues**: [GitHub Issues](https://github.com/eyaltoledano/claude-task-master/issues)
- **Discussions**: [GitHub Discussions](https://github.com/eyaltoledano/claude-task-master/discussions)
## 📄 License
By contributing, you agree that your contributions will be licensed under the same license as the project (MIT with Commons Clause).
---
**Thank you for contributing to Task Master!** 🎉
Your contributions help make AI-driven development more accessible and efficient for everyone.

View File

@@ -0,0 +1,12 @@
---
title: FAQ
sidebarTitle: "FAQ"
---
Coming soon.
## 💬 Getting Help
- **Discord**: [Join our community](https://discord.gg/taskmasterai)
- **Issues**: [GitHub Issues](https://github.com/eyaltoledano/claude-task-master/issues)
- **Discussions**: [GitHub Discussions](https://github.com/eyaltoledano/claude-task-master/discussions)

View File

@@ -0,0 +1,112 @@
---
title: Configuration
sidebarTitle: "Configuration"
---
Before getting started with Task Master, you'll need to set up your API keys. There are a couple of ways to do this depending on whether you're using the CLI or working inside MCP. It's also a good time to start getting familiar with the other configuration options available — even if you dont need to adjust them yet, knowing whats possible will help down the line.
## API Key Setup
Task Master uses environment variables to securely store provider API keys and optional endpoint URLs.
### MCP Usage: mcp.json file
For MCP/Cursor usage: Configure keys in the env section of your .cursor/mcp.json file.
```java .env lines icon="java"
{
"mcpServers": {
"task-master-ai": {
"command": "node",
"args": ["./mcp-server/server.js"],
"env": {
"ANTHROPIC_API_KEY": "ANTHROPIC_API_KEY_HERE",
"PERPLEXITY_API_KEY": "PERPLEXITY_API_KEY_HERE",
"OPENAI_API_KEY": "OPENAI_API_KEY_HERE",
"GOOGLE_API_KEY": "GOOGLE_API_KEY_HERE",
"XAI_API_KEY": "XAI_API_KEY_HERE",
"OPENROUTER_API_KEY": "OPENROUTER_API_KEY_HERE",
"MISTRAL_API_KEY": "MISTRAL_API_KEY_HERE",
"AZURE_OPENAI_API_KEY": "AZURE_OPENAI_API_KEY_HERE",
"OLLAMA_API_KEY": "OLLAMA_API_KEY_HERE",
"GITHUB_API_KEY": "GITHUB_API_KEY_HERE"
}
}
}
}
```
### CLI Usage: `.env` File
Create a `.env` file in your project root and include the keys for the providers you plan to use:
```java .env lines icon="java"
# Required API keys for providers configured in .taskmaster/config.json
ANTHROPIC_API_KEY=sk-ant-api03-your-key-here
PERPLEXITY_API_KEY=pplx-your-key-here
# OPENAI_API_KEY=sk-your-key-here
# GOOGLE_API_KEY=AIzaSy...
# AZURE_OPENAI_API_KEY=your-azure-openai-api-key-here
# etc.
# Optional Endpoint Overrides
# Use a specific provider's base URL, e.g., for an OpenAI-compatible API
# OPENAI_BASE_URL=https://api.third-party.com/v1
#
# Azure OpenAI Configuration
# AZURE_OPENAI_ENDPOINT=https://your-resource-name.openai.azure.com/ or https://your-endpoint-name.cognitiveservices.azure.com/openai/deployments
# OLLAMA_BASE_URL=http://custom-ollama-host:11434/api
# Google Vertex AI Configuration (Required if using 'vertex' provider)
# VERTEX_PROJECT_ID=your-gcp-project-id
```
## What Else Can Be Configured?
The main configuration file (`.taskmaster/config.json`) allows you to control nearly every aspect of Task Masters behavior. Heres a high-level look at what you can customize:
<Tip>
You dont need to configure everything up front. Most settings can be left as defaults or updated later as your workflow evolves.
</Tip>
<Accordion title="View Configuration Options">
### Models and Providers
- Role-based model setup: `main`, `research`, `fallback`
- Provider selection (Anthropic, OpenAI, Perplexity, etc.)
- Model IDs per role
- Temperature, max tokens, and other generation settings
- Custom base URLs for OpenAI-compatible APIs
### Global Settings
- `logLevel`: Logging verbosity
- `debug`: Enable/disable debug mode
- `projectName`: Optional name for your project
- `defaultTag`: Default tag for task grouping
- `defaultSubtasks`: Number of subtasks to auto-generate
- `defaultPriority`: Priority level for new tasks
### API Endpoint Overrides
- `ollamaBaseURL`: Custom Ollama server URL
- `azureBaseURL`: Global Azure endpoint
- `vertexProjectId`: Google Vertex AI project ID
- `vertexLocation`: Region for Vertex AI models
### Tag and Git Integration
- Default tag context per project
- Support for task isolation by tag
- Manual tag creation from Git branches
### State Management
- Active tag tracking
- Migration state
- Last tag switch timestamp
</Accordion>
<Note>
For advanced configuration options and detailed customization, see our [Advanced Configuration Guide](/docs/best-practices/configuration-advanced) page.
</Note>

View File

@@ -0,0 +1,59 @@
---
title: Executing Tasks
sidebarTitle: "Executing Tasks"
---
Now that your tasks are generated and reviewed you are ready to begin executing.
## Select the Task to Work on: Next Task
Task Master has the "next" command to find the next task to work on. You can access it with the following request:
```
What's the next task I should work on? Please consider dependencies and priorities.
```
Alternatively you can use the CLI to show the next task
```bash
task-master next
```
## Discuss Task
When you know what task to work on next you can then start chatting with the agent to make sure it understands the plan of action.
You can tag relevant files and folders so it knows what context to pull up as it generates its plan. For example:
```
Please review Task 5 and confirm you understand how to execute before beginning. Refer to @models @api and @schema
```
The agent will begin analyzing the task and files and respond with the steps to complete the task.
## Agent Task execution
If you agree with the plan of action, tell the agent to get started.
```
You may begin. I believe in you.
```
## Review and Test
Once the agent is finished with the task you can refer to the task testing strategy to make sure it was completed correctly.
## Update Task Status
If the task was completed correctly you can update the status to done
```
Please mark Task 5 as done
```
The agent will execute
```bash
task-master set-status --id=5 --status=done
```
## Rules and Context
If you ran into problems and had to debug errors you can create new rules as you go. This helps build context on your codebase that helps the creation and execution of future tasks.
## On to the Next Task!
By now you have all you need to get started executing code faster and smarter with Task Master.
If you have any questions please check out [Frequently Asked Questions](/docs/getting-started/faq)

View File

@@ -0,0 +1,159 @@
---
title: Installation
sidebarTitle: "Installation"
---
Now that you have Node.js and your first API Key, you are ready to begin installing Task Master in one of three ways.
<Note>Cursor Users Can Use the One Click Install Below</Note>
<Accordion title="Quick Install for Cursor 1.0+ (One-Click)">
<a href="cursor://anysphere.cursor-deeplink/mcp/install?name=task-master-ai&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIi0tcGFja2FnZT10YXNrLW1hc3Rlci1haSIsInRhc2stbWFzdGVyLWFpIl0sImVudiI6eyJBTlRIUk9QSUNfQVBJX0tFWSI6IllPVVJfQU5USFJPUElDX0FQSV9LRVlfSEVSRSIsIlBFUlBMRVhJVFlfQVBJX0tFWSI6IllPVVJfUEVSUExFWElUWV9BUElfS0VZX0hFUkUiLCJPUEVOQUlfQVBJX0tFWSI6IllPVVJfT1BFTkFJX0tFWV9IRVJFIiwiR09PR0xFX0FQSV9LRVkiOiJZT1VSX0dPT0dMRV9LRVlfSEVSRSIsIk1JU1RSQUxfQVBJX0tFWSI6IllPVVJfTUlTVFJBTF9LRVlfSEVSRSIsIk9QRU5ST1VURVJfQVBJX0tFWSI6IllPVVJfT1BFTlJPVVRFUl9LRVlfSEVSRSIsIlhBSV9BUElfS0VZIjoiWU9VUl9YQUlfS0VZX0hFUkUiLCJBWlVSRV9PUEVOQUJFX0FQSV9LRVkiOiJZT1VSX0FaVVJFX0tFWV9IRVJFIiwiT0xMQU1BX0FQSV9LRVkiOiJZT1VSX09MTEFNQV9BUElfS0VZX0hFUkUifX0%3D">
<img
className="block dark:hidden"
src="https://cursor.com/deeplink/mcp-install-light.png"
alt="Add Task Master MCP server to Cursor"
noZoom
/>
<img
className="hidden dark:block"
src="https://cursor.com/deeplink/mcp-install-dark.png"
alt="Add Task Master MCP server to Cursor"
noZoom
/>
</a>
Or click the copy button (top-right of code block) then paste into your browser:
```text
cursor://anysphere.cursor-deeplink/mcp/install?name=taskmaster-ai&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIi0tcGFja2FnZT10YXNrLW1hc3Rlci1haSIsInRhc2stbWFzdGVyLWFpIl0sImVudiI6eyJBTlRIUk9QSUNfQVBJX0tFWSI6IllPVVJfQU5USFJPUElDX0FQSV9LRVlfSEVSRSIsIlBFUlBMRVhJVFlfQVBJX0tFWSI6IllPVVJfUEVSUExFWElUWV9BUElfS0VZX0hFUkUiLCJPUEVOQUlfQVBJX0tFWSI6IllPVVJfT1BFTkFJX0tFWV9IRVJFIiwiR09PR0xFX0FQSV9LRVkiOiJZT1VSX0dPT0dMRV9LRVlfSEVSRSIsIk1JU1RSQUxfQVBJX0tFWSI6IllPVVJfTUlTVFJBTF9LRVlfSEVSRSIsIk9QRU5ST1VURVJfQVBJX0tFWSI6IllPVVJfT1BFTlJPVVRFUl9LRVlfSEVSRSIsIlhBSV9BUElfS0VZIjoiWU9VUl9YQUlfS0VZX0hFUkUiLCJBWlVSRV9PUEVOQUlfQVBJX0tFWSI6IllPVVJfQVpVUkVfS0VZX0hFUkUiLCJPTExBTUFfQVBJX0tFWSI6IllPVVJfT0xMQU1BX0FQSV9LRVlfSEVSRSJ9fQo=
```
> **Note:** After clicking the link, you'll still need to add your API keys to the configuration. The link installs the MCP server with placeholder keys that you'll need to replace with your actual API keys.
</Accordion>
## Installation Options
<Accordion title="Option 1: MCP (Recommended)">
MCP (Model Control Protocol) lets you run Task Master directly from your editor.
## 1. Add your MCP config at the following path depending on your editor
| Editor | Scope | Linux/macOS Path | Windows Path | Key |
| ------------ | ------- | ------------------------------------- | ------------------------------------------------- | ------------ |
| **Cursor** | Global | `~/.cursor/mcp.json` | `%USERPROFILE%\.cursor\mcp.json` | `mcpServers` |
| | Project | `<project_folder>/.cursor/mcp.json` | `<project_folder>\.cursor\mcp.json` | `mcpServers` |
| **Windsurf** | Global | `~/.codeium/windsurf/mcp_config.json` | `%USERPROFILE%\.codeium\windsurf\mcp_config.json` | `mcpServers` |
| **VS Code** | Project | `<project_folder>/.vscode/mcp.json` | `<project_folder>\.vscode\mcp.json` | `servers` |
## Manual Configuration
### Cursor & Windsurf (`mcpServers`)
```json
{
"mcpServers": {
"taskmaster-ai": {
"command": "npx",
"args": ["-y", "--package=task-master-ai", "task-master-ai"],
"env": {
"ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY_HERE",
"PERPLEXITY_API_KEY": "YOUR_PERPLEXITY_API_KEY_HERE",
"OPENAI_API_KEY": "YOUR_OPENAI_KEY_HERE",
"GOOGLE_API_KEY": "YOUR_GOOGLE_KEY_HERE",
"MISTRAL_API_KEY": "YOUR_MISTRAL_KEY_HERE",
"OPENROUTER_API_KEY": "YOUR_OPENROUTER_KEY_HERE",
"XAI_API_KEY": "YOUR_XAI_KEY_HERE",
"AZURE_OPENAI_API_KEY": "YOUR_AZURE_KEY_HERE",
"OLLAMA_API_KEY": "YOUR_OLLAMA_API_KEY_HERE"
}
}
}
}
```
> 🔑 Replace `YOUR_…_KEY_HERE` with your real API keys. You can remove keys you don't use.
> **Note**: If you see `0 tools enabled` in the MCP settings, try removing the `--package=task-master-ai` flag from `args`.
### VS Code (`servers` + `type`)
```json
{
"servers": {
"taskmaster-ai": {
"command": "npx",
"args": ["-y", "--package=task-master-ai", "task-master-ai"],
"env": {
"ANTHROPIC_API_KEY": "YOUR_ANTHROPIC_API_KEY_HERE",
"PERPLEXITY_API_KEY": "YOUR_PERPLEXITY_API_KEY_HERE",
"OPENAI_API_KEY": "YOUR_OPENAI_KEY_HERE",
"GOOGLE_API_KEY": "YOUR_GOOGLE_KEY_HERE",
"MISTRAL_API_KEY": "YOUR_MISTRAL_KEY_HERE",
"OPENROUTER_API_KEY": "YOUR_OPENROUTER_KEY_HERE",
"XAI_API_KEY": "YOUR_XAI_KEY_HERE",
"AZURE_OPENAI_API_KEY": "YOUR_AZURE_KEY_HERE"
},
"type": "stdio"
}
}
}
```
> 🔑 Replace `YOUR_…_KEY_HERE` with your real API keys. You can remove keys you don't use.
#### 2. (Cursor-only) Enable Taskmaster MCP
Open Cursor Settings (Ctrl+Shift+J) ➡ Click on MCP tab on the left ➡ Enable task-master-ai with the toggle
#### 3. (Optional) Configure the models you want to use
In your editor's AI chat pane, say:
```txt
Change the main, research and fallback models to <model_name>, <model_name> and <model_name> respectively.
```
For example, to use Claude Code (no API key required):
```txt
Change the main model to claude-code/sonnet
```
#### 4. Initialize Task Master
In your editor's AI chat pane, say:
```txt
Initialize taskmaster-ai in my project
```
</Accordion>
<Accordion title="Option 2: Using Command Line">
## CLI Installation
```bash
# Install globally
npm install -g task-master-ai
# OR install locally within your project
npm install task-master-ai
```
## Initialize a new project
```bash
# If installed globally
task-master init
# If installed locally
npx task-master init
# Initialize project with specific rules
task-master init --rules cursor,windsurf,vscode
```
This will prompt you for project details and set up a new project with the necessary files and structure.
</Accordion>

View File

@@ -0,0 +1,4 @@
---
title: Moving Forward
sidebarTitle: "Moving Forward"
---

View File

@@ -0,0 +1,81 @@
---
title: PRD Creation and Parsing
sidebarTitle: "PRD Creation and Parsing"
---
# Writing a PRD
A PRD (Product Requirements Document) is the starting point of every task flow in Task Master. It defines what you're building and why. A clear PRD dramatically improves the quality of your tasks, your model outputs, and your final product — so its worth taking the time to get it right.
<Tip>
You dont need to define your whole app up front. You can write a focused PRD just for the next feature or module youre working on.
</Tip>
<Tip>
You can start with an empty project or you can start with a feature PRD on an existing project.
</Tip>
<Tip>
You can add and parse multiple PRDs per project using the --append flag
</Tip>
## What Makes a Good PRD?
- Clear objective — whats the outcome or feature?
- Context — whats already in place or assumed?
- Constraints — what limits or requirements need to be respected?
- Reasoning — why are you building it this way?
The more context you give the model, the better the breakdown and results.
---
## Writing a PRD for Task Master
<Note>An example PRD can be found in .taskmaster/templates/example_prd.txt</Note>
You can co-write your PRD with an LLM model using the following workflow:
1. **Chat about requirements** — explain what you want to build.
2. **Show an example PRD** — share the example PRD so the model understands the expected format. The example uses formatting that work well with Task Master's code. Following the example will yield better results.
3. **Iterate and refine** — work with the model to shape the draft into a clear and well-structured PRD.
This approach works great in Cursor, or anywhere you use a chat-based LLM.
---
## Where to Save Your PRD
Place your PRD file in the `.taskmaster/docs` folder in your project.
- You can have **multiple PRDs** per project.
- Name your PRDs clearly so theyre easy to reference later.
- Examples: `dashboard_redesign.txt`, `user_onboarding.txt`
---
# Parse your PRD into Tasks
This is where the Task Master magic begins.
In Cursor's AI chat, instruct the agent to generate tasks from your PRD:
```
Please use the task-master parse-prd command to generate tasks from my PRD. The PRD is located at .taskmaster/docs/<prd-name>.txt.
```
The agent will execute the following command which you can alternatively paste into the CLI:
```bash
task-master parse-prd .taskmaster/docs/<prd-name>.txt
```
This will:
- Parse your PRD document
- Generate a structured `tasks.json` file with tasks, dependencies, priorities, and test strategies
Now that you have written and parsed a PRD, you are ready to start setting up your tasks.

View File

@@ -0,0 +1,19 @@
---
title: Quick Start
sidebarTitle: "Quick Start"
---
This guide is for new users who want to start using Task Master with minimal setup time.
It covers:
- [Requirements](/docs/getting-started/quick-start/requirements): You will need Node.js and an AI model API Key.
- [Installation](/docs/getting-started/quick-start/installation): How to Install Task Master.
- [Configuration](/docs/getting-started/quick-start/configuration-quick): Setting up your API Key, MCP, and more.
- [PRD](/docs/getting-started/quick-start/prd-quick): Writing and parsing your first PRD.
- [Task Setup](/docs/getting-started/quick-start/tasks-quick): Preparing your tasks for execution.
- [Executing Tasks](/docs/getting-started/quick-start/execute-quick): Using Task Master to execute tasks.
- [Rules & Context](/docs/getting-started/quick-start/rules-quick): Learn how and why to build context in your project over time.
<Tip>
By the end of this guide, you'll have everything you need to begin working productively with Task Master.
</Tip>

View File

@@ -0,0 +1,50 @@
---
title: Requirements
sidebarTitle: "Requirements"
---
Before you can start using TaskMaster AI, you'll need to install Node.js and set up at least one model API Key.
## 1. Node.js
TaskMaster AI is built with Node.js and requires it to run. npm (Node Package Manager) comes bundled with Node.js.
<Accordion title="Install Node.js">
### Installation
**Option 1: Download from official website**
1. Visit [nodejs.org](https://nodejs.org)
2. Download the **LTS (Long Term Support)** version for your operating system
3. Run the installer and follow the setup wizard
**Option 2: Use a package manager**
<CodeGroup>
```bash Windows (Chocolatey)
choco install nodejs
```
```bash Windows (winget)
winget install OpenJS.NodeJS
```
</CodeGroup>
</Accordion>
## 2. Model API Key
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).
<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>
At least one (1) of the following is required:
1. Anthropic API key (Claude API) - **recommended for Quick Start**
2. OpenAI API key
3. Google Gemini API key
4. Perplexity API key (for research model)
5. xAI API Key (for research or main model)
6. OpenRouter API Key (for research or main model)
7. Claude Code (no API key required - requires Claude Code CLI)

View File

@@ -0,0 +1,4 @@
---
title: Rules and Context
sidebarTitle: "Rules and Context"
---

View File

@@ -0,0 +1,69 @@
---
title: Tasks Setup
sidebarTitle: "Tasks Setup"
---
Now that your tasks are generated you can review the plan and prepare for execution.
<Tip>
Not all of the setup steps are required but they are recommended in order to ensure your coding agents work on accurate tasks.
</Tip>
## Expand Tasks
Used to add detail to tasks and create subtasks. We recommend expanding all tasks using the MCP request below:
```
Expand all tasks into subtasks.
```
The agent will execute
```bash
task-master expand --all
```
## List/Show Tasks
Used to view task details. It is important to review the plan and ensure it makes sense in your project. Check for correct folder structures, dependencies, out of scope subtasks, etc.
To see a list of tasks and descriptions use the following command:
```
List all pending tasks so I can review.
```
To see all tasks in the CLI you can use:
```bash
task-master list
```
To see all implementation details of an individual task, including subtasks and testing strategy, you can use Show Task:
```
Show task 2 so I can review.
```
```bash
task-master show --id=<##>
```
## Update Tasks
If the task details need to be edited you can update the task using this request:
```
Update Task 2 to use Postgres instead of MongoDB and remove the sharding subtask
```
Or this CLI command:
```bash
task-master update-task --id=2 --prompt="use Postgres instead of MongoDB and remove the sharding subtask"
```
## Analyze complexity
Task Master can provide a complexity report which can be helpful to read before you begin. If you didn't already expand all your tasks, it could help identify which could be broken down further with subtasks.
```
Can you analyze the complexity of our tasks to help me understand which ones need to be broken down further?
```
You can view the report in a friendly table using:
```
Can you show me the complexity report in a more readable format?
```
<Check>Now you are ready to begin [executing tasks](/docs/getting-started/quick-start/execute-quick)</Check>

View File

@@ -0,0 +1,20 @@
<Tip>
Welcome to v1 of the Task Master Docs. Expect weekly updates as we expand and refine each section.
</Tip>
We've organized the docs into three sections depending on your experience level and goals:
### Getting Started - Jump in to [Quick Start](/docs/getting-started/quick-start)
Designed for first-time users. Get set up, create your first PRD, and run your first task.
### Best Practices
Covers common workflows, strategic usage of commands, model configuration tips, and real-world usage patterns. Recommended for active users.
### Technical Capabilities
A detailed glossary of every root command and available capability — meant for power users and contributors.
---
Thanks for being here early. If you spot something broken or want to contribute, check out the [GitHub repo](https://github.com/eyaltoledano/claude-task-master).
Have questions? Join our [Discord community](https://discord.gg/fWJkU7rf) to connect with other users and get help from the team.

Some files were not shown because too many files have changed in this diff Show More