From bb5a0211f4970f6ae2bf4c6dff71f7f9b99244ba Mon Sep 17 00:00:00 2001 From: Eyal Toledano Date: Sun, 25 May 2025 03:51:51 -0400 Subject: [PATCH] feat: implement research command with enhanced context gathering - Add comprehensive research command with AI-powered queries - Implement ContextGatherer utility for reusable context extraction - Support multiple context types: tasks, files, custom text, project tree - Add fuzzy search integration for automatic task discovery - Implement detailed token breakdown display with syntax highlighting - Add enhanced UI with boxed output and code block formatting - Support different detail levels (low, medium, high) for responses - Include project-specific context for more relevant AI responses - Add token counting with gpt-tokens library integration - Create reusable patterns for future context-aware commands - Task 94.4 completed --- .changeset/bright-windows-sing.md | 6 +- .taskmaster/tasks/task_045.txt | 222 +++++----------- .taskmaster/tasks/task_098.txt | 209 ++++++++++++++- .taskmaster/tasks/tasks.json | 315 +++++++++++++++++++++-- package.json | 5 +- scripts/modules/commands.js | 4 +- scripts/modules/task-manager.js | 4 +- scripts/modules/ui.js | 5 + scripts/modules/utils/fuzzyTaskSearch.js | 6 +- 9 files changed, 563 insertions(+), 213 deletions(-) diff --git a/.changeset/bright-windows-sing.md b/.changeset/bright-windows-sing.md index f3b3f42a..a8ab6c08 100644 --- a/.changeset/bright-windows-sing.md +++ b/.changeset/bright-windows-sing.md @@ -1,5 +1,5 @@ --- -'task-master-ai': minor +"task-master-ai": minor --- Add comprehensive AI-powered research command with intelligent context gathering and interactive follow-ups. @@ -7,6 +7,7 @@ Add comprehensive AI-powered research command with intelligent context gathering The new `research` command provides AI-powered research capabilities that automatically gather relevant project context to answer your questions. The command intelligently selects context from multiple sources and supports interactive follow-up questions in CLI mode. **Key Features:** + - **Intelligent Task Discovery**: Automatically finds relevant tasks and subtasks using fuzzy search based on your query keywords, supplementing any explicitly provided task IDs - **Multi-Source Context**: Gathers context from tasks, files, project structure, and custom text to provide comprehensive answers - **Interactive Follow-ups**: CLI users can ask follow-up questions that build on the conversation history while allowing fresh context discovery for each question @@ -15,6 +16,7 @@ The new `research` command provides AI-powered research capabilities that automa - **Enhanced Display**: Syntax-highlighted code blocks and structured output with clear visual separation **Usage Examples:** + ```bash # Basic research with auto-discovered context task-master research "How should I implement user authentication?" @@ -30,12 +32,14 @@ task-master research "Quick implementation steps?" --context="Using JWT tokens" ``` **Context Sources:** + - **Tasks**: Automatically discovers relevant tasks/subtasks via fuzzy search, plus any explicitly specified via `--id` - **Files**: Include specific files via `--files` for code-aware responses - **Project Tree**: Add `--tree` to include project structure overview - **Custom Context**: Provide additional context via `--context` for domain-specific information **Interactive Features (CLI only):** + - Follow-up questions that maintain conversation history - Fresh fuzzy search for each follow-up to discover newly relevant tasks - Cumulative context building across the conversation diff --git a/.taskmaster/tasks/task_045.txt b/.taskmaster/tasks/task_045.txt index 3cc1ff5d..97644b10 100644 --- a/.taskmaster/tasks/task_045.txt +++ b/.taskmaster/tasks/task_045.txt @@ -1,134 +1,82 @@ # Task ID: 45 # Title: Implement GitHub Issue Import Feature # Status: pending -# Dependencies: None +# Dependencies: 97 # Priority: medium -# Description: Implement a comprehensive LLM-powered 'import_task' command that can intelligently import tasks from GitHub Issues and Discussions. The system uses our existing ContextGatherer.js infrastructure to analyze the full context of GitHub content and automatically generate well-structured tasks with appropriate subtasks, priorities, and implementation details. This feature works in conjunction with the GitHub export feature (Task #97) to provide bidirectional linking between Task Master tasks and GitHub issues. +# Description: Add a '--from-github' flag to the add-task command that accepts a GitHub issue URL and automatically generates a corresponding task with relevant details. This feature works in conjunction with the GitHub export feature (Task #97) to provide bidirectional linking between Task Master tasks and GitHub issues. # Details: -Implement a new 'import_task' command that leverages LLM-powered analysis to create comprehensive tasks from GitHub Issues and Discussions. The system should be designed as an extensible import framework that can support multiple platforms in the future. +Implement a new flag '--from-github' for the add-task command that allows users to create tasks directly from GitHub issues. The implementation should work seamlessly with the GitHub export feature (Task #97) to provide bidirectional linking capabilities. Core functionality: -1. **New Command Structure**: Create 'import_task' command with source-specific subcommands: - - 'taskmaster import_task github ' for GitHub imports - - Future: 'taskmaster import_task gitlab ', 'taskmaster import_task linear ', etc. +1. Accept a GitHub issue URL as an argument (e.g., 'taskmaster add-task --from-github https://github.com/owner/repo/issues/123') +2. Parse the URL to extract the repository owner, name, and issue number +3. Use the GitHub API to fetch the issue details including: + - Issue title (to be used as task title) + - Issue description (to be used as task description) + - Issue labels (to be potentially used as tags) + - Issue assignees (for reference) + - Issue status (open/closed) +4. Generate a well-formatted task with this information +5. **Automatically add GitHub link metadata** using the same schema as the export feature: + - Store the source GitHub issue URL in task metadata + - Use consistent metadata structure with export feature for bidirectional compatibility + - Enable future synchronization capabilities +6. Include a reference link back to the original GitHub issue in the task description +7. Handle authentication for private repositories using GitHub tokens from environment variables or config file +8. Implement proper error handling for: + - Invalid URLs + - Non-existent issues + - API rate limiting + - Authentication failures + - Network issues +9. **Validate GitHub links** during import to ensure they point to valid, accessible issues +10. Allow users to override or supplement the imported details with additional command-line arguments +11. Add appropriate documentation in help text and user guide, including information about the complementary export feature -2. **Multi-Source GitHub Support**: Automatically detect and handle: - - GitHub Issues: https://github.com/owner/repo/issues/123 - - GitHub Discussions: https://github.com/owner/repo/discussions/456 - - Auto-detect URL type and use appropriate API endpoints - -3. **LLM-Powered Context Analysis**: Integrate with ContextGatherer.js to: - - Fetch complete GitHub content (main post + all comments/replies) - - Analyze discussion threads and extract key insights - - Identify references to our project components and codebase - - Generate comprehensive task descriptions based on full context - - Automatically create relevant subtasks from complex discussions - - Determine appropriate priority levels based on content analysis - - Suggest dependencies based on mentioned components/features - -4. **Smart Content Processing**: The LLM should: - - Parse markdown content and preserve important formatting - - Extract actionable items from discussion threads - - Identify implementation requirements and technical details - - Convert complex discussions into structured task breakdowns - - Generate appropriate test strategies based on the scope - - Preserve important context while creating focused task descriptions - -5. **Enhanced GitHub API Integration**: - - Support GITHUB_API_KEY environment variable for authentication - - Handle both public and private repository access - - Fetch issue/discussion metadata (labels, assignees, status) - - Retrieve complete comment threads with proper threading - - Implement rate limiting and error handling - -6. **Rich Metadata Storage**: - - Source platform and original URL - - Import timestamp and LLM model version used - - Content hash for change detection and sync capabilities - - Participant information and discussion context - - GitHub-specific metadata (labels, assignees, status) - - **Use consistent metadata schema with export feature (Task #97)** - -7. **Future-Proof Architecture**: - - Modular design supporting multiple import sources - - Plugin-style architecture for new platforms - - Extensible content type handling (issues, PRs, discussions, etc.) - - Configurable LLM prompts for different content types - -8. **Bidirectional Integration**: - - Maintain compatibility with GitHub export feature - - Enable round-trip workflows (import → modify → export) - - Preserve source linking for synchronization capabilities - - Support identification of imported vs. native tasks - -9. **Error Handling and Validation**: - - Validate GitHub URLs and accessibility - - Handle API rate limiting gracefully - - Provide meaningful error messages for various failure scenarios - - Implement retry logic for transient failures - - Validate LLM responses and handle generation errors - -10. **Configuration and Customization**: - - Allow users to customize LLM prompts for task generation - - Support different import strategies (full vs. summary) - - Enable filtering of comments by date, author, or relevance - - Provide options for manual review before task creation +Bidirectional Integration: +- Use the same metadata schema as Task #97 for GitHub links +- Ensure imported tasks can be identified as GitHub-linked for future export operations +- Prepare infrastructure for future synchronization between tasks and their source issues +- Maintain consistency with export feature's link management approach # Test Strategy: Testing should cover the comprehensive LLM-powered import system: -1. **Unit Tests**: - - Test URL parsing for GitHub Issues and Discussions - - Test GitHub API client with mocked responses - - Test LLM integration with ContextGatherer.js - - Test metadata schema consistency with export feature - - Test content processing and task generation logic - - Test error handling for various failure scenarios +1. Unit tests: + - Test URL parsing functionality with valid and invalid GitHub issue URLs + - Test GitHub API response parsing with mocked API responses + - Test error handling for various failure cases + - **Test metadata schema consistency with export feature** + - **Test GitHub link validation functionality** -2. **Integration Tests**: - - Test with real GitHub Issues and Discussions (public repos) - - Test LLM-powered analysis with various content types - - Test ContextGatherer integration with GitHub content - - Test bidirectional compatibility with export feature - - Test metadata structure and storage - - Test with different GitHub content complexities +2. Integration tests: + - Test with real GitHub public issues (use well-known repositories) + - Test with both open and closed issues + - Test with issues containing various elements (labels, assignees, comments) + - **Test bidirectional compatibility with export feature** + - **Verify metadata structure matches export feature requirements** -3. **LLM and Context Analysis Tests**: - - Test task generation quality with various GitHub content types - - Test subtask creation from complex discussions - - Test priority and dependency inference - - Test handling of code references and technical discussions - - Test content summarization and structure preservation - - Validate LLM prompt effectiveness and response quality - -4. **Error Case Tests**: - - Invalid or malformed GitHub URLs - - Non-existent repositories or issues/discussions - - API rate limit handling +3. Error case tests: + - Invalid URL format + - Non-existent repository + - Non-existent issue number + - API rate limit exceeded - Authentication failures for private repos - - LLM service unavailability or errors - - Network connectivity issues - - Malformed or incomplete GitHub content + - **Invalid or inaccessible GitHub links** -5. **End-to-End Tests**: - - Complete import workflow from GitHub URL to created task - - Verify task quality and completeness - - Test metadata preservation and linking - - Test compatibility with existing task management features - - Verify bidirectional workflow with export feature +4. End-to-end tests: + - Verify that a task created from a GitHub issue contains all expected information + - **Verify that imported tasks contain proper GitHub link metadata** + - Verify that the task can be properly managed after creation + - Test the interaction with other flags and commands + - **Test compatibility with export feature workflows** -6. **Performance and Scalability Tests**: - - Test with large GitHub discussions (many comments) - - Test LLM processing time and resource usage - - Test API rate limiting behavior - - Test concurrent import operations +5. **Bidirectional feature tests**: + - Import a GitHub issue and verify it can be exported back + - Test metadata consistency between import and export operations + - Verify link validation works correctly -7. **Future Platform Preparation Tests**: - - Test modular architecture extensibility - - Verify plugin-style platform addition capability - - Test configuration system flexibility - -Create comprehensive mock data for GitHub API responses including various issue/discussion types, comment structures, and edge cases. Use environment variables for test credentials and LLM service configuration. +Create mock GitHub API responses for testing to avoid hitting rate limits during development and testing. Use environment variables to configure test credentials if needed. # Subtasks: ## 1. Design GitHub API integration architecture [pending] @@ -173,51 +121,3 @@ Design and implement metadata structure that matches the export feature (Task #9 ### Details: Verify that tasks imported from GitHub can be properly exported back to GitHub. Implement checks to prevent duplicate exports of imported issues. Add metadata flags to identify imported tasks and their source repositories. Test round-trip workflows (import → modify → export) to ensure data integrity. -## 8. Design extensible import_task command architecture [pending] -### Dependencies: None -### Description: Create the foundational architecture for the new import_task command that supports multiple platforms and content types. -### Details: -Design modular command structure with platform-specific subcommands. Create plugin-style architecture for adding new import sources. Define interfaces for different content types (issues, discussions, PRs). Plan configuration system for platform-specific settings and LLM prompts. Document extensibility patterns for future platform additions. - -## 9. Extend GitHub URL parsing for Issues and Discussions [pending] -### Dependencies: 45.2, 45.8 -### Description: Enhance URL parsing to support both GitHub Issues and Discussions with automatic type detection. -### Details: -Extend existing URL parser to handle GitHub Discussions URLs. Implement automatic detection of content type (issue vs discussion). Update validation logic for both content types. Ensure consistent data extraction for owner, repo, and content ID regardless of type. - -## 10. Implement comprehensive GitHub API client [pending] -### Dependencies: 45.3, 45.9 -### Description: Create enhanced GitHub API client supporting both Issues and Discussions APIs with complete content fetching. -### Details: -Extend existing API client to support GitHub Discussions API. Implement complete content fetching including all comments and replies. Add support for GITHUB_API_KEY environment variable. Handle threaded discussions and comment hierarchies. Implement robust error handling and rate limiting for both API types. - -## 11. Integrate ContextGatherer for LLM-powered analysis [pending] -### Dependencies: 45.10 -### Description: Integrate with existing ContextGatherer.js to enable LLM-powered analysis of GitHub content. -### Details: -Adapt ContextGatherer.js to work with GitHub content as input source. Create GitHub-specific context gathering strategies. Implement content preprocessing for optimal LLM analysis. Add project component identification for GitHub discussions. Create prompts for task generation from GitHub content. - -## 12. Implement LLM-powered task generation [pending] -### Dependencies: 45.11 -### Description: Create the core LLM integration that analyzes GitHub content and generates comprehensive tasks with subtasks. -### Details: -Design LLM prompts for task generation from GitHub content. Implement automatic subtask creation from complex discussions. Add priority and dependency inference based on content analysis. Create test strategy generation from technical discussions. Implement quality validation for LLM-generated content. Add fallback mechanisms for LLM failures. - -## 13. Enhance metadata system for rich import context [pending] -### Dependencies: 45.6, 45.12 -### Description: Extend the metadata schema to store comprehensive import context and enable advanced features. -### Details: -Extend existing metadata schema with import-specific fields. Add source platform, import timestamp, and LLM model tracking. Implement content hash storage for change detection. Store participant information and discussion context. Add support for custom metadata per platform type. Ensure backward compatibility with existing export feature metadata. - -## 14. Implement import_task command interface [pending] -### Dependencies: 45.8, 45.12, 45.13 -### Description: Create the user-facing command interface for the new import_task system with GitHub support. -### Details: -Implement the main import_task command with GitHub subcommand. Add command-line argument parsing and validation. Create progress indicators for LLM processing. Implement user review and confirmation workflow. Add verbose output options for debugging. Create help documentation and usage examples. - -## 15. Add comprehensive testing and validation [pending] -### Dependencies: 45.14 -### Description: Implement comprehensive testing suite covering all aspects of the LLM-powered import system. -### Details: -Create unit tests for all new components. Implement integration tests with real GitHub content. Add LLM response validation and quality tests. Create performance tests for large discussions. Implement end-to-end workflow testing. Add mock data for consistent testing. Test bidirectional compatibility with export feature. - diff --git a/.taskmaster/tasks/task_098.txt b/.taskmaster/tasks/task_098.txt index e82a52f9..11d29362 100644 --- a/.taskmaster/tasks/task_098.txt +++ b/.taskmaster/tasks/task_098.txt @@ -26,19 +26,63 @@ - Check help output and usage documentation for accuracy and completeness. # Subtasks: -## 1. Command Registration [in-progress] +## 1. Command Registration [done] ### Dependencies: None ### Description: Register the 'research' command with the CLI framework, ensuring it appears in the list of available commands and supports standard CLI conventions. ### Details: Integrate the new command into the CLI's command registry. Ensure it is discoverable via the CLI's help system and follows established naming and grouping conventions. -## 2. Parameter and Flag Handling [pending] +## 2. Parameter and Flag Handling [done] ### Dependencies: 94.1 ### Description: Define and implement parsing for all arguments, flags, and options accepted by the 'research' command, including validation and default values. ### Details: Use a command-line parsing framework to handle parameters. Ensure support for optional and required arguments, order-independence, and clear error messages for invalid input. + +✅ **Parameter and Flag Handling Implementation Complete** -## 3. Context Gathering [pending] +Successfully implemented comprehensive parameter validation and processing for the research command: + +**✅ Implemented Features:** +1. **Comprehensive Parameter Validation:** + - Prompt validation (required, non-empty string) + - Detail level validation (low, medium, high) + - Task ID format validation (supports "15" and "15.2" formats) + - File path validation (comma-separated, existence checks) + - Save target validation (security checks for path traversal) + +2. **Advanced Parameter Processing:** + - Comma-separated value parsing for task IDs and file paths + - Whitespace trimming and normalization + - Project root detection using `findProjectRoot()` + - Relative/absolute path handling for files + - Default value application + +3. **Informative Error Messages:** + - Specific error messages for each validation failure + - Clear examples of correct usage + - Helpful suggestions for fixing errors + - Much more informative than basic Commander.js errors + +4. **Structured Output:** + - Creates validated parameters object with all processed values + - Proper type conversion and normalization + - Ready for consumption by core research function + +**✅ Validation Examples Tested:** +- Missing prompt: Shows Commander.js error (expected behavior) +- Invalid detail level: "Error: Detail level must be one of: low, medium, high" +- Invalid task ID format: "Error parsing task IDs: Invalid task ID format: "invalid_format". Expected format: "15" or "15.2"" +- Valid parameters: Successfully processes and creates structured parameter object + +**✅ Security Features:** +- Path traversal protection for save targets +- File existence validation +- Input sanitization and trimming + +The parameter validation is now production-ready and follows the same patterns used throughout the Task Master codebase. Ready to proceed to subtask 94.3 (Context Gathering Utility). + + +## 3. Context Gathering [done] ### Dependencies: 94.2 ### Description: Implement logic to gather necessary context for the research operation, such as reading from files, stdin, or other sources as specified by the user. ### Details: @@ -90,22 +134,159 @@ const context = await contextGatherer.gather({ This utility will eliminate code duplication between task 51 (explore REPL) and task 94 (research command) while providing a robust, extensible foundation for context gathering operations. + +✅ **Context Gathering Implementation Complete** -## 4. AI Service Integration [pending] -### Dependencies: 94.3 -### Description: Integrate with the AI service to process the gathered context and parameters, handling API calls, authentication, and error management. +Successfully implemented the comprehensive ContextGatherer utility in `scripts/modules/utils/contextGatherer.js`: + +**✅ Core Features Implemented:** + +1. **Task/Subtask Context Extraction:** + - ✅ Parse task IDs and subtask IDs (formats: "15", "15.2", "16,17.1") + - ✅ Extract task titles, descriptions, details, and dependencies from the task system + - ✅ Include parent task context automatically for subtasks + - ✅ Format task data optimally for AI consumption + - ✅ Proper integration with existing `findTaskById` utility function + +2. **File Path Context Processing:** + - ✅ Handle single or comma-separated file paths + - ✅ Implement safe file reading with comprehensive error handling + - ✅ Support multiple file types (JavaScript, markdown, text, JSON, etc.) + - ✅ Include file metadata (path, size, type, last modified) + - ✅ File size limits (50KB max) to prevent context explosion + +3. **Project File Tree Generation:** + - ✅ Create structured project overview with configurable depth (max 3 levels) + - ✅ Filter out irrelevant directories (.git, node_modules, .env files) + - ✅ Include file counts and directory statistics + - ✅ Support custom filtering patterns + +4. **Custom Context Integration:** + - ✅ Accept and merge custom context strings + - ✅ Maintain clear context hierarchy and organization + - ✅ Preserve context source attribution + +5. **Unified API Design:** + - ✅ Clean class-based API with factory function + - ✅ Flexible options object for configuration + - ✅ Multiple output formats (research, chat, system-prompt) + - ✅ Proper error handling and graceful degradation + +**✅ Output Formatting:** +- ✅ Support for 'research', 'chat', and 'system-prompt' formats +- ✅ Consistent context structure across different use cases +- ✅ Optimized for AI model consumption and token efficiency + +**✅ Testing:** +- ✅ Successfully tested with real task data (Task 94 and subtask 94.1) +- ✅ Verified task context extraction works correctly +- ✅ Confirmed proper formatting and structure + +**✅ Integration Ready:** +- ✅ Designed to be shared between task 51 (explore REPL) and task 94 (research command) +- ✅ Follows existing codebase patterns and utilities +- ✅ Proper ES6 module exports for easy importing + +The ContextGatherer utility is now ready for integration into the core research function (subtask 94.4). + + +## 4. Core Function Implementation [done] +### Dependencies: 94.2, 94.3 +### Description: Implement the core research function in scripts/modules/task-manager/ following the add-task.js pattern ### Details: -Establish a robust interface to the AI backend, manage API keys or tokens securely, and handle network or service errors gracefully. +Create a new core function (e.g., research.js) in scripts/modules/task-manager/ that: +- Accepts parameters: query, context options (task IDs, file paths, custom context), project tree flag, detail level +- Implements context gathering using the contextGatherer utility from subtask 94.3 +- Integrates with ai-services-unified.js using research role +- Handles both CLI and MCP output formats +- Returns structured results with telemetry data +- Follows the same parameter validation and error handling patterns as add-task.js + +✅ COMPLETED: Added loading spinner to research command -## 5. Output Formatting [pending] +**Implementation Details:** +- Imported `startLoadingIndicator` and `stopLoadingIndicator` from ui.js +- Added loading indicator that shows "Researching with AI..." during AI service calls +- Properly wrapped AI service call in try/catch/finally blocks to ensure spinner stops on both success and error +- Loading indicator only shows in CLI mode (outputFormat === 'text'), not in MCP mode +- Follows the same pattern as add-task.js for consistent user experience + +**Testing:** +- Tested with `node bin/task-master.js research "What is TypeScript?" --detail=low` +- Confirmed spinner appears during AI processing and disappears when complete +- Telemetry display works correctly after spinner stops + +The research command now provides the same polished user experience as other AI-powered commands in the system. + + +## 5. Direct Function Implementation [pending] ### Dependencies: 94.4 -### Description: Format the AI-generated output according to user-specified modes (e.g., plain text, JSON), and support writing to stdout or files. +### Description: Create the MCP direct function wrapper in mcp-server/src/core/direct-functions/ following the add-task pattern ### Details: -Implement flexible output formatting, ensuring compatibility with piping and redirection. Provide clear, user-friendly output and support for machine-readable formats. +Create a new direct function (e.g., research.js) in mcp-server/src/core/direct-functions/ that: +- Follows the addTaskDirect pattern for parameter handling and error management +- Uses enableSilentMode/disableSilentMode to prevent console output interference +- Creates logger wrapper using createLogWrapper utility +- Validates required parameters (query, projectRoot) +- Calls the core research function with proper context (session, mcpLog, projectRoot) +- Returns standardized result object with success/error structure +- Handles telemetry data propagation +- Export and register in task-master-core.js -## 6. Documentation and Help [pending] -### Dependencies: 94.1, 94.2, 94.3, 94.4, 94.5 -### Description: Document the 'research' command, including usage examples, parameter descriptions, and integration with the CLI's --help system. +## 6. MCP Tool Implementation [pending] +### Dependencies: 94.5 +### Description: Create the MCP tool in mcp-server/src/tools/ following the add-task tool pattern ### Details: -Update CLI documentation and ensure the --help flag provides comprehensive guidance on using the command, its options, and expected outputs. +Create a new MCP tool (e.g., research.js) in mcp-server/src/tools/ that: +- Defines zod schema for all research command parameters (query, id, files, context, project-tree, save, detail) +- Uses withNormalizedProjectRoot HOF to handle project path normalization +- Calls findTasksJsonPath to locate tasks.json file +- Invokes the direct function with proper parameter mapping +- Uses handleApiResult for standardized response formatting +- Registers the tool as 'research' (snake_case) in the MCP server +- Handles errors with createErrorResponse +- Register in mcp-server/src/tools/index.js +- Update .cursor/mcp.json with tool definition + +## 7. Add research save-to-file functionality [pending] +### Dependencies: None +### Description: Implement functionality to save research results to /research/ folder with optional interactive prompts +### Details: +Add capability to save research results to files in a /research/ directory at project root. For CLI mode, use inquirer to prompt user if they want to save the research. For MCP mode, accept a saveToFile parameter. + +Key implementation details: +- Create /research/ directory if it doesn't exist (similar to how tasks/ is handled) +- Generate meaningful filenames based on query and timestamp +- Support both CLI interactive mode (inquirer prompts) and MCP parameter mode +- Follow project root detection pattern from add-task.js stack +- Handle file writing with proper error handling +- Return saved file path in response for confirmation + +File structure: +- /research/YYYY-MM-DD_query-summary.md (markdown format) +- Include query, timestamp, context used, and full AI response +- Add metadata header with query details and context sources + +## 8. Add research-to-task linking functionality [pending] +### Dependencies: 94.7 +### Description: Implement functionality to link saved research to specific tasks with interactive task selection +### Details: +Add capability to link research results to specific tasks by updating task details with research references. For CLI mode, use inquirer to prompt user if they want to link research to tasks and provide task selection. For MCP mode, accept linkToTasks parameter. + +Key implementation details: +- Prompt user if they want to link research to existing tasks (CLI mode) +- Provide task selection interface using inquirer with task list (ID, title, status) +- Support multiple task selection (checkbox interface) +- Update selected tasks' details section with research reference +- Add timestamped research link in format: "Research: [Query Title](file:///path/to/research.md) - YYYY-MM-DD" +- Follow add-task.js pattern for task file updates and regeneration +- Handle task.json reading/writing with proper error handling +- Support both single and multiple task linking +- Return list of updated task IDs in response + +Research link format in task details: +``` +## Research References +- [How to implement authentication](file:///research/2024-01-15_authentication-research.md) - 2024-01-15 +``` diff --git a/.taskmaster/tasks/tasks.json b/.taskmaster/tasks/tasks.json index f7d15930..b91c22d3 100644 --- a/.taskmaster/tasks/tasks.json +++ b/.taskmaster/tasks/tasks.json @@ -2712,12 +2712,14 @@ { "id": 45, "title": "Implement GitHub Issue Import Feature", - "description": "Add a '--from-github' flag to the add-task command that accepts a GitHub issue URL and automatically generates a corresponding task with relevant details.", + "description": "Add a '--from-github' flag to the add-task command that accepts a GitHub issue URL and automatically generates a corresponding task with relevant details. This feature works in conjunction with the GitHub export feature (Task #97) to provide bidirectional linking between Task Master tasks and GitHub issues.", "status": "pending", - "dependencies": [], + "dependencies": [ + 97 + ], "priority": "medium", - "details": "Implement a new flag '--from-github' for the add-task command that allows users to create tasks directly from GitHub issues. The implementation should:\n\n1. Accept a GitHub issue URL as an argument (e.g., 'taskmaster add-task --from-github https://github.com/owner/repo/issues/123')\n2. Parse the URL to extract the repository owner, name, and issue number\n3. Use the GitHub API to fetch the issue details including:\n - Issue title (to be used as task title)\n - Issue description (to be used as task description)\n - Issue labels (to be potentially used as tags)\n - Issue assignees (for reference)\n - Issue status (open/closed)\n4. Generate a well-formatted task with this information\n5. Include a reference link back to the original GitHub issue\n6. Handle authentication for private repositories using GitHub tokens from environment variables or config file\n7. Implement proper error handling for:\n - Invalid URLs\n - Non-existent issues\n - API rate limiting\n - Authentication failures\n - Network issues\n8. Allow users to override or supplement the imported details with additional command-line arguments\n9. Add appropriate documentation in help text and user guide", - "testStrategy": "Testing should cover the following scenarios:\n\n1. Unit tests:\n - Test URL parsing functionality with valid and invalid GitHub issue URLs\n - Test GitHub API response parsing with mocked API responses\n - Test error handling for various failure cases\n\n2. Integration tests:\n - Test with real GitHub public issues (use well-known repositories)\n - Test with both open and closed issues\n - Test with issues containing various elements (labels, assignees, comments)\n\n3. Error case tests:\n - Invalid URL format\n - Non-existent repository\n - Non-existent issue number\n - API rate limit exceeded\n - Authentication failures for private repos\n\n4. End-to-end tests:\n - Verify that a task created from a GitHub issue contains all expected information\n - Verify that the task can be properly managed after creation\n - Test the interaction with other flags and commands\n\nCreate mock GitHub API responses for testing to avoid hitting rate limits during development and testing. Use environment variables to configure test credentials if needed.", + "details": "Implement a new flag '--from-github' for the add-task command that allows users to create tasks directly from GitHub issues. The implementation should work seamlessly with the GitHub export feature (Task #97) to provide bidirectional linking capabilities.\n\nCore functionality:\n1. Accept a GitHub issue URL as an argument (e.g., 'taskmaster add-task --from-github https://github.com/owner/repo/issues/123')\n2. Parse the URL to extract the repository owner, name, and issue number\n3. Use the GitHub API to fetch the issue details including:\n - Issue title (to be used as task title)\n - Issue description (to be used as task description)\n - Issue labels (to be potentially used as tags)\n - Issue assignees (for reference)\n - Issue status (open/closed)\n4. Generate a well-formatted task with this information\n5. **Automatically add GitHub link metadata** using the same schema as the export feature:\n - Store the source GitHub issue URL in task metadata\n - Use consistent metadata structure with export feature for bidirectional compatibility\n - Enable future synchronization capabilities\n6. Include a reference link back to the original GitHub issue in the task description\n7. Handle authentication for private repositories using GitHub tokens from environment variables or config file\n8. Implement proper error handling for:\n - Invalid URLs\n - Non-existent issues\n - API rate limiting\n - Authentication failures\n - Network issues\n9. **Validate GitHub links** during import to ensure they point to valid, accessible issues\n10. Allow users to override or supplement the imported details with additional command-line arguments\n11. Add appropriate documentation in help text and user guide, including information about the complementary export feature\n\nBidirectional Integration:\n- Use the same metadata schema as Task #97 for GitHub links\n- Ensure imported tasks can be identified as GitHub-linked for future export operations\n- Prepare infrastructure for future synchronization between tasks and their source issues\n- Maintain consistency with export feature's link management approach", + "testStrategy": "Testing should cover the following scenarios:\n\n1. Unit tests:\n - Test URL parsing functionality with valid and invalid GitHub issue URLs\n - Test GitHub API response parsing with mocked API responses\n - Test error handling for various failure cases\n - **Test metadata schema consistency with export feature**\n - **Test GitHub link validation functionality**\n\n2. Integration tests:\n - Test with real GitHub public issues (use well-known repositories)\n - Test with both open and closed issues\n - Test with issues containing various elements (labels, assignees, comments)\n - **Test bidirectional compatibility with export feature**\n - **Verify metadata structure matches export feature requirements**\n\n3. Error case tests:\n - Invalid URL format\n - Non-existent repository\n - Non-existent issue number\n - API rate limit exceeded\n - Authentication failures for private repos\n - **Invalid or inaccessible GitHub links**\n\n4. End-to-end tests:\n - Verify that a task created from a GitHub issue contains all expected information\n - **Verify that imported tasks contain proper GitHub link metadata**\n - Verify that the task can be properly managed after creation\n - Test the interaction with other flags and commands\n - **Test compatibility with export feature workflows**\n\n5. **Bidirectional feature tests**:\n - Import a GitHub issue and verify it can be exported back\n - Test metadata consistency between import and export operations\n - Verify link validation works correctly\n\nCreate mock GitHub API responses for testing to avoid hitting rate limits during development and testing. Use environment variables to configure test credentials if needed.", "subtasks": [ { "id": 1, @@ -2767,6 +2769,24 @@ ], "details": "Design and implement UI for URL input and import confirmation. Show loading states during API calls. Display meaningful error messages for various failure scenarios. Allow users to review and modify imported task details before saving. Add automated tests for the entire import flow.", "status": "pending" + }, + { + "id": 6, + "title": "Implement GitHub metadata schema and link management", + "description": "Create a consistent metadata schema for GitHub links that works with both import and export features, ensuring bidirectional compatibility.", + "dependencies": [], + "details": "Design and implement metadata structure that matches the export feature (Task #97). Include fields for GitHub issue URL, repository information, issue number, and sync status. Implement link validation to ensure GitHub URLs are accessible and valid. Create utilities for managing GitHub link metadata consistently across import and export operations.", + "status": "pending" + }, + { + "id": 7, + "title": "Add bidirectional integration with export feature", + "description": "Ensure imported tasks work seamlessly with the GitHub export feature and maintain consistent link management.", + "dependencies": [ + 6 + ], + "details": "Verify that tasks imported from GitHub can be properly exported back to GitHub. Implement checks to prevent duplicate exports of imported issues. Add metadata flags to identify imported tasks and their source repositories. Test round-trip workflows (import → modify → export) to ensure data integrity.", + "status": "pending" } ] }, @@ -5970,7 +5990,7 @@ "description": "Register the 'research' command with the CLI framework, ensuring it appears in the list of available commands and supports standard CLI conventions.", "dependencies": [], "details": "Integrate the new command into the CLI's command registry. Ensure it is discoverable via the CLI's help system and follows established naming and grouping conventions.", - "status": "in-progress" + "status": "done" }, { "id": 2, @@ -5979,8 +5999,8 @@ "dependencies": [ 1 ], - "details": "Use a command-line parsing framework to handle parameters. Ensure support for optional and required arguments, order-independence, and clear error messages for invalid input.", - "status": "pending" + "details": "Use a command-line parsing framework to handle parameters. Ensure support for optional and required arguments, order-independence, and clear error messages for invalid input.\n\n✅ **Parameter and Flag Handling Implementation Complete**\n\nSuccessfully implemented comprehensive parameter validation and processing for the research command:\n\n**✅ Implemented Features:**\n1. **Comprehensive Parameter Validation:**\n - Prompt validation (required, non-empty string)\n - Detail level validation (low, medium, high)\n - Task ID format validation (supports \"15\" and \"15.2\" formats)\n - File path validation (comma-separated, existence checks)\n - Save target validation (security checks for path traversal)\n\n2. **Advanced Parameter Processing:**\n - Comma-separated value parsing for task IDs and file paths\n - Whitespace trimming and normalization\n - Project root detection using `findProjectRoot()`\n - Relative/absolute path handling for files\n - Default value application\n\n3. **Informative Error Messages:**\n - Specific error messages for each validation failure\n - Clear examples of correct usage\n - Helpful suggestions for fixing errors\n - Much more informative than basic Commander.js errors\n\n4. **Structured Output:**\n - Creates validated parameters object with all processed values\n - Proper type conversion and normalization\n - Ready for consumption by core research function\n\n**✅ Validation Examples Tested:**\n- Missing prompt: Shows Commander.js error (expected behavior)\n- Invalid detail level: \"Error: Detail level must be one of: low, medium, high\"\n- Invalid task ID format: \"Error parsing task IDs: Invalid task ID format: \"invalid_format\". Expected format: \"15\" or \"15.2\"\"\n- Valid parameters: Successfully processes and creates structured parameter object\n\n**✅ Security Features:**\n- Path traversal protection for save targets\n- File existence validation\n- Input sanitization and trimming\n\nThe parameter validation is now production-ready and follows the same patterns used throughout the Task Master codebase. Ready to proceed to subtask 94.3 (Context Gathering Utility).\n", + "status": "done" }, { "id": 3, @@ -5989,42 +6009,283 @@ "dependencies": [ 2 ], - "details": "Support reading input from files or stdin using '-' as a convention. Validate and preprocess the gathered context to ensure it is suitable for AI processing.\n\nCreate a comprehensive, reusable context gathering utility `utils/contextGatherer.js` that can be shared between the research command and explore REPL functionality.\n\n**Core Features:**\n\n**Task/Subtask Context Extraction:**\n- Parse task IDs and subtask IDs (formats: \"15\", \"15.2\", \"16,17.1\")\n- Extract task titles, descriptions, details, and dependencies from the task system\n- Include parent task context automatically for subtasks\n- Format task data optimally for AI consumption\n\n**File Path Context Processing:**\n- Handle single or comma-separated file paths\n- Implement safe file reading with comprehensive error handling\n- Support multiple file types (JavaScript, markdown, text, JSON, etc.)\n- Include file metadata (path, size, type, last modified)\n\n**Project File Tree Generation:**\n- Create structured project overview with configurable depth\n- Filter out irrelevant directories (.git, node_modules, .env files)\n- Include file counts and directory statistics\n- Support custom filtering patterns\n\n**Custom Context Integration:**\n- Accept and merge custom context strings\n- Maintain clear context hierarchy and organization\n- Preserve context source attribution\n\n**Unified API Design:**\n```javascript\nconst contextGatherer = new ContextGatherer(projectRoot);\nconst context = await contextGatherer.gather({\n tasks: [\"15\", \"16.2\"],\n files: [\"src/main.js\", \"README.md\"],\n customContext: \"Additional context...\",\n includeProjectTree: true,\n format: \"research\" // or \"chat\", \"system-prompt\"\n});\n```\n\n**Output Formatting:**\n- Support multiple output formats (research, chat, system-prompt)\n- Ensure consistent context structure across different use cases\n- Optimize for AI model consumption and token efficiency\n\nThis utility will eliminate code duplication between task 51 (explore REPL) and task 94 (research command) while providing a robust, extensible foundation for context gathering operations.\n", - "status": "pending" + "details": "Support reading input from files or stdin using '-' as a convention. Validate and preprocess the gathered context to ensure it is suitable for AI processing.\n\nCreate a comprehensive, reusable context gathering utility `utils/contextGatherer.js` that can be shared between the research command and explore REPL functionality.\n\n**Core Features:**\n\n**Task/Subtask Context Extraction:**\n- Parse task IDs and subtask IDs (formats: \"15\", \"15.2\", \"16,17.1\")\n- Extract task titles, descriptions, details, and dependencies from the task system\n- Include parent task context automatically for subtasks\n- Format task data optimally for AI consumption\n\n**File Path Context Processing:**\n- Handle single or comma-separated file paths\n- Implement safe file reading with comprehensive error handling\n- Support multiple file types (JavaScript, markdown, text, JSON, etc.)\n- Include file metadata (path, size, type, last modified)\n\n**Project File Tree Generation:**\n- Create structured project overview with configurable depth\n- Filter out irrelevant directories (.git, node_modules, .env files)\n- Include file counts and directory statistics\n- Support custom filtering patterns\n\n**Custom Context Integration:**\n- Accept and merge custom context strings\n- Maintain clear context hierarchy and organization\n- Preserve context source attribution\n\n**Unified API Design:**\n```javascript\nconst contextGatherer = new ContextGatherer(projectRoot);\nconst context = await contextGatherer.gather({\n tasks: [\"15\", \"16.2\"],\n files: [\"src/main.js\", \"README.md\"],\n customContext: \"Additional context...\",\n includeProjectTree: true,\n format: \"research\" // or \"chat\", \"system-prompt\"\n});\n```\n\n**Output Formatting:**\n- Support multiple output formats (research, chat, system-prompt)\n- Ensure consistent context structure across different use cases\n- Optimize for AI model consumption and token efficiency\n\nThis utility will eliminate code duplication between task 51 (explore REPL) and task 94 (research command) while providing a robust, extensible foundation for context gathering operations.\n\n\n✅ **Context Gathering Implementation Complete**\n\nSuccessfully implemented the comprehensive ContextGatherer utility in `scripts/modules/utils/contextGatherer.js`:\n\n**✅ Core Features Implemented:**\n\n1. **Task/Subtask Context Extraction:**\n - ✅ Parse task IDs and subtask IDs (formats: \"15\", \"15.2\", \"16,17.1\")\n - ✅ Extract task titles, descriptions, details, and dependencies from the task system\n - ✅ Include parent task context automatically for subtasks\n - ✅ Format task data optimally for AI consumption\n - ✅ Proper integration with existing `findTaskById` utility function\n\n2. **File Path Context Processing:**\n - ✅ Handle single or comma-separated file paths\n - ✅ Implement safe file reading with comprehensive error handling\n - ✅ Support multiple file types (JavaScript, markdown, text, JSON, etc.)\n - ✅ Include file metadata (path, size, type, last modified)\n - ✅ File size limits (50KB max) to prevent context explosion\n\n3. **Project File Tree Generation:**\n - ✅ Create structured project overview with configurable depth (max 3 levels)\n - ✅ Filter out irrelevant directories (.git, node_modules, .env files)\n - ✅ Include file counts and directory statistics\n - ✅ Support custom filtering patterns\n\n4. **Custom Context Integration:**\n - ✅ Accept and merge custom context strings\n - ✅ Maintain clear context hierarchy and organization\n - ✅ Preserve context source attribution\n\n5. **Unified API Design:**\n - ✅ Clean class-based API with factory function\n - ✅ Flexible options object for configuration\n - ✅ Multiple output formats (research, chat, system-prompt)\n - ✅ Proper error handling and graceful degradation\n\n**✅ Output Formatting:**\n- ✅ Support for 'research', 'chat', and 'system-prompt' formats\n- ✅ Consistent context structure across different use cases\n- ✅ Optimized for AI model consumption and token efficiency\n\n**✅ Testing:**\n- ✅ Successfully tested with real task data (Task 94 and subtask 94.1)\n- ✅ Verified task context extraction works correctly\n- ✅ Confirmed proper formatting and structure\n\n**✅ Integration Ready:**\n- ✅ Designed to be shared between task 51 (explore REPL) and task 94 (research command)\n- ✅ Follows existing codebase patterns and utilities\n- ✅ Proper ES6 module exports for easy importing\n\nThe ContextGatherer utility is now ready for integration into the core research function (subtask 94.4).\n", + "status": "done" }, { "id": 4, - "title": "AI Service Integration", - "description": "Integrate with the AI service to process the gathered context and parameters, handling API calls, authentication, and error management.", + "title": "Core Function Implementation", + "description": "Implement the core research function in scripts/modules/task-manager/ following the add-task.js pattern", + "details": "Create a new core function (e.g., research.js) in scripts/modules/task-manager/ that:\n- Accepts parameters: query, context options (task IDs, file paths, custom context), project tree flag, detail level\n- Implements context gathering using the contextGatherer utility from subtask 94.3\n- Integrates with ai-services-unified.js using research role\n- Handles both CLI and MCP output formats\n- Returns structured results with telemetry data\n- Follows the same parameter validation and error handling patterns as add-task.js\n\n✅ COMPLETED: Added loading spinner to research command\n\n**Implementation Details:**\n- Imported `startLoadingIndicator` and `stopLoadingIndicator` from ui.js\n- Added loading indicator that shows \"Researching with AI...\" during AI service calls\n- Properly wrapped AI service call in try/catch/finally blocks to ensure spinner stops on both success and error\n- Loading indicator only shows in CLI mode (outputFormat === 'text'), not in MCP mode\n- Follows the same pattern as add-task.js for consistent user experience\n\n**Testing:**\n- Tested with `node bin/task-master.js research \"What is TypeScript?\" --detail=low`\n- Confirmed spinner appears during AI processing and disappears when complete\n- Telemetry display works correctly after spinner stops\n\nThe research command now provides the same polished user experience as other AI-powered commands in the system.\n", + "status": "done", "dependencies": [ - 3 + "98.2", + "98.3" ], - "details": "Establish a robust interface to the AI backend, manage API keys or tokens securely, and handle network or service errors gracefully.", - "status": "pending" + "parentTaskId": 98 }, { "id": 5, - "title": "Output Formatting", - "description": "Format the AI-generated output according to user-specified modes (e.g., plain text, JSON), and support writing to stdout or files.", + "title": "Direct Function Implementation", + "description": "Create the MCP direct function wrapper in mcp-server/src/core/direct-functions/ following the add-task pattern", + "details": "Create a new direct function (e.g., research.js) in mcp-server/src/core/direct-functions/ that:\n- Follows the addTaskDirect pattern for parameter handling and error management\n- Uses enableSilentMode/disableSilentMode to prevent console output interference\n- Creates logger wrapper using createLogWrapper utility\n- Validates required parameters (query, projectRoot)\n- Calls the core research function with proper context (session, mcpLog, projectRoot)\n- Returns standardized result object with success/error structure\n- Handles telemetry data propagation\n- Export and register in task-master-core.js", + "status": "pending", "dependencies": [ - 4 + "98.4" ], - "details": "Implement flexible output formatting, ensuring compatibility with piping and redirection. Provide clear, user-friendly output and support for machine-readable formats.", - "status": "pending" + "parentTaskId": 98 }, { "id": 6, - "title": "Documentation and Help", - "description": "Document the 'research' command, including usage examples, parameter descriptions, and integration with the CLI's --help system.", + "title": "MCP Tool Implementation", + "description": "Create the MCP tool in mcp-server/src/tools/ following the add-task tool pattern", + "details": "Create a new MCP tool (e.g., research.js) in mcp-server/src/tools/ that:\n- Defines zod schema for all research command parameters (query, id, files, context, project-tree, save, detail)\n- Uses withNormalizedProjectRoot HOF to handle project path normalization\n- Calls findTasksJsonPath to locate tasks.json file\n- Invokes the direct function with proper parameter mapping\n- Uses handleApiResult for standardized response formatting\n- Registers the tool as 'research' (snake_case) in the MCP server\n- Handles errors with createErrorResponse\n- Register in mcp-server/src/tools/index.js\n- Update .cursor/mcp.json with tool definition", + "status": "pending", + "dependencies": [ + "98.5" + ], + "parentTaskId": 98 + }, + { + "id": 7, + "title": "Add research save-to-file functionality", + "description": "Implement functionality to save research results to /research/ folder with optional interactive prompts", + "details": "Add capability to save research results to files in a /research/ directory at project root. For CLI mode, use inquirer to prompt user if they want to save the research. For MCP mode, accept a saveToFile parameter.\n\nKey implementation details:\n- Create /research/ directory if it doesn't exist (similar to how tasks/ is handled)\n- Generate meaningful filenames based on query and timestamp\n- Support both CLI interactive mode (inquirer prompts) and MCP parameter mode\n- Follow project root detection pattern from add-task.js stack\n- Handle file writing with proper error handling\n- Return saved file path in response for confirmation\n\nFile structure:\n- /research/YYYY-MM-DD_query-summary.md (markdown format)\n- Include query, timestamp, context used, and full AI response\n- Add metadata header with query details and context sources", + "status": "pending", + "dependencies": [], + "parentTaskId": 98 + }, + { + "id": 8, + "title": "Add research-to-task linking functionality", + "description": "Implement functionality to link saved research to specific tasks with interactive task selection", + "details": "Add capability to link research results to specific tasks by updating task details with research references. For CLI mode, use inquirer to prompt user if they want to link research to tasks and provide task selection. For MCP mode, accept linkToTasks parameter.\n\nKey implementation details:\n- Prompt user if they want to link research to existing tasks (CLI mode)\n- Provide task selection interface using inquirer with task list (ID, title, status)\n- Support multiple task selection (checkbox interface)\n- Update selected tasks' details section with research reference\n- Add timestamped research link in format: \"Research: [Query Title](file:///path/to/research.md) - YYYY-MM-DD\"\n- Follow add-task.js pattern for task file updates and regeneration\n- Handle task.json reading/writing with proper error handling\n- Support both single and multiple task linking\n- Return list of updated task IDs in response\n\nResearch link format in task details:\n```\n## Research References\n- [How to implement authentication](file:///research/2024-01-15_authentication-research.md) - 2024-01-15\n```", + "status": "pending", + "dependencies": [ + "94.7" + ], + "parentTaskId": 98 + } + ] + }, + { + "id": 99, + "title": "Enhance Parse-PRD with Intelligent Task Expansion and Detail Preservation", + "description": "Transform parse-prd from a simple task generator into an intelligent system that preserves PRD detail resolution through context-aware task expansion. This addresses the critical issue where highly detailed PRDs lose their specificity when parsed into too few top-level tasks, and ensures that task expansions are grounded in actual PRD content rather than generic AI assumptions.", + "details": "## Core Problem Statement\n\nThe current parse-prd implementation suffers from a fundamental resolution loss problem:\n\n1. **Detail Compression**: Complex, detailed PRDs get compressed into a fixed number of top-level tasks (default 10), losing critical specificity\n2. **Orphaned Expansions**: When tasks are later expanded via expand-task, the AI lacks the original PRD context, resulting in generic subtasks that don't reflect the PRD's specific requirements\n3. **Binary Approach**: The system either creates too few high-level tasks OR requires manual expansion that loses PRD context\n\n## Solution Architecture\n\n### Phase 1: Enhanced PRD Analysis Engine\n- Implement intelligent PRD segmentation that identifies natural task boundaries based on content structure\n- Create a PRD context preservation system that maintains detailed mappings between PRD sections and generated tasks\n- Develop adaptive task count determination based on PRD complexity metrics (length, technical depth, feature count)\n\n### Phase 2: Context-Aware Task Generation\n- Modify generateTasksFromPRD to create tasks with embedded PRD context references\n- Implement a PRD section mapping system that links each task to its source PRD content\n- Add metadata fields to tasks that preserve original PRD language and specifications\n\n### Phase 3: Intelligent In-Flight Expansion\n- Add optional `--expand-tasks` flag to parse-prd that triggers immediate expansion after initial task generation\n- Implement context-aware expansion that uses the original PRD content for each task's expansion\n- Create a two-pass system: first pass generates tasks with PRD context, second pass expands using that context\n\n### Phase 4: PRD-Grounded Expansion Logic\n- Enhance the expansion prompt generation to include relevant PRD excerpts for each task being expanded\n- Implement smart context windowing that includes related PRD sections when expanding tasks\n- Add validation to ensure expanded subtasks maintain fidelity to original PRD specifications\n\n## Technical Implementation Details\n\n### File Modifications Required:\n1. **scripts/modules/task-manager/parse-prd.js**\n - Add PRD analysis functions for intelligent segmentation\n - Implement context preservation during task generation\n - Add optional expansion pipeline integration\n - Create PRD-to-task mapping system\n\n2. **scripts/modules/task-manager/expand-task.js**\n - Enhance to accept PRD context as additional input\n - Modify expansion prompts to include relevant PRD excerpts\n - Add PRD-grounded validation for generated subtasks\n\n3. **scripts/modules/ai-services-unified.js**\n - Add support for context-aware prompting with PRD excerpts\n - Implement intelligent context windowing for large PRDs\n - Add PRD analysis capabilities for complexity assessment\n\n### New Data Structures:\n```javascript\n// Enhanced task structure with PRD context\n{\n id: \"1\",\n title: \"User Authentication System\",\n description: \"...\",\n prdContext: {\n sourceSection: \"Authentication Requirements (Lines 45-78)\",\n originalText: \"The system must implement OAuth 2.0...\",\n relatedSections: [\"Security Requirements\", \"User Management\"],\n contextWindow: \"Full PRD excerpt relevant to this task\"\n },\n // ... existing fields\n}\n\n// PRD analysis metadata\n{\n prdAnalysis: {\n totalComplexity: 8.5,\n naturalTaskBoundaries: [...],\n recommendedTaskCount: 15,\n sectionMappings: {...}\n }\n}\n```\n\n### New CLI Options:\n- `--expand-tasks`: Automatically expand generated tasks using PRD context\n- `--preserve-detail`: Maximum detail preservation mode\n- `--adaptive-count`: Let AI determine optimal task count based on PRD complexity\n- `--context-window-size`: Control how much PRD context to include in expansions\n\n## Implementation Strategy\n\n### Step 1: PRD Analysis Enhancement\n- Create PRD parsing utilities that identify natural section boundaries\n- Implement complexity scoring for different PRD sections\n- Build context extraction functions that preserve relevant details\n\n### Step 2: Context-Aware Task Generation\n- Modify the task generation prompt to include section-specific context\n- Implement task-to-PRD mapping during generation\n- Add metadata fields to preserve PRD relationships\n\n### Step 3: Intelligent Expansion Pipeline\n- Create expansion logic that uses preserved PRD context\n- Implement smart prompt engineering that includes relevant PRD excerpts\n- Add validation to ensure subtask fidelity to original requirements\n\n### Step 4: Integration and Testing\n- Integrate new functionality with existing parse-prd workflow\n- Add comprehensive testing with various PRD types and complexities\n- Implement telemetry for tracking detail preservation effectiveness\n\n## Success Metrics\n- PRD detail preservation rate (measured by semantic similarity between PRD and generated tasks)\n- Reduction in manual task refinement needed post-parsing\n- Improved accuracy of expanded subtasks compared to PRD specifications\n- User satisfaction with task granularity and detail accuracy\n\n## Edge Cases and Considerations\n- Very large PRDs that exceed context windows\n- PRDs with conflicting or ambiguous requirements\n- Integration with existing task expansion workflows\n- Performance impact of enhanced analysis\n- Backward compatibility with existing parse-prd usage", + "testStrategy": "", + "status": "pending", + "dependencies": [], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "Implement PRD Analysis and Segmentation Engine", + "description": "Create intelligent PRD parsing that identifies natural task boundaries and complexity metrics", + "details": "## Implementation Requirements\n\n### Core Functions to Implement:\n1. **analyzePRDStructure(prdContent)**\n - Parse PRD into logical sections using headers, bullet points, and semantic breaks\n - Identify feature boundaries, technical requirements, and implementation sections\n - Return structured analysis with section metadata\n\n2. **calculatePRDComplexity(prdContent)**\n - Analyze technical depth, feature count, integration requirements\n - Score complexity on 1-10 scale for different aspects\n - Return recommended task count based on complexity\n\n3. **extractTaskBoundaries(prdAnalysis)**\n - Identify natural breaking points for task creation\n - Group related requirements into logical task units\n - Preserve context relationships between sections\n\n### Technical Approach:\n- Use regex patterns and NLP techniques to identify section headers\n- Implement keyword analysis for technical complexity assessment\n- Create semantic grouping algorithms for related requirements\n- Build context preservation mappings\n\n### Output Structure:\n```javascript\n{\n sections: [\n {\n title: \"User Authentication\",\n content: \"...\",\n startLine: 45,\n endLine: 78,\n complexity: 7,\n relatedSections: [\"Security\", \"User Management\"]\n }\n ],\n overallComplexity: 8.5,\n recommendedTaskCount: 15,\n naturalBoundaries: [...],\n contextMappings: {...}\n}\n```\n\n### Integration Points:\n- Called at the beginning of parse-prd process\n- Results used to inform task generation strategy\n- Analysis stored for later use in expansion phase", + "status": "pending", + "dependencies": [], + "parentTaskId": 99 + }, + { + "id": 2, + "title": "Enhance Task Generation with PRD Context Preservation", + "description": "Modify generateTasksFromPRD to embed PRD context and maintain source mappings", + "details": "## Implementation Requirements\n\n### Core Modifications to generateTasksFromPRD:\n1. **Add PRD Context Embedding**\n - Modify task generation prompt to include relevant PRD excerpts\n - Ensure each generated task includes source section references\n - Preserve original PRD language and specifications in task metadata\n\n2. **Implement Context Windowing**\n - For large PRDs, implement intelligent context windowing\n - Include relevant sections for each task being generated\n - Maintain context relationships between related tasks\n\n3. **Enhanced Task Structure**\n - Add prdContext field to task objects\n - Include sourceSection, originalText, and relatedSections\n - Store contextWindow for later use in expansions\n\n### Technical Implementation:\n```javascript\n// Enhanced task generation with context\nconst generateTaskWithContext = async (prdSection, relatedSections, fullPRD) => {\n const contextWindow = buildContextWindow(prdSection, relatedSections, fullPRD);\n const prompt = `\n Generate a task based on this PRD section:\n \n PRIMARY SECTION:\n ${prdSection.content}\n \n RELATED CONTEXT:\n ${contextWindow}\n \n Ensure the task preserves all specific requirements and technical details.\n `;\n \n // Generate task with embedded context\n const task = await generateTask(prompt);\n task.prdContext = {\n sourceSection: prdSection.title,\n originalText: prdSection.content,\n relatedSections: relatedSections.map(s => s.title),\n contextWindow: contextWindow\n };\n \n return task;\n};\n```\n\n### Context Preservation Strategy:\n- Map each task to its source PRD sections\n- Preserve technical specifications and requirements language\n- Maintain relationships between interdependent features\n- Store context for later use in expansion phase\n\n### Integration with Existing Flow:\n- Modify existing generateTasksFromPRD function\n- Maintain backward compatibility with simple PRDs\n- Add new metadata fields without breaking existing structure\n- Ensure context is available for subsequent operations", + "status": "pending", + "dependencies": [ + "99.1" + ], + "parentTaskId": 99 + }, + { + "id": 3, + "title": "Implement In-Flight Task Expansion Pipeline", + "description": "Add optional --expand-tasks flag and intelligent expansion using preserved PRD context", + "details": "## Implementation Requirements\n\n### Core Features:\n1. **Add --expand-tasks CLI Flag**\n - Optional flag for parse-prd command\n - Triggers automatic expansion after initial task generation\n - Configurable expansion depth and strategy\n\n2. **Two-Pass Processing System**\n - First pass: Generate tasks with PRD context preservation\n - Second pass: Expand tasks using their embedded PRD context\n - Maintain context fidelity throughout the process\n\n3. **Context-Aware Expansion Logic**\n - Use preserved PRD context for each task's expansion\n - Include relevant PRD excerpts in expansion prompts\n - Ensure subtasks maintain fidelity to original specifications\n\n### Technical Implementation:\n```javascript\n// Enhanced parse-prd with expansion pipeline\nconst parsePRDWithExpansion = async (prdContent, options) => {\n // Phase 1: Analyze and generate tasks with context\n const prdAnalysis = await analyzePRDStructure(prdContent);\n const tasksWithContext = await generateTasksWithContext(prdAnalysis);\n \n // Phase 2: Expand tasks if requested\n if (options.expandTasks) {\n for (const task of tasksWithContext) {\n if (shouldExpandTask(task, prdAnalysis)) {\n const expandedSubtasks = await expandTaskWithPRDContext(task);\n task.subtasks = expandedSubtasks;\n }\n }\n }\n \n return tasksWithContext;\n};\n\n// Context-aware task expansion\nconst expandTaskWithPRDContext = async (task) => {\n const { prdContext } = task;\n const expansionPrompt = `\n Expand this task into detailed subtasks using the original PRD context:\n \n TASK: ${task.title}\n DESCRIPTION: ${task.description}\n \n ORIGINAL PRD CONTEXT:\n ${prdContext.originalText}\n \n RELATED SECTIONS:\n ${prdContext.contextWindow}\n \n Generate subtasks that preserve all technical details and requirements from the PRD.\n `;\n \n return await generateSubtasks(expansionPrompt);\n};\n```\n\n### CLI Integration:\n- Add --expand-tasks flag to parse-prd command\n- Add --expansion-depth option for controlling subtask levels\n- Add --preserve-detail flag for maximum context preservation\n- Maintain backward compatibility with existing parse-prd usage\n\n### Expansion Strategy:\n- Determine which tasks should be expanded based on complexity\n- Use PRD context to generate accurate, detailed subtasks\n- Preserve technical specifications and implementation details\n- Validate subtask accuracy against original PRD content\n\n### Performance Considerations:\n- Implement batching for large numbers of tasks\n- Add progress indicators for long-running expansions\n- Optimize context window sizes for efficiency\n- Cache PRD analysis results for reuse", + "status": "pending", + "dependencies": [ + "99.2" + ], + "parentTaskId": 99 + }, + { + "id": 4, + "title": "Enhance Expand-Task with PRD Context Integration", + "description": "Modify existing expand-task functionality to leverage preserved PRD context for more accurate expansions", + "details": "## Implementation Requirements\n\n### Core Enhancements to expand-task.js:\n1. **PRD Context Detection**\n - Check if task has embedded prdContext metadata\n - Extract relevant PRD sections for expansion\n - Fall back to existing expansion logic if no PRD context\n\n2. **Context-Enhanced Expansion Prompts**\n - Include original PRD excerpts in expansion prompts\n - Add related section context for comprehensive understanding\n - Preserve technical specifications and requirements language\n\n3. **Validation and Quality Assurance**\n - Validate generated subtasks against original PRD content\n - Ensure technical accuracy and requirement compliance\n - Flag potential discrepancies for review\n\n### Technical Implementation:\n```javascript\n// Enhanced expand-task with PRD context\nconst expandTaskWithContext = async (taskId, options, context) => {\n const task = await getTask(taskId);\n \n // Check for PRD context\n if (task.prdContext) {\n return await expandWithPRDContext(task, options);\n } else {\n // Fall back to existing expansion logic\n return await expandTaskStandard(task, options);\n }\n};\n\nconst expandWithPRDContext = async (task, options) => {\n const { prdContext } = task;\n \n const enhancedPrompt = `\n Expand this task into detailed subtasks using the original PRD context:\n \n TASK DETAILS:\n Title: ${task.title}\n Description: ${task.description}\n Current Details: ${task.details}\n \n ORIGINAL PRD CONTEXT:\n Source Section: ${prdContext.sourceSection}\n Original Requirements:\n ${prdContext.originalText}\n \n RELATED CONTEXT:\n ${prdContext.contextWindow}\n \n EXPANSION REQUIREMENTS:\n - Preserve all technical specifications from the PRD\n - Maintain requirement accuracy and completeness\n - Generate ${options.num || 'appropriate number of'} subtasks\n - Include implementation details that reflect PRD specifics\n \n Generate subtasks that are grounded in the original PRD content.\n `;\n \n const subtasks = await generateSubtasks(enhancedPrompt, options);\n \n // Add PRD context inheritance to subtasks\n subtasks.forEach(subtask => {\n subtask.prdContext = {\n inheritedFrom: task.id,\n sourceSection: prdContext.sourceSection,\n relevantExcerpt: extractRelevantExcerpt(prdContext, subtask)\n };\n });\n \n return subtasks;\n};\n```\n\n### Integration Points:\n1. **Modify existing expand-task.js**\n - Add PRD context detection logic\n - Enhance prompt generation with context\n - Maintain backward compatibility\n\n2. **Update expansion validation**\n - Add PRD compliance checking\n - Implement quality scoring for context fidelity\n - Flag potential accuracy issues\n\n3. **CLI and MCP Integration**\n - Update expand-task command to leverage PRD context\n - Add options for context-aware expansion\n - Maintain existing command interface\n\n### Context Inheritance Strategy:\n- Pass relevant PRD context to generated subtasks\n- Create context inheritance chain for nested expansions\n- Preserve source traceability throughout expansion tree\n- Enable future re-expansion with maintained context\n\n### Quality Assurance Features:\n- Semantic similarity checking between subtasks and PRD\n- Technical requirement compliance validation\n- Automated flagging of potential context drift\n- User feedback integration for continuous improvement", + "status": "pending", + "dependencies": [ + "99.2" + ], + "parentTaskId": 99 + }, + { + "id": 5, + "title": "Add New CLI Options and MCP Parameters", + "description": "Implement new command-line flags and MCP tool parameters for enhanced PRD parsing", + "details": "## Implementation Requirements\n\n### New CLI Options for parse-prd:\n1. **--expand-tasks**\n - Automatically expand generated tasks using PRD context\n - Boolean flag, default false\n - Triggers in-flight expansion pipeline\n\n2. **--preserve-detail**\n - Maximum detail preservation mode\n - Boolean flag, default false\n - Ensures highest fidelity to PRD content\n\n3. **--adaptive-count**\n - Let AI determine optimal task count based on PRD complexity\n - Boolean flag, default false\n - Overrides --num-tasks when enabled\n\n4. **--context-window-size**\n - Control how much PRD context to include in expansions\n - Integer value, default 2000 characters\n - Balances context richness with performance\n\n5. **--expansion-depth**\n - Control how many levels deep to expand tasks\n - Integer value, default 1\n - Prevents excessive nesting\n\n### MCP Tool Parameter Updates:\n```javascript\n// Enhanced parse_prd MCP tool parameters\n{\n input: \"Path to PRD file\",\n output: \"Output path for tasks.json\",\n numTasks: \"Number of top-level tasks (overridden by adaptiveCount)\",\n expandTasks: \"Boolean - automatically expand tasks with PRD context\",\n preserveDetail: \"Boolean - maximum detail preservation mode\",\n adaptiveCount: \"Boolean - AI determines optimal task count\",\n contextWindowSize: \"Integer - context size for expansions\",\n expansionDepth: \"Integer - levels of expansion to perform\",\n research: \"Boolean - use research model for enhanced analysis\",\n force: \"Boolean - overwrite existing files\"\n}\n```\n\n### CLI Command Updates:\n```bash\n# Enhanced parse-prd command examples\ntask-master parse-prd prd.txt --expand-tasks --preserve-detail\ntask-master parse-prd prd.txt --adaptive-count --expansion-depth=2\ntask-master parse-prd prd.txt --context-window-size=3000 --research\n```\n\n### Implementation Details:\n1. **Update commands.js**\n - Add new option definitions\n - Update parse-prd command handler\n - Maintain backward compatibility\n\n2. **Update MCP tool definition**\n - Add new parameter schemas\n - Update tool description and examples\n - Ensure parameter validation\n\n3. **Parameter Processing Logic**\n - Validate parameter combinations\n - Set appropriate defaults\n - Handle conflicting options gracefully\n\n### Validation Rules:\n- expansion-depth must be positive integer ≤ 3\n- context-window-size must be between 500-5000 characters\n- adaptive-count overrides num-tasks when both specified\n- expand-tasks requires either adaptive-count or num-tasks > 5\n\n### Help Documentation Updates:\n- Update command help text with new options\n- Add usage examples for different scenarios\n- Document parameter interactions and constraints\n- Include performance considerations for large PRDs", + "status": "pending", + "dependencies": [ + "99.3" + ], + "parentTaskId": 99 + }, + { + "id": 6, + "title": "Implement Comprehensive Testing and Validation", + "description": "Create test suite for PRD analysis, context preservation, and expansion accuracy", + "details": "## Implementation Requirements\n\n### Test Categories:\n1. **PRD Analysis Testing**\n - Test section identification with various PRD formats\n - Validate complexity scoring accuracy\n - Test boundary detection for different document structures\n - Verify context mapping correctness\n\n2. **Context Preservation Testing**\n - Validate PRD context embedding in generated tasks\n - Test context window generation and sizing\n - Verify source section mapping accuracy\n - Test context inheritance in subtasks\n\n3. **Expansion Accuracy Testing**\n - Compare PRD-grounded vs standard expansions\n - Measure semantic similarity between PRD and subtasks\n - Test technical requirement preservation\n - Validate expansion depth and quality\n\n4. **Integration Testing**\n - Test full parse-prd pipeline with expansion\n - Validate CLI option combinations\n - Test MCP tool parameter handling\n - Verify backward compatibility\n\n### Test Data Requirements:\n```javascript\n// Test PRD samples\nconst testPRDs = {\n simple: \"Basic PRD with minimal technical details\",\n complex: \"Detailed PRD with extensive technical specifications\",\n structured: \"Well-organized PRD with clear sections\",\n unstructured: \"Free-form PRD with mixed content\",\n technical: \"Highly technical PRD with specific requirements\",\n large: \"Very large PRD testing context window limits\"\n};\n```\n\n### Validation Metrics:\n1. **Detail Preservation Score**\n - Semantic similarity between PRD and generated tasks\n - Technical requirement coverage percentage\n - Specification accuracy rating\n\n2. **Context Fidelity Score**\n - Accuracy of source section mapping\n - Relevance of included context windows\n - Quality of context inheritance\n\n3. **Expansion Quality Score**\n - Subtask relevance to parent task and PRD\n - Technical accuracy of implementation details\n - Completeness of requirement coverage\n\n### Test Implementation:\n```javascript\n// Example test structure\ndescribe('Enhanced Parse-PRD', () => {\n describe('PRD Analysis', () => {\n test('should identify sections correctly', async () => {\n const analysis = await analyzePRDStructure(testPRDs.structured);\n expect(analysis.sections).toHaveLength(expectedSectionCount);\n expect(analysis.overallComplexity).toBeGreaterThan(0);\n });\n \n test('should calculate appropriate task count', async () => {\n const analysis = await analyzePRDStructure(testPRDs.complex);\n expect(analysis.recommendedTaskCount).toBeGreaterThan(10);\n });\n });\n \n describe('Context Preservation', () => {\n test('should embed PRD context in tasks', async () => {\n const tasks = await generateTasksWithContext(testPRDs.technical);\n tasks.forEach(task => {\n expect(task.prdContext).toBeDefined();\n expect(task.prdContext.sourceSection).toBeTruthy();\n expect(task.prdContext.originalText).toBeTruthy();\n });\n });\n });\n \n describe('Expansion Accuracy', () => {\n test('should generate relevant subtasks from PRD context', async () => {\n const task = createTestTaskWithPRDContext();\n const subtasks = await expandTaskWithPRDContext(task);\n \n const relevanceScore = calculateRelevanceScore(subtasks, task.prdContext);\n expect(relevanceScore).toBeGreaterThan(0.8);\n });\n });\n});\n```\n\n### Performance Testing:\n- Test with large PRDs (>10,000 words)\n- Measure processing time for different complexity levels\n- Test memory usage with extensive context preservation\n- Validate timeout handling for long-running operations\n\n### Quality Assurance Tools:\n- Automated semantic similarity checking\n- Technical requirement compliance validation\n- Context drift detection algorithms\n- User acceptance testing framework\n\n### Continuous Integration:\n- Add tests to existing CI pipeline\n- Set up performance benchmarking\n- Implement quality gates for PRD processing\n- Create regression testing for context preservation", + "status": "pending", + "dependencies": [ + "99.4", + "99.5" + ], + "parentTaskId": 99 + } + ] + }, + { + "id": 100, + "title": "Implement Dynamic Help Menu Generation from CLI Commands", + "description": "Transform the static help menu in ui.js into a dynamic system that automatically generates help content by introspecting the actual CLI commands, options, and flags defined in commands.js. This ensures the help menu stays synchronized with command implementations and reduces maintenance overhead.", + "details": "## Core Problem Statement\n\nThe current help menu in `displayHelp()` function (ui.js:434-734) is hardcoded with static command information that can become outdated when:\n\n1. **Command Changes**: New options/flags are added to existing commands\n2. **New Commands**: New commands are added to commands.js but not reflected in help\n3. **Command Removal**: Commands are removed but help text remains\n4. **Inconsistent Documentation**: Help text doesn't match actual command behavior\n5. **Maintenance Burden**: Developers must remember to update help when modifying commands\n\n## Technical Implementation Requirements\n\n### 1. Command Introspection System\n- **Extract Command Metadata**: Parse Commander.js program instance to extract:\n - Command names and aliases\n - Command descriptions\n - All options/flags with their descriptions and default values\n - Required vs optional parameters\n - Argument specifications\n- **Command Categorization**: Implement intelligent categorization based on:\n - Command name patterns (e.g., 'add-*', 'remove-*', 'set-*')\n - Command descriptions containing keywords\n - Manual category overrides for edge cases\n- **Validation**: Ensure all registered commands are captured and categorized\n\n### 2. Dynamic Help Generation Engine\n- **Template System**: Create flexible templates for:\n - Category headers with consistent styling\n - Command entries with proper formatting\n - Option/flag documentation with type information\n - Example usage generation\n- **Formatting Logic**: Implement dynamic column width calculation based on:\n - Terminal width detection\n - Content length analysis\n - Responsive layout adjustments\n- **Content Optimization**: Handle text wrapping, truncation, and spacing automatically\n\n### 3. Enhanced Command Documentation\n- **Auto-Generated Examples**: Create realistic usage examples by:\n - Combining command names with common option patterns\n - Using project-specific values (task IDs, file paths)\n - Showing both simple and complex usage scenarios\n- **Option Details**: Display comprehensive option information:\n - Short and long flag variants (-f, --file)\n - Data types and format requirements\n - Default values and behavior\n - Required vs optional indicators\n- **Cross-References**: Add intelligent linking between related commands\n\n### 4. Integration Points\n- **Commands.js Integration**: \n - Access the programInstance after all commands are registered\n - Extract metadata without affecting command functionality\n - Handle edge cases like hidden commands or aliases\n- **UI.js Refactoring**:\n - Replace static commandCategories array with dynamic generation\n - Maintain existing visual styling and layout\n - Preserve terminal width responsiveness\n - Keep configuration and quick start sections\n\n### 5. Category Classification Logic\nImplement smart categorization rules:\n```javascript\nconst categoryRules = {\n 'Project Setup & Configuration': ['init', 'models'],\n 'Task Generation': ['parse-prd', 'generate'],\n 'Task Management': ['list', 'set-status', 'update', 'add-task', 'remove-task'],\n 'Subtask Management': ['add-subtask', 'remove-subtask', 'clear-subtasks'],\n 'Task Analysis & Breakdown': ['analyze-complexity', 'complexity-report', 'expand', 'research'],\n 'Task Navigation & Viewing': ['next', 'show'],\n 'Dependency Management': ['add-dependency', 'remove-dependency', 'validate-dependencies', 'fix-dependencies']\n};\n```\n\n### 6. Error Handling and Fallbacks\n- **Graceful Degradation**: Fall back to static help if introspection fails\n- **Missing Information**: Handle commands with incomplete metadata\n- **Performance Considerations**: Cache generated help content when possible\n- **Debug Mode**: Provide verbose output for troubleshooting categorization\n\n## Implementation Architecture\n\n### Core Functions to Implement:\n1. **`extractCommandMetadata(programInstance)`**\n - Parse Commander.js instance\n - Extract all command and option information\n - Return structured metadata object\n\n2. **`categorizeCommands(commandMetadata)`**\n - Apply categorization rules\n - Handle special cases and overrides\n - Return categorized command structure\n\n3. **`generateDynamicHelp(categorizedCommands)`**\n - Create formatted help content\n - Apply consistent styling\n - Handle responsive layout\n\n4. **`displayDynamicHelp(programInstance)`**\n - Replace current displayHelp() function\n - Integrate with existing banner and footer content\n - Maintain backward compatibility\n\n### File Structure Changes:\n- **ui.js**: Replace static help with dynamic generation\n- **commands.js**: Ensure all commands have proper descriptions and option documentation\n- **New utility functions**: Add command introspection helpers\n\n## Testing Requirements\n\n### Unit Tests:\n- Command metadata extraction accuracy\n- Categorization logic correctness\n- Help content generation formatting\n- Terminal width responsiveness\n\n### Integration Tests:\n- Full help menu generation from actual commands\n- Consistency between help and actual command behavior\n- Performance with large numbers of commands\n\n### Manual Testing:\n- Visual verification of help output\n- Terminal width adaptation testing\n- Comparison with current static help for completeness\n\n## Benefits\n\n1. **Automatic Synchronization**: Help always reflects actual command state\n2. **Reduced Maintenance**: No manual help updates needed for command changes\n3. **Consistency**: Guaranteed alignment between help and implementation\n4. **Extensibility**: Easy to add new categorization rules or formatting\n5. **Accuracy**: Eliminates human error in help documentation\n6. **Developer Experience**: Faster development with automatic documentation\n\n## Migration Strategy\n\n1. **Phase 1**: Implement introspection system alongside existing static help\n2. **Phase 2**: Add categorization and dynamic generation\n3. **Phase 3**: Replace static help with dynamic system\n4. **Phase 4**: Remove static command definitions and add validation tests\n\nThis implementation will create a self-documenting CLI that maintains accuracy and reduces the burden on developers to manually maintain help documentation.", + "testStrategy": "", + "status": "pending", + "dependencies": [ + 2, + 4 + ], + "priority": "medium", + "subtasks": [ + { + "id": 1, + "title": "Implement Command Metadata Extraction System", + "description": "Create the core introspection system to extract command metadata from Commander.js program instance", + "details": "## Implementation Requirements\n\n### Core Function: `extractCommandMetadata(programInstance)`\n\n**Location**: Add to `ui.js` or create new `help-utils.js` module\n\n**Functionality**:\n1. **Command Discovery**:\n - Iterate through `programInstance.commands` array\n - Extract command names, aliases, and descriptions\n - Handle subcommands and nested command structures\n - Filter out hidden or internal commands\n\n2. **Option Extraction**:\n - Parse `command.options` array for each command\n - Extract short flags (-f), long flags (--file), descriptions\n - Identify required vs optional parameters\n - Capture default values and data types\n - Handle boolean flags vs value-accepting options\n\n3. **Argument Processing**:\n - Extract positional arguments and their descriptions\n - Identify required vs optional arguments\n - Handle variadic arguments (e.g., [files...])\n\n4. **Metadata Structure**:\n```javascript\n{\n commandName: {\n name: 'command-name',\n aliases: ['alias1', 'alias2'],\n description: 'Command description',\n usage: 'command-name [options] ',\n options: [\n {\n flags: '-f, --file ',\n description: 'File path description',\n required: false,\n defaultValue: 'default.json',\n type: 'string'\n }\n ],\n arguments: [\n {\n name: 'id',\n description: 'Task ID',\n required: true,\n variadic: false\n }\n ]\n }\n}\n```\n\n### Technical Implementation:\n1. **Commander.js API Usage**:\n - Access `command._name`, `command._description`\n - Parse `command.options` for option metadata\n - Handle `command._args` for positional arguments\n - Use `command._aliases` for command aliases\n\n2. **Option Parsing Logic**:\n - Parse option flags using regex to separate short/long forms\n - Detect required parameters using `<>` vs optional `[]`\n - Extract default values from option configurations\n - Identify boolean flags vs value-accepting options\n\n3. **Error Handling**:\n - Handle commands with missing descriptions\n - Deal with malformed option definitions\n - Provide fallbacks for incomplete metadata\n - Log warnings for problematic command definitions\n\n### Testing Requirements:\n- Unit tests for metadata extraction accuracy\n- Test with various command configurations\n- Verify handling of edge cases (missing descriptions, complex options)\n- Performance testing with large command sets", + "status": "pending", + "dependencies": [], + "parentTaskId": 100 + }, + { + "id": 2, + "title": "Create Intelligent Command Categorization System", + "description": "Implement smart categorization logic to group commands into logical categories for the help menu", + "details": "## Implementation Requirements\n\n### Core Function: `categorizeCommands(commandMetadata)`\n\n**Location**: Add to `ui.js` or `help-utils.js` module\n\n**Functionality**:\n1. **Category Definition System**:\n - Define category rules with command name patterns\n - Support keyword-based categorization from descriptions\n - Allow manual overrides for edge cases\n - Maintain existing category structure for consistency\n\n2. **Categorization Rules**:\n```javascript\nconst categoryRules = {\n 'Project Setup & Configuration': {\n commands: ['init', 'models'],\n patterns: [/^models/, /^init/],\n keywords: ['setup', 'configure', 'initialization'],\n color: 'blue'\n },\n 'Task Generation': {\n commands: ['parse-prd', 'generate'],\n patterns: [/^parse/, /^generate/],\n keywords: ['create', 'generate', 'parse'],\n color: 'cyan'\n },\n 'Task Management': {\n commands: ['list', 'set-status', 'update', 'add-task', 'remove-task'],\n patterns: [/^(list|set-|update|add-|remove-)/, /status$/],\n keywords: ['manage', 'update', 'modify', 'status'],\n color: 'green'\n },\n 'Subtask Management': {\n commands: ['add-subtask', 'remove-subtask', 'clear-subtasks'],\n patterns: [/subtask/],\n keywords: ['subtask', 'sub-task'],\n color: 'yellow'\n },\n 'Task Analysis & Breakdown': {\n commands: ['analyze-complexity', 'complexity-report', 'expand', 'research'],\n patterns: [/^(analyze|complexity|expand|research)/],\n keywords: ['analyze', 'complexity', 'expand', 'research', 'breakdown'],\n color: 'magenta'\n },\n 'Task Navigation & Viewing': {\n commands: ['next', 'show'],\n patterns: [/^(next|show|view|display)/],\n keywords: ['view', 'show', 'display', 'navigate'],\n color: 'cyan'\n },\n 'Dependency Management': {\n commands: ['add-dependency', 'remove-dependency', 'validate-dependencies', 'fix-dependencies'],\n patterns: [/dependency|dependencies/],\n keywords: ['dependency', 'dependencies', 'depend'],\n color: 'blue'\n }\n};\n```\n\n3. **Categorization Algorithm**:\n - **Exact Match**: Check if command name is in category's command list\n - **Pattern Matching**: Test command name against regex patterns\n - **Keyword Analysis**: Search command description for category keywords\n - **Fallback Category**: Create \"Other Commands\" for uncategorized commands\n - **Priority System**: Handle commands that match multiple categories\n\n4. **Category Validation**:\n - Ensure all commands are categorized\n - Detect and warn about duplicate categorizations\n - Validate category color assignments\n - Check for empty categories\n\n### Technical Implementation:\n1. **Categorization Logic**:\n```javascript\nfunction categorizeCommands(commandMetadata) {\n const categorizedCommands = {};\n const uncategorized = [];\n \n // Initialize categories\n Object.keys(categoryRules).forEach(categoryName => {\n categorizedCommands[categoryName] = {\n ...categoryRules[categoryName],\n commands: []\n };\n });\n \n // Categorize each command\n Object.values(commandMetadata).forEach(command => {\n const category = findBestCategory(command);\n if (category) {\n categorizedCommands[category].commands.push(command);\n } else {\n uncategorized.push(command);\n }\n });\n \n // Handle uncategorized commands\n if (uncategorized.length > 0) {\n categorizedCommands['Other Commands'] = {\n color: 'gray',\n commands: uncategorized\n };\n }\n \n return categorizedCommands;\n}\n```\n\n2. **Best Category Detection**:\n - Score each category based on match strength\n - Prefer exact command name matches over patterns\n - Weight keyword matches by frequency and relevance\n - Return highest-scoring category\n\n3. **Dynamic Category Creation**:\n - Support adding new categories without code changes\n - Allow category rules to be loaded from configuration\n - Handle category inheritance and hierarchies\n\n### Testing Requirements:\n- Test categorization accuracy for all existing commands\n- Verify handling of new commands not in predefined lists\n- Test pattern matching and keyword detection\n- Validate category completeness and no duplicates", + "status": "pending", + "dependencies": [ + 1 + ], + "parentTaskId": 100 + }, + { + "id": 3, + "title": "Build Dynamic Help Content Generator", + "description": "Create the core help content generation system that formats command metadata into user-friendly help text", + "details": "## Implementation Requirements\n\n### Core Function: `generateHelpContent(categorizedCommands)`\n\n**Location**: Replace existing `displayHelp()` logic in `ui.js`\n\n**Functionality**:\n1. **Help Section Generation**:\n - Generate header with tool name and version\n - Create usage section with basic syntax\n - Build categorized command sections\n - Add footer with additional resources\n\n2. **Command Formatting Logic**:\n```javascript\nfunction formatCommand(command) {\n const { name, description, options, arguments: args, aliases } = command;\n \n // Build usage line\n let usage = `task-master ${name}`;\n \n // Add arguments\n if (args && args.length > 0) {\n args.forEach(arg => {\n if (arg.required) {\n usage += ` <${arg.name}>`;\n } else {\n usage += ` [${arg.name}]`;\n }\n });\n }\n \n // Add options indicator\n if (options && options.length > 0) {\n usage += ' [options]';\n }\n \n // Format aliases\n const aliasText = aliases && aliases.length > 0 \n ? ` (aliases: ${aliases.join(', ')})` \n : '';\n \n return {\n usage,\n description: description || 'No description available',\n aliasText,\n options: formatOptions(options)\n };\n}\n```\n\n3. **Option Formatting**:\n - Format flags with proper spacing and alignment\n - Include descriptions and default values\n - Highlight required vs optional parameters\n - Group related options together\n\n4. **Category Section Generation**:\n```javascript\nfunction generateCategorySection(categoryName, categoryData) {\n const { color, commands } = categoryData;\n \n let section = `\\n${chalk[color].bold(categoryName)}:\\n`;\n \n commands.forEach(command => {\n const formatted = formatCommand(command);\n section += ` ${chalk.cyan(formatted.usage)}${formatted.aliasText}\\n`;\n section += ` ${formatted.description}\\n`;\n \n if (formatted.options.length > 0) {\n section += ` Options:\\n`;\n formatted.options.forEach(option => {\n section += ` ${option.flags.padEnd(20)} ${option.description}\\n`;\n });\n }\n section += '\\n';\n });\n \n return section;\n}\n```\n\n5. **Responsive Formatting**:\n - Detect terminal width for optimal formatting\n - Adjust column widths based on content length\n - Handle long descriptions with proper wrapping\n - Maintain consistent indentation and spacing\n\n### Technical Implementation:\n1. **Content Assembly**:\n - Build help content in logical sections\n - Apply consistent styling and colors\n - Handle empty categories gracefully\n - Support different output formats (terminal, plain text)\n\n2. **Performance Optimization**:\n - Cache generated help content\n - Lazy-load command metadata only when needed\n - Minimize string concatenation overhead\n - Support incremental updates\n\n3. **Accessibility Features**:\n - Support no-color output for accessibility\n - Provide plain text fallbacks\n - Ensure proper screen reader compatibility\n - Support different terminal capabilities\n\n4. **Customization Options**:\n - Allow filtering by category\n - Support command-specific help\n - Enable verbose vs compact modes\n - Provide search functionality\n\n### Integration Points:\n1. **Replace Existing displayHelp()**:\n - Maintain same function signature\n - Preserve existing color scheme\n - Keep backward compatibility\n - Update all call sites\n\n2. **Add New Help Variants**:\n - `displayHelp(category)` - Show specific category\n - `displayCommandHelp(commandName)` - Detailed command help\n - `displayHelpSearch(query)` - Search-based help\n\n### Testing Requirements:\n- Test help generation for all command categories\n- Verify formatting consistency across different terminals\n- Test with various terminal widths and capabilities\n- Validate color output and no-color fallbacks\n- Performance testing with large command sets", + "status": "pending", + "dependencies": [ + 2 + ], + "parentTaskId": 100 + }, + { + "id": 4, + "title": "Integrate Dynamic Help System with Existing CLI", + "description": "Replace the static help system with the new dynamic help generation and ensure seamless integration", + "details": "## Implementation Requirements\n\n### Core Integration Tasks:\n\n1. **Replace displayHelp() Function**:\n - **Location**: `ui.js` lines 434-734\n - **Action**: Replace static help content with dynamic generation\n - **Preserve**: Existing function signature and color scheme\n - **Enhance**: Add new parameters for filtering and customization\n\n2. **Update Function Signature**:\n```javascript\n// Current: displayHelp()\n// New: displayHelp(options = {})\nfunction displayHelp(options = {}) {\n const {\n category = null, // Filter by specific category\n command = null, // Show help for specific command\n search = null, // Search query for commands\n verbose = false, // Show detailed help\n noColor = false // Disable colors for accessibility\n } = options;\n \n // Dynamic help generation logic\n}\n```\n\n3. **Integration with commands.js**:\n - **Access Program Instance**: Get reference to Commander.js program\n - **Timing**: Ensure commands are fully registered before help generation\n - **Caching**: Cache command metadata to avoid repeated parsing\n\n4. **Update Help Command Registration**:\n```javascript\n// In commands.js, update help command\nprogram\n .command('help [command]')\n .description('Display help information')\n .option('-c, --category ', 'Show help for specific category')\n .option('-s, --search ', 'Search commands by keyword')\n .option('-v, --verbose', 'Show detailed help information')\n .option('--no-color', 'Disable colored output')\n .action(async (command, options) => {\n displayHelp({\n command,\n category: options.category,\n search: options.search,\n verbose: options.verbose,\n noColor: !options.color\n });\n });\n```\n\n5. **Fallback and Error Handling**:\n - **Graceful Degradation**: Fall back to static help if dynamic generation fails\n - **Error Recovery**: Handle malformed command definitions\n - **Performance**: Ensure help generation doesn't slow down CLI startup\n\n### Technical Implementation:\n\n1. **Program Instance Access**:\n```javascript\n// Method 1: Pass program instance to displayHelp\nfunction displayHelp(options = {}, programInstance = null) {\n if (!programInstance) {\n // Fallback to static help or error\n console.warn('Dynamic help unavailable, using static fallback');\n return displayStaticHelp();\n }\n \n const commandMetadata = extractCommandMetadata(programInstance);\n const categorizedCommands = categorizeCommands(commandMetadata);\n return generateHelpContent(categorizedCommands, options);\n}\n\n// Method 2: Global program reference\nlet globalProgramInstance = null;\nexport function setProgramInstance(program) {\n globalProgramInstance = program;\n}\n```\n\n2. **Initialization Sequence**:\n - Commands are registered in `commands.js`\n - Program instance is made available to help system\n - Help system caches command metadata on first use\n - Subsequent help calls use cached data\n\n3. **Backward Compatibility**:\n - Maintain existing `displayHelp()` calls without parameters\n - Preserve existing color scheme and formatting style\n - Keep same output structure for scripts that parse help output\n\n4. **Performance Optimization**:\n - Cache command metadata after first extraction\n - Lazy-load help content generation\n - Minimize impact on CLI startup time\n - Support incremental cache updates\n\n### Integration Points:\n\n1. **Update All Help Call Sites**:\n - Search codebase for `displayHelp()` calls\n - Update calls to pass program instance or use global reference\n - Test all help invocation paths\n\n2. **Enhanced Help Commands**:\n - `task-master help` - General help (existing behavior)\n - `task-master help ` - Command-specific help\n - `task-master help --category ` - Category-specific help\n - `task-master help --search ` - Search-based help\n\n3. **Error Handling Integration**:\n - Update error messages to suggest relevant help commands\n - Provide contextual help suggestions based on failed commands\n - Integrate with existing error reporting system\n\n### Testing Requirements:\n\n1. **Integration Testing**:\n - Test help system with all existing commands\n - Verify backward compatibility with existing help calls\n - Test new help command options and parameters\n\n2. **Performance Testing**:\n - Measure help generation time with full command set\n - Test CLI startup time impact\n - Verify caching effectiveness\n\n3. **Compatibility Testing**:\n - Test with different terminal types and capabilities\n - Verify color output and no-color modes\n - Test with various screen sizes and widths\n\n4. **Error Scenario Testing**:\n - Test behavior with malformed command definitions\n - Verify fallback to static help when needed\n - Test graceful handling of missing metadata\n\n### Migration Strategy:\n\n1. **Phase 1**: Implement dynamic help system alongside existing static help\n2. **Phase 2**: Update help command to use dynamic system with fallback\n3. **Phase 3**: Replace all displayHelp() calls with dynamic version\n4. **Phase 4**: Remove static help content and cleanup old code\n5. **Phase 5**: Add enhanced help features (search, filtering, etc.)", + "status": "pending", + "dependencies": [ + 3 + ], + "parentTaskId": 100 + }, + { + "id": 5, + "title": "Add Enhanced Help Features and Search Functionality", + "description": "Implement advanced help features including command search, category filtering, and contextual help suggestions", + "details": "## Implementation Requirements\n\n### Enhanced Help Features:\n\n1. **Command Search Functionality**:\n```javascript\nfunction searchCommands(query, commandMetadata) {\n const results = [];\n const searchTerms = query.toLowerCase().split(' ');\n \n Object.values(commandMetadata).forEach(command => {\n let score = 0;\n \n // Search in command name (highest weight)\n if (command.name.toLowerCase().includes(query.toLowerCase())) {\n score += 10;\n }\n \n // Search in description (medium weight)\n if (command.description && command.description.toLowerCase().includes(query.toLowerCase())) {\n score += 5;\n }\n \n // Search in option descriptions (lower weight)\n command.options?.forEach(option => {\n if (option.description.toLowerCase().includes(query.toLowerCase())) {\n score += 2;\n }\n });\n \n // Fuzzy matching for command names\n if (fuzzyMatch(command.name, query)) {\n score += 3;\n }\n \n if (score > 0) {\n results.push({ command, score });\n }\n });\n \n return results.sort((a, b) => b.score - a.score);\n}\n```\n\n2. **Category Filtering**:\n - Allow users to view help for specific categories only\n - Support partial category name matching\n - Provide category list when invalid category specified\n - Enable multiple category selection\n\n3. **Contextual Help Suggestions**:\n```javascript\nfunction suggestRelatedCommands(commandName, commandMetadata) {\n const suggestions = [];\n const command = commandMetadata[commandName];\n \n if (!command) return suggestions;\n \n // Find commands in same category\n const category = findCommandCategory(commandName);\n if (category) {\n suggestions.push(...getCategoryCommands(category));\n }\n \n // Find commands with similar names\n Object.keys(commandMetadata).forEach(name => {\n if (name !== commandName && similarity(name, commandName) > 0.6) {\n suggestions.push(commandMetadata[name]);\n }\n });\n \n // Find commands with related functionality\n const keywords = extractKeywords(command.description);\n keywords.forEach(keyword => {\n const related = findCommandsByKeyword(keyword, commandMetadata);\n suggestions.push(...related);\n });\n \n return deduplicateAndScore(suggestions);\n}\n```\n\n4. **Interactive Help Mode**:\n - Implement step-by-step help wizard\n - Guide users through command selection\n - Provide examples and use cases\n - Support help history and bookmarks\n\n### Advanced Features:\n\n1. **Help Caching and Performance**:\n```javascript\nclass HelpCache {\n constructor() {\n this.cache = new Map();\n this.lastUpdate = null;\n this.commandMetadata = null;\n }\n \n getHelp(key, generator) {\n if (this.cache.has(key) && !this.isStale()) {\n return this.cache.get(key);\n }\n \n const content = generator();\n this.cache.set(key, content);\n return content;\n }\n \n invalidate() {\n this.cache.clear();\n this.lastUpdate = Date.now();\n }\n \n isStale() {\n return Date.now() - this.lastUpdate > 300000; // 5 minutes\n }\n}\n```\n\n2. **Help Export and Documentation**:\n - Export help content to markdown format\n - Generate man pages from command metadata\n - Create HTML documentation\n - Support JSON export for API documentation\n\n3. **Accessibility Enhancements**:\n - Screen reader friendly output\n - High contrast mode support\n - Keyboard navigation for interactive help\n - Alternative text descriptions for visual elements\n\n4. **Internationalization Support**:\n - Support for multiple languages\n - Localized command descriptions\n - Cultural formatting preferences\n - RTL language support\n\n### Command-Specific Help Features:\n\n1. **Detailed Command Help**:\n```javascript\nfunction displayCommandHelp(commandName, commandMetadata) {\n const command = commandMetadata[commandName];\n if (!command) {\n console.error(`Command '${commandName}' not found.`);\n suggestSimilarCommands(commandName, commandMetadata);\n return;\n }\n \n console.log(chalk.cyan.bold(`\\\\n${command.name.toUpperCase()} COMMAND HELP\\\\n`));\n console.log(`Description: ${command.description}\\\\n`);\n \n // Usage examples\n if (command.examples) {\n console.log(chalk.yellow.bold('Examples:'));\n command.examples.forEach(example => {\n console.log(` ${chalk.green(example.command)}`);\n console.log(` ${example.description}\\\\n`);\n });\n }\n \n // Detailed options\n if (command.options && command.options.length > 0) {\n console.log(chalk.yellow.bold('Options:'));\n command.options.forEach(option => {\n console.log(` ${chalk.cyan(option.flags.padEnd(20))} ${option.description}`);\n if (option.defaultValue) {\n console.log(`${' '.repeat(22)}Default: ${option.defaultValue}`);\n }\n if (option.examples) {\n console.log(`${' '.repeat(22)}Example: ${option.examples[0]}`);\n }\n });\n }\n \n // Related commands\n const related = suggestRelatedCommands(commandName, commandMetadata);\n if (related.length > 0) {\n console.log(chalk.yellow.bold('\\\\nRelated Commands:'));\n related.slice(0, 5).forEach(cmd => {\n console.log(` ${chalk.cyan(cmd.name)} - ${cmd.description}`);\n });\n }\n}\n```\n\n2. **Usage Examples Generation**:\n - Auto-generate common usage patterns\n - Include real-world scenarios\n - Show before/after examples\n - Provide troubleshooting tips\n\n### Error Integration:\n\n1. **Smart Error Messages**:\n```javascript\nfunction enhanceErrorWithHelp(error, commandName, commandMetadata) {\n console.error(chalk.red(error.message));\n \n // Suggest correct usage\n if (commandMetadata[commandName]) {\n console.log(chalk.yellow('\\\\nCorrect usage:'));\n console.log(` ${formatCommandUsage(commandMetadata[commandName])}`);\n }\n \n // Suggest similar commands\n const suggestions = findSimilarCommands(commandName, commandMetadata);\n if (suggestions.length > 0) {\n console.log(chalk.yellow('\\\\nDid you mean:'));\n suggestions.slice(0, 3).forEach(cmd => {\n console.log(` ${chalk.cyan(cmd.name)} - ${cmd.description}`);\n });\n }\n \n // Provide help command\n console.log(chalk.gray(`\\\\nFor more help: task-master help ${commandName}`));\n}\n```\n\n### Testing Requirements:\n\n1. **Search Functionality Testing**:\n - Test search accuracy with various queries\n - Verify fuzzy matching and scoring\n - Test performance with large command sets\n - Validate search result ranking\n\n2. **Feature Integration Testing**:\n - Test all new help command options\n - Verify category filtering accuracy\n - Test contextual suggestions relevance\n - Validate caching behavior\n\n3. **Accessibility Testing**:\n - Test with screen readers\n - Verify keyboard navigation\n - Test color contrast and no-color modes\n - Validate output formatting\n\n4. **Performance Testing**:\n - Measure search response times\n - Test caching effectiveness\n - Verify memory usage with large datasets\n - Test concurrent help requests\n\n### Documentation Updates:\n\n1. **Update README**:\n - Document new help features\n - Provide usage examples\n - Update command reference\n - Add troubleshooting section\n\n2. **Create Help Documentation**:\n - Comprehensive help system guide\n - Advanced usage patterns\n - Customization options\n - Integration examples", + "status": "pending", + "dependencies": [ + 4 + ], + "parentTaskId": 100 + }, + { + "id": 6, + "title": "Create Comprehensive Testing Suite and Documentation", + "description": "Implement thorough testing for the dynamic help system and update all relevant documentation", + "details": "## Implementation Requirements\n\n### Testing Strategy:\n\n1. **Unit Tests for Core Functions**:\n```javascript\n// tests/unit/help-system.test.js\ndescribe('Dynamic Help System', () => {\n describe('extractCommandMetadata', () => {\n test('should extract basic command information', () => {\n const mockProgram = createMockProgram();\n const metadata = extractCommandMetadata(mockProgram);\n \n expect(metadata).toHaveProperty('init');\n expect(metadata.init.name).toBe('init');\n expect(metadata.init.description).toBeDefined();\n expect(metadata.init.options).toBeArray();\n });\n \n test('should handle commands with complex options', () => {\n const mockProgram = createComplexMockProgram();\n const metadata = extractCommandMetadata(mockProgram);\n \n expect(metadata.parseRrd.options).toHaveLength(5);\n expect(metadata.parseRrd.options[0]).toHaveProperty('flags');\n expect(metadata.parseRrd.options[0]).toHaveProperty('description');\n });\n \n test('should handle missing descriptions gracefully', () => {\n const mockProgram = createIncompleteProgram();\n const metadata = extractCommandMetadata(mockProgram);\n \n expect(metadata.undocumented.description).toBe('No description available');\n });\n });\n \n describe('categorizeCommands', () => {\n test('should categorize commands correctly', () => {\n const mockMetadata = createMockMetadata();\n const categorized = categorizeCommands(mockMetadata);\n \n expect(categorized).toHaveProperty('Project Setup & Configuration');\n expect(categorized['Project Setup & Configuration'].commands).toContainEqual(\n expect.objectContaining({ name: 'init' })\n );\n });\n \n test('should handle uncategorized commands', () => {\n const mockMetadata = { unknownCommand: { name: 'unknown', description: 'test' } };\n const categorized = categorizeCommands(mockMetadata);\n \n expect(categorized).toHaveProperty('Other Commands');\n expect(categorized['Other Commands'].commands).toHaveLength(1);\n });\n });\n \n describe('generateHelpContent', () => {\n test('should generate properly formatted help content', () => {\n const mockCategorized = createMockCategorizedCommands();\n const content = generateHelpContent(mockCategorized);\n \n expect(content).toContain('Task Master CLI');\n expect(content).toContain('Project Setup & Configuration');\n expect(content).toContain('task-master init');\n });\n \n test('should handle empty categories', () => {\n const emptyCategorized = { 'Empty Category': { commands: [] } };\n const content = generateHelpContent(emptyCategorized);\n \n expect(content).not.toContain('Empty Category');\n });\n });\n});\n```\n\n2. **Integration Tests**:\n```javascript\n// tests/integration/help-integration.test.js\ndescribe('Help System Integration', () => {\n test('should integrate with actual CLI commands', async () => {\n const { program } = await import('../../scripts/modules/commands.js');\n const metadata = extractCommandMetadata(program);\n \n // Verify all expected commands are present\n const expectedCommands = ['init', 'parse-prd', 'list', 'add-task', 'expand'];\n expectedCommands.forEach(cmd => {\n expect(metadata).toHaveProperty(cmd);\n });\n });\n \n test('should maintain backward compatibility', () => {\n const originalHelp = captureConsoleOutput(() => {\n displayHelp(); // Original function call\n });\n \n expect(originalHelp).toContain('Task Master CLI');\n expect(originalHelp).toContain('Available Commands');\n });\n \n test('should handle help command with options', () => {\n const categoryHelp = captureConsoleOutput(() => {\n displayHelp({ category: 'Task Management' });\n });\n \n expect(categoryHelp).toContain('Task Management');\n expect(categoryHelp).toContain('list');\n expect(categoryHelp).not.toContain('init'); // Should not contain other categories\n });\n});\n```\n\n3. **Performance Tests**:\n```javascript\n// tests/performance/help-performance.test.js\ndescribe('Help System Performance', () => {\n test('should extract metadata within acceptable time', () => {\n const start = performance.now();\n const metadata = extractCommandMetadata(largeMockProgram);\n const end = performance.now();\n \n expect(end - start).toBeLessThan(100); // Should complete in under 100ms\n });\n \n test('should cache help content effectively', () => {\n const cache = new HelpCache();\n \n const start1 = performance.now();\n const content1 = cache.getHelp('main', () => generateHelpContent(mockData));\n const end1 = performance.now();\n \n const start2 = performance.now();\n const content2 = cache.getHelp('main', () => generateHelpContent(mockData));\n const end2 = performance.now();\n \n expect(content1).toBe(content2);\n expect(end2 - start2).toBeLessThan((end1 - start1) / 10); // Cached should be 10x faster\n });\n});\n```\n\n4. **Accessibility Tests**:\n```javascript\n// tests/accessibility/help-accessibility.test.js\ndescribe('Help System Accessibility', () => {\n test('should provide no-color output', () => {\n const noColorHelp = captureConsoleOutput(() => {\n displayHelp({ noColor: true });\n });\n \n // Should not contain ANSI color codes\n expect(noColorHelp).not.toMatch(/\\u001b\\[[0-9;]*m/);\n });\n \n test('should format content for screen readers', () => {\n const accessibleHelp = generateAccessibleHelp(mockMetadata);\n \n expect(accessibleHelp).toContain('Heading level 1: Task Master CLI');\n expect(accessibleHelp).toContain('List item: init command');\n });\n});\n```\n\n### Mock Data and Utilities:\n\n1. **Mock Program Creation**:\n```javascript\n// tests/utils/mock-program.js\nexport function createMockProgram() {\n return {\n commands: [\n {\n _name: 'init',\n _description: 'Initialize a new Task Master project',\n _aliases: [],\n options: [\n {\n flags: '-y, --yes',\n description: 'Skip prompts and use defaults',\n required: false,\n defaultValue: false\n }\n ],\n _args: []\n },\n {\n _name: 'list',\n _description: 'List all tasks',\n _aliases: ['ls'],\n options: [\n {\n flags: '-s, --status ',\n description: 'Filter by status',\n required: false\n }\n ],\n _args: []\n }\n ]\n };\n}\n```\n\n2. **Test Utilities**:\n```javascript\n// tests/utils/test-helpers.js\nexport function captureConsoleOutput(fn) {\n const originalLog = console.log;\n let output = '';\n \n console.log = (...args) => {\n output += args.join(' ') + '\\n';\n };\n \n try {\n fn();\n return output;\n } finally {\n console.log = originalLog;\n }\n}\n\nexport function stripAnsiColors(text) {\n return text.replace(/\\u001b\\[[0-9;]*m/g, '');\n}\n```\n\n### Documentation Updates:\n\n1. **README.md Updates**:\n```markdown\n## Enhanced Help System\n\nTask Master now features a dynamic help system that automatically generates help content from your CLI commands.\n\n### Basic Help\n```bash\ntask-master help\n```\n\n### Category-Specific Help\n```bash\ntask-master help --category \"Task Management\"\n```\n\n### Command Search\n```bash\ntask-master help --search \"dependency\"\n```\n\n### Command-Specific Help\n```bash\ntask-master help add-task\n```\n\n### Advanced Options\n- `--verbose`: Show detailed help with examples\n- `--no-color`: Disable colored output for accessibility\n- `--search `: Search commands by keyword\n- `--category `: Filter by command category\n```\n\n2. **API Documentation**:\n```markdown\n## Help System API\n\n### Core Functions\n\n#### `extractCommandMetadata(programInstance)`\nExtracts command metadata from a Commander.js program instance.\n\n**Parameters:**\n- `programInstance` (Object): Commander.js program instance\n\n**Returns:**\n- Object containing command metadata\n\n#### `categorizeCommands(commandMetadata)`\nCategorizes commands into logical groups.\n\n**Parameters:**\n- `commandMetadata` (Object): Command metadata from extractCommandMetadata\n\n**Returns:**\n- Object with categorized commands\n\n#### `generateHelpContent(categorizedCommands, options)`\nGenerates formatted help content.\n\n**Parameters:**\n- `categorizedCommands` (Object): Categorized command data\n- `options` (Object): Formatting options\n\n**Returns:**\n- String containing formatted help content\n```\n\n3. **Developer Guide**:\n```markdown\n## Extending the Help System\n\n### Adding New Categories\nTo add a new command category, update the `categoryRules` object:\n\n```javascript\nconst categoryRules = {\n 'Your New Category': {\n commands: ['command1', 'command2'],\n patterns: [/^pattern/],\n keywords: ['keyword1', 'keyword2'],\n color: 'blue'\n }\n};\n```\n\n### Custom Help Formatters\nCreate custom help formatters for specific use cases:\n\n```javascript\nfunction customHelpFormatter(command) {\n // Your custom formatting logic\n return formattedContent;\n}\n```\n```\n\n### Continuous Integration:\n\n1. **GitHub Actions Workflow**:\n```yaml\n# .github/workflows/help-system-tests.yml\nname: Help System Tests\n\non: [push, pull_request]\n\njobs:\n test-help-system:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v3\n - uses: actions/setup-node@v3\n with:\n node-version: '18'\n - run: npm ci\n - run: npm run test:help-system\n - run: npm run test:help-accessibility\n - run: npm run test:help-performance\n```\n\n2. **Test Scripts in package.json**:\n```json\n{\n \"scripts\": {\n \"test:help-system\": \"jest tests/unit/help-system.test.js tests/integration/help-integration.test.js\",\n \"test:help-accessibility\": \"jest tests/accessibility/help-accessibility.test.js\",\n \"test:help-performance\": \"jest tests/performance/help-performance.test.js\",\n \"test:help-all\": \"npm run test:help-system && npm run test:help-accessibility && npm run test:help-performance\"\n }\n}\n```\n\n### Quality Assurance:\n\n1. **Code Coverage Requirements**:\n - Minimum 90% coverage for help system functions\n - 100% coverage for critical path functions\n - Integration test coverage for all CLI commands\n\n2. **Performance Benchmarks**:\n - Help generation: < 100ms for full help\n - Command search: < 50ms for typical queries\n - Cache hit ratio: > 95% for repeated requests\n\n3. **Accessibility Standards**:\n - WCAG 2.1 AA compliance for terminal output\n - Screen reader compatibility testing\n - High contrast mode support\n - Keyboard navigation support", + "status": "pending", "dependencies": [ - 1, - 2, - 3, - 4, 5 ], - "details": "Update CLI documentation and ensure the --help flag provides comprehensive guidance on using the command, its options, and expected outputs.", - "status": "pending" + "parentTaskId": 100 + } + ] + }, + { + "id": 101, + "title": "Implement GitHub Issue Export Feature with Bidirectional Linking", + "description": "Add a 'github-export' command that creates GitHub issues from Task Master tasks and establishes bidirectional linking between tasks and issues. This complements the import feature by enabling full GitHub integration workflow.", + "details": "## Core Problem Statement\n\nUsers need the ability to export Task Master tasks to GitHub issues to:\n\n1. **Share Tasks with Team**: Convert internal tasks to GitHub issues for team collaboration\n2. **Track Progress Publicly**: Make task progress visible in GitHub project boards\n3. **Integrate with GitHub Workflow**: Connect Task Master planning with GitHub development workflow\n4. **Maintain Synchronization**: Keep tasks and issues linked for status updates\n5. **Enable Hybrid Workflow**: Allow teams to work with both Task Master and GitHub seamlessly\n\n## Core Requirements\n\n### 1. GitHub Export Command\n- **Command**: `task-master github-export --id= --repo= [options]`\n- **Functionality**: Create GitHub issue from Task Master task\n- **Authentication**: Use GitHub Personal Access Token or OAuth\n- **Repository Target**: Support any accessible GitHub repository\n\n### 2. Bidirectional Linking System\n- **Task → Issue**: Store GitHub issue URL in task metadata\n- **Issue → Task**: Include Task Master reference in GitHub issue description\n- **Link Validation**: Verify links remain valid and accessible\n- **Link Display**: Show GitHub links in task views and vice versa\n\n### 3. Content Mapping and Formatting\n- **Title Mapping**: Task title → GitHub issue title\n- **Description Mapping**: Task description → GitHub issue description\n- **Details Conversion**: Convert Task Master details to GitHub markdown\n- **Metadata Preservation**: Include Task Master ID, priority, status in issue\n- **Subtask Handling**: Convert subtasks to GitHub issue checklist or separate issues\n\n### 4. Advanced Export Options\n- **Selective Export**: Choose which task fields to include\n- **Template Customization**: Custom GitHub issue templates\n- **Label Management**: Map Task Master priorities/tags to GitHub labels\n- **Assignee Mapping**: Map Task Master assignments to GitHub assignees\n- **Milestone Integration**: Connect tasks to GitHub milestones\n\n## Technical Implementation Requirements\n\n### 1. GitHub API Integration\n```javascript\n// Core export service\nclass GitHubExportService {\n constructor(token, baseURL = 'https://api.github.com') {\n this.token = token;\n this.baseURL = baseURL;\n this.rateLimiter = new RateLimiter();\n }\n \n async exportTask(task, repoOwner, repoName, options = {}) {\n // Validate repository access\n // Format task content for GitHub\n // Create GitHub issue via API\n // Update task with GitHub link\n // Return export result\n }\n \n async updateTaskWithGitHubLink(taskId, issueUrl) {\n // Add GitHub link to task metadata\n // Update task file with link reference\n // Regenerate task files if needed\n }\n}\n```\n\n### 2. Content Formatting System\n```javascript\nclass TaskToGitHubFormatter {\n formatIssueTitle(task) {\n return `[Task ${task.id}] ${task.title}`;\n }\n \n formatIssueDescription(task) {\n let description = `# ${task.title}\\n\\n`;\n description += `**Task Master ID**: ${task.id}\\n`;\n description += `**Priority**: ${task.priority}\\n`;\n description += `**Status**: ${task.status}\\n\\n`;\n \n if (task.description) {\n description += `## Description\\n${task.description}\\n\\n`;\n }\n \n if (task.details) {\n description += `## Implementation Details\\n${task.details}\\n\\n`;\n }\n \n if (task.subtasks && task.subtasks.length > 0) {\n description += `## Subtasks\\n`;\n task.subtasks.forEach(subtask => {\n const checked = subtask.status === 'done' ? 'x' : ' ';\n description += `- [${checked}] ${subtask.title}\\n`;\n });\n }\n \n description += `\\n---\\n*Exported from Task Master*`;\n return description;\n }\n}\n```\n\n### 3. Bidirectional Link Management\n```javascript\nclass LinkManager {\n async addGitHubLinkToTask(taskId, issueUrl, issueNumber) {\n const task = await getTask(taskId);\n \n if (!task.metadata) task.metadata = {};\n task.metadata.githubIssue = {\n url: issueUrl,\n number: issueNumber,\n exportedAt: new Date().toISOString(),\n repository: this.extractRepoFromUrl(issueUrl)\n };\n \n await updateTask(taskId, task);\n await regenerateTaskFiles();\n }\n \n async validateGitHubLink(issueUrl) {\n // Check if GitHub issue still exists\n // Verify access permissions\n // Return link status\n }\n \n generateTaskMasterReference(taskId, projectName) {\n return `\\n\\n---\\n**Task Master Reference**: Task #${taskId} in project \"${projectName}\"`;\n }\n}\n```\n\n### 4. Command Line Interface\n```javascript\n// In commands.js\nprogram\n .command('github-export')\n .description('Export Task Master task to GitHub issue')\n .requiredOption('-i, --id ', 'Task ID to export')\n .requiredOption('-r, --repo ', 'Target GitHub repository')\n .option('-t, --token ', 'GitHub Personal Access Token (or use GITHUB_TOKEN env var)')\n .option('--title ', 'Override issue title')\n .option('--labels <labels>', 'Comma-separated list of GitHub labels')\n .option('--assignees <assignees>', 'Comma-separated list of GitHub usernames')\n .option('--milestone <milestone>', 'GitHub milestone number or title')\n .option('--template <template>', 'Custom issue template file')\n .option('--include-subtasks', 'Export subtasks as checklist items')\n .option('--separate-subtasks', 'Create separate issues for subtasks')\n .option('--dry-run', 'Preview the issue content without creating it')\n .option('--force', 'Overwrite existing GitHub link if present')\n .action(async (options) => {\n await handleGitHubExport(options);\n });\n```\n\n### 5. MCP Tool Integration\n```javascript\n// MCP tool for github-export\nexport function registerGitHubExportTool(server) {\n server.addTool({\n name: \"github_export_task\",\n description: \"Export a Task Master task to GitHub issue with bidirectional linking\",\n parameters: {\n type: \"object\",\n properties: {\n taskId: { type: \"string\", description: \"Task ID to export\" },\n repository: { type: \"string\", description: \"GitHub repository (owner/repo)\" },\n token: { type: \"string\", description: \"GitHub Personal Access Token\" },\n options: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Override issue title\" },\n labels: { type: \"array\", items: { type: \"string\" } },\n assignees: { type: \"array\", items: { type: \"string\" } },\n milestone: { type: \"string\", description: \"Milestone number or title\" },\n includeSubtasks: { type: \"boolean\", description: \"Include subtasks as checklist\" },\n separateSubtasks: { type: \"boolean\", description: \"Create separate issues for subtasks\" },\n dryRun: { type: \"boolean\", description: \"Preview without creating\" }\n }\n }\n },\n required: [\"taskId\", \"repository\"]\n },\n execute: async (args) => {\n return await gitHubExportDirect(args);\n }\n });\n}\n```\n\n## Advanced Features\n\n### 1. Batch Export\n- Export multiple tasks at once\n- Maintain relationships between exported issues\n- Progress tracking for bulk operations\n- Rollback capability for failed exports\n\n### 2. Synchronization Features\n- **Status Sync**: Update Task Master when GitHub issue status changes\n- **Comment Sync**: Sync comments between Task Master and GitHub\n- **Webhook Integration**: Real-time updates via GitHub webhooks\n- **Conflict Resolution**: Handle conflicting updates gracefully\n\n### 3. Template System\n```javascript\n// Custom export templates\nconst issueTemplates = {\n bug: {\n title: \"[BUG] {task.title}\",\n labels: [\"bug\", \"task-master\"],\n body: `## Bug Description\\n{task.description}\\n\\n## Steps to Reproduce\\n{task.details}`\n },\n feature: {\n title: \"[FEATURE] {task.title}\",\n labels: [\"enhancement\", \"task-master\"],\n body: `## Feature Request\\n{task.description}\\n\\n## Implementation Details\\n{task.details}`\n }\n};\n```\n\n### 4. Integration with GitHub Projects\n- Automatically add exported issues to GitHub project boards\n- Map Task Master status to GitHub project columns\n- Sync priority levels with GitHub project priorities\n\n## Error Handling and Edge Cases\n\n### 1. Authentication Issues\n- Invalid or expired GitHub tokens\n- Insufficient repository permissions\n- Rate limiting and quota management\n\n### 2. Repository Issues\n- Non-existent repositories\n- Private repository access\n- Repository permission changes\n\n### 3. Content Issues\n- Task content too large for GitHub issue\n- Invalid characters in titles or descriptions\n- Markdown formatting conflicts\n\n### 4. Link Management Issues\n- Broken or invalid GitHub links\n- Deleted GitHub issues\n- Repository transfers or renames\n\n## Testing Strategy\n\n### 1. Unit Tests\n- GitHub API client functionality\n- Content formatting and conversion\n- Link management operations\n- Error handling scenarios\n\n### 2. Integration Tests\n- End-to-end export workflow\n- Bidirectional linking verification\n- GitHub API integration\n- Authentication flow testing\n\n### 3. Performance Tests\n- Bulk export operations\n- Rate limiting compliance\n- Large task content handling\n- Concurrent export operations\n\n## Security Considerations\n\n### 1. Token Management\n- Secure storage of GitHub tokens\n- Token validation and refresh\n- Scope limitation and permissions\n- Environment variable protection\n\n### 2. Data Privacy\n- Sensitive information filtering\n- Private repository handling\n- User consent for public exports\n- Audit logging for exports\n\n## Documentation Requirements\n\n### 1. User Guide\n- Setup and authentication instructions\n- Export workflow examples\n- Troubleshooting common issues\n- Best practices for GitHub integration\n\n### 2. API Documentation\n- MCP tool reference\n- CLI command documentation\n- Configuration options\n- Integration examples\n\n### 3. Developer Guide\n- Extension points for custom templates\n- Webhook setup instructions\n- Advanced configuration options\n- Contributing guidelines", + "testStrategy": "", + "status": "pending", + "dependencies": [], + "priority": "high", + "subtasks": [ + { + "id": 1, + "title": "Implement GitHub API Export Service", + "description": "Create the core service for exporting tasks to GitHub issues via the GitHub REST API", + "details": "## Implementation Requirements\n\n### Core GitHub Export Service\n```javascript\n// scripts/modules/github/github-export-service.js\nclass GitHubExportService {\n constructor(token, options = {}) {\n this.token = token;\n this.baseURL = options.baseURL || 'https://api.github.com';\n this.rateLimiter = new RateLimiter({\n tokensPerInterval: 5000, // GitHub API limit\n interval: 'hour'\n });\n }\n \n async exportTask(task, repoOwner, repoName, exportOptions = {}) {\n // Validate repository access\n await this.validateRepositoryAccess(repoOwner, repoName);\n \n // Format task content for GitHub\n const issueData = this.formatTaskAsIssue(task, exportOptions);\n \n // Create GitHub issue\n const issue = await this.createGitHubIssue(repoOwner, repoName, issueData);\n \n // Update task with GitHub link\n await this.updateTaskWithGitHubLink(task.id, issue.html_url, issue.number);\n \n return {\n success: true,\n issue: issue,\n taskId: task.id,\n issueUrl: issue.html_url\n };\n }\n}\n```\n\n### Repository Validation\n- **Access Check**: Verify user has write access to target repository\n- **Repository Existence**: Confirm repository exists and is accessible\n- **Permission Validation**: Check if user can create issues in the repository\n- **Rate Limit Check**: Ensure API quota is available for the operation\n\n### Issue Creation Logic\n```javascript\nasync createGitHubIssue(owner, repo, issueData) {\n const response = await this.makeAPIRequest('POST', `/repos/${owner}/${repo}/issues`, {\n title: issueData.title,\n body: issueData.body,\n labels: issueData.labels || [],\n assignees: issueData.assignees || [],\n milestone: issueData.milestone || null\n });\n \n if (!response.ok) {\n throw new GitHubAPIError(`Failed to create issue: ${response.statusText}`);\n }\n \n return response.json();\n}\n```\n\n### Error Handling\n- **Authentication Errors**: Invalid or expired tokens\n- **Permission Errors**: Insufficient repository access\n- **Rate Limiting**: Handle API quota exceeded\n- **Network Errors**: Connection timeouts and failures\n- **Validation Errors**: Invalid repository or issue data\n\n### Testing Requirements\n- Unit tests for API client methods\n- Mock GitHub API responses for testing\n- Error scenario testing (invalid repos, auth failures)\n- Rate limiting behavior verification\n- Integration tests with real GitHub API (using test repositories)", + "status": "pending", + "dependencies": [], + "parentTaskId": 101 + }, + { + "id": 2, + "title": "Create Task-to-GitHub Content Formatter", + "description": "Implement intelligent content formatting to convert Task Master tasks into properly formatted GitHub issues", + "details": "## Implementation Requirements\n\n### Core Formatting Service\n```javascript\n// scripts/modules/github/task-formatter.js\nclass TaskToGitHubFormatter {\n constructor(options = {}) {\n this.options = {\n includeTaskId: true,\n includeMetadata: true,\n convertSubtasksToChecklist: true,\n addTaskMasterReference: true,\n ...options\n };\n }\n \n formatTaskAsIssue(task, exportOptions = {}) {\n return {\n title: this.formatTitle(task, exportOptions),\n body: this.formatBody(task, exportOptions),\n labels: this.formatLabels(task, exportOptions),\n assignees: this.formatAssignees(task, exportOptions)\n };\n }\n}\n```\n\n### Title Formatting\n```javascript\nformatTitle(task, options) {\n let title = task.title;\n \n // Add task ID prefix if enabled\n if (this.options.includeTaskId && !options.hideTaskId) {\n title = `[Task ${task.id}] ${title}`;\n }\n \n // Add priority indicator for high priority tasks\n if (task.priority === 'high') {\n title = `🔥 ${title}`;\n }\n \n // Truncate if too long (GitHub limit is 256 characters)\n if (title.length > 250) {\n title = title.substring(0, 247) + '...';\n }\n \n return title;\n}\n```\n\n### Body Formatting\n```javascript\nformatBody(task, options) {\n let body = '';\n \n // Header with task metadata\n if (this.options.includeMetadata) {\n body += this.formatMetadataSection(task);\n }\n \n // Main description\n if (task.description) {\n body += `## Description\\n\\n${task.description}\\n\\n`;\n }\n \n // Implementation details\n if (task.details) {\n body += `## Implementation Details\\n\\n${this.formatDetails(task.details)}\\n\\n`;\n }\n \n // Test strategy\n if (task.testStrategy) {\n body += `## Test Strategy\\n\\n${task.testStrategy}\\n\\n`;\n }\n \n // Subtasks as checklist\n if (task.subtasks && task.subtasks.length > 0 && this.options.convertSubtasksToChecklist) {\n body += this.formatSubtasksSection(task.subtasks);\n }\n \n // Dependencies\n if (task.dependencies && task.dependencies.length > 0) {\n body += this.formatDependenciesSection(task.dependencies);\n }\n \n // Task Master reference\n if (this.options.addTaskMasterReference) {\n body += this.formatTaskMasterReference(task);\n }\n \n return body;\n}\n```\n\n### Metadata Section\n```javascript\nformatMetadataSection(task) {\n let metadata = '## Task Information\\n\\n';\n metadata += `| Field | Value |\\n`;\n metadata += `|-------|-------|\\n`;\n metadata += `| **Task ID** | ${task.id} |\\n`;\n metadata += `| **Priority** | ${this.formatPriority(task.priority)} |\\n`;\n metadata += `| **Status** | ${this.formatStatus(task.status)} |\\n`;\n \n if (task.dependencies && task.dependencies.length > 0) {\n metadata += `| **Dependencies** | ${task.dependencies.join(', ')} |\\n`;\n }\n \n if (task.complexityScore) {\n metadata += `| **Complexity** | ${task.complexityScore}/10 |\\n`;\n }\n \n metadata += '\\n';\n return metadata;\n}\n```\n\n### Subtasks Formatting\n```javascript\nformatSubtasksSection(subtasks) {\n let section = '## Subtasks\\n\\n';\n \n subtasks.forEach(subtask => {\n const checked = subtask.status === 'done' ? 'x' : ' ';\n section += `- [${checked}] **${subtask.title}**`;\n \n if (subtask.description) {\n section += ` - ${subtask.description}`;\n }\n \n section += '\\n';\n \n // Add subtask details as indented content\n if (subtask.details) {\n const indentedDetails = subtask.details\n .split('\\n')\n .map(line => ` ${line}`)\n .join('\\n');\n section += `${indentedDetails}\\n`;\n }\n });\n \n section += '\\n';\n return section;\n}\n```\n\n### Label Generation\n```javascript\nformatLabels(task, options) {\n const labels = [];\n \n // Always add task-master label\n labels.push('task-master');\n \n // Priority-based labels\n if (task.priority === 'high') {\n labels.push('priority:high');\n } else if (task.priority === 'low') {\n labels.push('priority:low');\n }\n \n // Status-based labels\n if (task.status === 'in-progress') {\n labels.push('in-progress');\n }\n \n // Complexity-based labels\n if (task.complexityScore >= 8) {\n labels.push('complexity:high');\n } else if (task.complexityScore <= 3) {\n labels.push('complexity:low');\n }\n \n // Custom labels from options\n if (options.labels) {\n labels.push(...options.labels);\n }\n \n return labels;\n}\n```\n\n### Markdown Conversion\n```javascript\nformatDetails(details) {\n // Convert Task Master specific formatting to GitHub markdown\n let formatted = details;\n \n // Convert code blocks\n formatted = formatted.replace(/```(\\w+)?\\n([\\s\\S]*?)```/g, (match, lang, code) => {\n return `\\`\\`\\`${lang || ''}\\n${code}\\`\\`\\``;\n });\n \n // Convert inline code\n formatted = formatted.replace(/`([^`]+)`/g, '`$1`');\n \n // Convert headers\n formatted = formatted.replace(/^(#{1,6})\\s+(.+)$/gm, '$1 $2');\n \n // Convert lists\n formatted = formatted.replace(/^\\s*[-*+]\\s+(.+)$/gm, '- $1');\n \n // Convert numbered lists\n formatted = formatted.replace(/^\\s*\\d+\\.\\s+(.+)$/gm, (match, content, offset, string) => {\n const lineNumber = string.substring(0, offset).split('\\n').length;\n return `${lineNumber}. ${content}`;\n });\n \n return formatted;\n}\n```\n\n### Task Master Reference\n```javascript\nformatTaskMasterReference(task) {\n return `\\n---\\n\\n*This issue was exported from Task Master*\\n\\n` +\n `**Original Task**: #${task.id}\\n` +\n `**Exported**: ${new Date().toISOString()}\\n` +\n `**Task Master Project**: ${this.getProjectName()}\\n`;\n}\n```\n\n### Template System\n```javascript\nclass IssueTemplateManager {\n constructor() {\n this.templates = {\n default: new DefaultTemplate(),\n bug: new BugTemplate(),\n feature: new FeatureTemplate(),\n epic: new EpicTemplate()\n };\n }\n \n applyTemplate(task, templateName, options) {\n const template = this.templates[templateName] || this.templates.default;\n return template.format(task, options);\n }\n}\n\nclass BugTemplate extends TaskToGitHubFormatter {\n formatTitle(task, options) {\n return `🐛 [BUG] ${task.title}`;\n }\n \n formatBody(task, options) {\n let body = '## Bug Report\\n\\n';\n body += `**Task ID**: ${task.id}\\n\\n`;\n \n if (task.description) {\n body += `### Description\\n${task.description}\\n\\n`;\n }\n \n if (task.details) {\n body += `### Steps to Reproduce\\n${task.details}\\n\\n`;\n }\n \n body += `### Expected Behavior\\n<!-- Describe what should happen -->\\n\\n`;\n body += `### Actual Behavior\\n<!-- Describe what actually happens -->\\n\\n`;\n \n return body + this.formatTaskMasterReference(task);\n }\n}\n```\n\n### Testing Requirements\n- Unit tests for all formatting methods\n- Test with various task structures (with/without subtasks, different priorities)\n- Markdown conversion accuracy testing\n- Template system testing\n- Character limit and truncation testing\n- Special character handling (emojis, unicode)\n- Large content handling and performance testing", + "status": "pending", + "dependencies": [ + 1 + ], + "parentTaskId": 101 + }, + { + "id": 3, + "title": "Implement Bidirectional Link Management System", + "description": "Create a robust system for managing links between Task Master tasks and GitHub issues, including validation and synchronization", + "details": "## Implementation Requirements\n\n### Core Link Management Service\n```javascript\n// scripts/modules/github/link-manager.js\nclass GitHubLinkManager {\n constructor(githubService) {\n this.githubService = githubService;\n this.linkCache = new Map();\n }\n \n async addGitHubLinkToTask(taskId, issueUrl, issueNumber, repository) {\n const task = await this.getTask(taskId);\n \n // Initialize metadata if it doesn't exist\n if (!task.metadata) {\n task.metadata = {};\n }\n \n // Add GitHub link information\n task.metadata.githubIssue = {\n url: issueUrl,\n number: issueNumber,\n repository: repository,\n exportedAt: new Date().toISOString(),\n lastValidated: new Date().toISOString(),\n status: 'active'\n };\n \n // Update task in storage\n await this.updateTask(taskId, task);\n \n // Regenerate task files to include the link\n await this.regenerateTaskFiles();\n \n // Cache the link for quick access\n this.linkCache.set(taskId, task.metadata.githubIssue);\n \n return task.metadata.githubIssue;\n }\n}\n```\n\n### Task Metadata Schema\n```javascript\n// Enhanced task structure with GitHub integration\nconst taskWithGitHubLink = {\n id: 42,\n title: \"Example Task\",\n description: \"Task description\",\n // ... other task fields ...\n metadata: {\n githubIssue: {\n url: \"https://github.com/owner/repo/issues/123\",\n number: 123,\n repository: \"owner/repo\",\n exportedAt: \"2024-01-15T10:30:00.000Z\",\n lastValidated: \"2024-01-15T10:30:00.000Z\",\n status: \"active\", // active, closed, deleted, invalid\n syncEnabled: true,\n lastSyncAt: \"2024-01-15T10:30:00.000Z\"\n },\n // Other metadata fields...\n }\n};\n```\n\n### Link Validation System\n```javascript\nclass LinkValidator {\n constructor(githubService) {\n this.githubService = githubService;\n }\n \n async validateGitHubLink(taskId, linkInfo) {\n try {\n const { repository, number } = linkInfo;\n const [owner, repo] = repository.split('/');\n \n // Check if issue still exists\n const issue = await this.githubService.getIssue(owner, repo, number);\n \n if (!issue) {\n return {\n valid: false,\n status: 'deleted',\n message: 'GitHub issue no longer exists'\n };\n }\n \n // Check if issue is closed\n const status = issue.state === 'open' ? 'active' : 'closed';\n \n // Update link status if changed\n if (linkInfo.status !== status) {\n await this.updateLinkStatus(taskId, status);\n }\n \n return {\n valid: true,\n status: status,\n issue: issue,\n lastValidated: new Date().toISOString()\n };\n \n } catch (error) {\n if (error.status === 404) {\n return {\n valid: false,\n status: 'deleted',\n message: 'GitHub issue not found'\n };\n } else if (error.status === 403) {\n return {\n valid: false,\n status: 'access_denied',\n message: 'Access denied to GitHub issue'\n };\n }\n \n throw error;\n }\n }\n \n async validateAllLinks() {\n const tasks = await this.getAllTasksWithGitHubLinks();\n const results = [];\n \n for (const task of tasks) {\n if (task.metadata?.githubIssue) {\n const result = await this.validateGitHubLink(task.id, task.metadata.githubIssue);\n results.push({\n taskId: task.id,\n ...result\n });\n }\n }\n \n return results;\n }\n}\n```\n\n### Task File Enhancement\n```javascript\n// Enhanced task file generation with GitHub links\nclass TaskFileGenerator {\n generateTaskFile(task) {\n let content = this.generateBasicTaskContent(task);\n \n // Add GitHub integration section if link exists\n if (task.metadata?.githubIssue) {\n content += this.generateGitHubSection(task.metadata.githubIssue);\n }\n \n return content;\n }\n \n generateGitHubSection(githubInfo) {\n let section = '\\n## GitHub Integration\\n\\n';\n \n section += `**GitHub Issue**: [#${githubInfo.number}](${githubInfo.url})\\n`;\n section += `**Repository**: ${githubInfo.repository}\\n`;\n section += `**Status**: ${this.formatGitHubStatus(githubInfo.status)}\\n`;\n section += `**Exported**: ${new Date(githubInfo.exportedAt).toLocaleDateString()}\\n`;\n \n if (githubInfo.lastValidated) {\n section += `**Last Validated**: ${new Date(githubInfo.lastValidated).toLocaleDateString()}\\n`;\n }\n \n if (githubInfo.status === 'closed') {\n section += '\\n> ⚠️ **Note**: The linked GitHub issue has been closed.\\n';\n } else if (githubInfo.status === 'deleted') {\n section += '\\n> ❌ **Warning**: The linked GitHub issue no longer exists.\\n';\n }\n \n return section;\n }\n \n formatGitHubStatus(status) {\n const statusMap = {\n 'active': '🟢 Active',\n 'closed': '🔴 Closed',\n 'deleted': '❌ Deleted',\n 'invalid': '⚠️ Invalid',\n 'access_denied': '🔒 Access Denied'\n };\n \n return statusMap[status] || status;\n }\n}\n```\n\n### GitHub Issue Reference System\n```javascript\nclass GitHubReferenceManager {\n generateTaskMasterReference(taskId, projectName, taskUrl = null) {\n let reference = '\\n\\n---\\n\\n';\n reference += '**🔗 Task Master Integration**\\n\\n';\n reference += `- **Task ID**: #${taskId}\\n`;\n reference += `- **Project**: ${projectName}\\n`;\n reference += `- **Exported**: ${new Date().toISOString()}\\n`;\n \n if (taskUrl) {\n reference += `- **Task URL**: [View in Task Master](${taskUrl})\\n`;\n }\n \n reference += '\\n*This issue is managed by Task Master. Changes made here may be overwritten during synchronization.*\\n';\n \n return reference;\n }\n \n async updateGitHubIssueWithTaskReference(issueUrl, taskId, projectName) {\n const { owner, repo, number } = this.parseGitHubUrl(issueUrl);\n const issue = await this.githubService.getIssue(owner, repo, number);\n \n if (!issue) {\n throw new Error('GitHub issue not found');\n }\n \n // Check if Task Master reference already exists\n const hasReference = issue.body.includes('Task Master Integration');\n \n if (!hasReference) {\n const reference = this.generateTaskMasterReference(taskId, projectName);\n const updatedBody = issue.body + reference;\n \n await this.githubService.updateIssue(owner, repo, number, {\n body: updatedBody\n });\n }\n }\n}\n```\n\n### Link Synchronization\n```javascript\nclass LinkSynchronizer {\n constructor(githubService, linkManager) {\n this.githubService = githubService;\n this.linkManager = linkManager;\n }\n \n async syncTaskWithGitHubIssue(taskId) {\n const task = await this.getTask(taskId);\n const githubInfo = task.metadata?.githubIssue;\n \n if (!githubInfo || !githubInfo.syncEnabled) {\n return { synced: false, reason: 'Sync not enabled' };\n }\n \n const { repository, number } = githubInfo;\n const [owner, repo] = repository.split('/');\n \n try {\n const issue = await this.githubService.getIssue(owner, repo, number);\n \n if (!issue) {\n await this.linkManager.updateLinkStatus(taskId, 'deleted');\n return { synced: false, reason: 'Issue deleted' };\n }\n \n // Sync status changes\n const changes = await this.detectChanges(task, issue);\n \n if (changes.length > 0) {\n await this.applyChanges(taskId, changes);\n await this.linkManager.updateLastSync(taskId);\n \n return { \n synced: true, \n changes: changes,\n lastSync: new Date().toISOString()\n };\n }\n \n return { synced: true, changes: [] };\n \n } catch (error) {\n console.error(`Failed to sync task ${taskId}:`, error);\n return { synced: false, error: error.message };\n }\n }\n \n async detectChanges(task, issue) {\n const changes = [];\n \n // Check if GitHub issue was closed and task is still pending\n if (issue.state === 'closed' && task.status !== 'done') {\n changes.push({\n type: 'status',\n from: task.status,\n to: 'done',\n reason: 'GitHub issue closed'\n });\n }\n \n // Check if GitHub issue was reopened and task is done\n if (issue.state === 'open' && task.status === 'done') {\n changes.push({\n type: 'status',\n from: task.status,\n to: 'in-progress',\n reason: 'GitHub issue reopened'\n });\n }\n \n return changes;\n }\n}\n```\n\n### CLI Integration\n```javascript\n// Add link management commands\nprogram\n .command('github-link')\n .description('Manage GitHub links for tasks')\n .option('--validate', 'Validate all GitHub links')\n .option('--sync <taskId>', 'Sync specific task with GitHub')\n .option('--sync-all', 'Sync all linked tasks')\n .option('--remove <taskId>', 'Remove GitHub link from task')\n .action(async (options) => {\n if (options.validate) {\n await validateAllGitHubLinks();\n } else if (options.sync) {\n await syncTaskWithGitHub(options.sync);\n } else if (options.syncAll) {\n await syncAllTasksWithGitHub();\n } else if (options.remove) {\n await removeGitHubLink(options.remove);\n }\n });\n```\n\n### Testing Requirements\n- Unit tests for link management operations\n- Integration tests with GitHub API\n- Link validation testing (valid, invalid, deleted issues)\n- Synchronization testing with various scenarios\n- Error handling testing (network failures, auth issues)\n- Performance testing with large numbers of linked tasks\n- Cache behavior testing\n- Concurrent operation testing", + "status": "pending", + "dependencies": [ + 2 + ], + "parentTaskId": 101 + }, + { + "id": 4, + "title": "Create CLI and MCP Tool Integration", + "description": "Implement the command-line interface and MCP tools for GitHub export functionality", + "details": "## Implementation Requirements\n\n### CLI Command Implementation\n```javascript\n// In scripts/modules/commands.js\nprogram\n .command('github-export')\n .description('Export Task Master task to GitHub issue with bidirectional linking')\n .requiredOption('-i, --id <taskId>', 'Task ID to export')\n .requiredOption('-r, --repo <owner/repo>', 'Target GitHub repository (owner/repo format)')\n .option('-t, --token <token>', 'GitHub Personal Access Token (or use GITHUB_TOKEN env var)')\n .option('--title <title>', 'Override the GitHub issue title')\n .option('--labels <labels>', 'Comma-separated list of GitHub labels to add')\n .option('--assignees <assignees>', 'Comma-separated list of GitHub usernames to assign')\n .option('--milestone <milestone>', 'GitHub milestone number or title')\n .option('--template <template>', 'Issue template to use (bug, feature, epic, default)')\n .option('--include-subtasks', 'Include subtasks as checklist items in the issue')\n .option('--separate-subtasks', 'Create separate GitHub issues for each subtask')\n .option('--dry-run', 'Preview the issue content without actually creating it')\n .option('--force', 'Overwrite existing GitHub link if task is already linked')\n .option('--no-link-back', 'Do not add Task Master reference to the GitHub issue')\n .option('--sync', 'Enable automatic synchronization between task and issue')\n .action(async (options) => {\n try {\n await handleGitHubExport(options);\n } catch (error) {\n console.error(chalk.red('GitHub export failed:'), error.message);\n process.exit(1);\n }\n });\n```\n\n### Core Export Handler\n```javascript\n// scripts/modules/github/github-export-handler.js\nasync function handleGitHubExport(options) {\n const {\n id: taskId,\n repo: repository,\n token,\n title: titleOverride,\n labels,\n assignees,\n milestone,\n template = 'default',\n includeSubtasks,\n separateSubtasks,\n dryRun,\n force,\n linkBack = true,\n sync = false\n } = options;\n\n // Validate inputs\n await validateExportOptions(options);\n \n // Get task details\n const task = await getTask(taskId);\n if (!task) {\n throw new Error(`Task ${taskId} not found`);\n }\n \n // Check for existing GitHub link\n if (task.metadata?.githubIssue && !force) {\n const existingUrl = task.metadata.githubIssue.url;\n console.log(chalk.yellow(`Task ${taskId} is already linked to GitHub issue: ${existingUrl}`));\n console.log(chalk.gray('Use --force to overwrite the existing link'));\n return;\n }\n \n // Initialize GitHub service\n const githubToken = token || process.env.GITHUB_TOKEN;\n if (!githubToken) {\n throw new Error('GitHub token required. Use --token flag or set GITHUB_TOKEN environment variable');\n }\n \n const githubService = new GitHubExportService(githubToken);\n const formatter = new TaskToGitHubFormatter();\n const linkManager = new GitHubLinkManager(githubService);\n \n // Format task content\n const exportOptions = {\n titleOverride,\n labels: labels ? labels.split(',').map(l => l.trim()) : [],\n assignees: assignees ? assignees.split(',').map(a => a.trim()) : [],\n milestone,\n template,\n includeSubtasks,\n linkBack\n };\n \n const issueData = formatter.formatTaskAsIssue(task, exportOptions);\n \n // Dry run - just show what would be created\n if (dryRun) {\n console.log(chalk.cyan('\\\\n=== DRY RUN - GitHub Issue Preview ===\\\\n'));\n console.log(chalk.bold('Title:'), issueData.title);\n console.log(chalk.bold('\\\\nLabels:'), issueData.labels.join(', ') || 'None');\n console.log(chalk.bold('\\\\nAssignees:'), issueData.assignees.join(', ') || 'None');\n console.log(chalk.bold('\\\\nBody:'));\n console.log(issueData.body);\n console.log(chalk.cyan('\\\\n=== End Preview ===\\\\n'));\n return;\n }\n \n // Show progress\n console.log(chalk.blue(`Exporting task ${taskId} to GitHub repository ${repository}...`));\n \n // Export to GitHub\n const result = await githubService.exportTask(task, repository, exportOptions);\n \n if (result.success) {\n console.log(chalk.green(`✅ Successfully exported task ${taskId} to GitHub!`));\n console.log(chalk.cyan(`GitHub Issue: ${result.issueUrl}`));\n \n // Add bidirectional link\n await linkManager.addGitHubLinkToTask(taskId, result.issueUrl, result.issue.number, repository);\n \n if (linkBack) {\n await linkManager.updateGitHubIssueWithTaskReference(result.issueUrl, taskId, getProjectName());\n }\n \n if (sync) {\n await linkManager.enableSync(taskId);\n console.log(chalk.blue('🔄 Synchronization enabled for this task'));\n }\n \n // Handle subtasks if requested\n if (separateSubtasks && task.subtasks && task.subtasks.length > 0) {\n console.log(chalk.blue('\\\\nExporting subtasks as separate issues...'));\n await exportSubtasksAsSeparateIssues(task.subtasks, repository, githubService, linkManager);\n }\n \n } else {\n throw new Error(result.error || 'Export failed');\n }\n}\n```\n\n### MCP Tool Implementation\n```javascript\n// mcp-server/src/tools/github-export.js\nimport { githubExportDirect } from '../core/direct-functions/github-export-direct.js';\nimport { handleApiResult, withNormalizedProjectRoot } from './utils.js';\n\nexport function registerGitHubExportTool(server) {\n server.addTool({\n name: \"github_export_task\",\n description: \"Export a Task Master task to GitHub issue with bidirectional linking\",\n parameters: {\n type: \"object\",\n properties: {\n taskId: {\n type: \"string\",\n description: \"Task ID to export (required)\"\n },\n repository: {\n type: \"string\", \n description: \"GitHub repository in owner/repo format (required)\"\n },\n token: {\n type: \"string\",\n description: \"GitHub Personal Access Token (optional if GITHUB_TOKEN env var is set)\"\n },\n options: {\n type: \"object\",\n properties: {\n title: {\n type: \"string\",\n description: \"Override the GitHub issue title\"\n },\n labels: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"GitHub labels to add to the issue\"\n },\n assignees: {\n type: \"array\", \n items: { type: \"string\" },\n description: \"GitHub usernames to assign to the issue\"\n },\n milestone: {\n type: \"string\",\n description: \"GitHub milestone number or title\"\n },\n template: {\n type: \"string\",\n enum: [\"default\", \"bug\", \"feature\", \"epic\"],\n description: \"Issue template to use\"\n },\n includeSubtasks: {\n type: \"boolean\",\n description: \"Include subtasks as checklist items\"\n },\n separateSubtasks: {\n type: \"boolean\", \n description: \"Create separate issues for subtasks\"\n },\n dryRun: {\n type: \"boolean\",\n description: \"Preview without creating the issue\"\n },\n force: {\n type: \"boolean\",\n description: \"Overwrite existing GitHub link\"\n },\n linkBack: {\n type: \"boolean\",\n description: \"Add Task Master reference to GitHub issue\"\n },\n enableSync: {\n type: \"boolean\",\n description: \"Enable automatic synchronization\"\n }\n }\n },\n projectRoot: {\n type: \"string\",\n description: \"Project root directory path\"\n }\n },\n required: [\"taskId\", \"repository\"]\n },\n execute: withNormalizedProjectRoot(async (args, { log, session }) => {\n try {\n const result = await githubExportDirect(args, log, { session });\n return handleApiResult(result, log);\n } catch (error) {\n log(`GitHub export error: ${error.message}`);\n return {\n success: false,\n error: error.message\n };\n }\n })\n });\n}\n```\n\n### Direct Function Implementation\n```javascript\n// mcp-server/src/core/direct-functions/github-export-direct.js\nimport { handleGitHubExport } from '../../../../scripts/modules/github/github-export-handler.js';\nimport { createLogWrapper } from '../../tools/utils.js';\n\nexport async function githubExportDirect(args, log, context = {}) {\n const { session } = context;\n const mcpLog = createLogWrapper(log);\n \n try {\n // Prepare options for the core handler\n const options = {\n id: args.taskId,\n repo: args.repository,\n token: args.token,\n ...args.options,\n projectRoot: args.projectRoot\n };\n \n // Call the core export handler\n const result = await handleGitHubExport(options, {\n session,\n mcpLog,\n outputFormat: 'json' // Request JSON output for MCP\n });\n \n return {\n success: true,\n data: {\n taskId: args.taskId,\n repository: args.repository,\n issueUrl: result.issueUrl,\n issueNumber: result.issue.number,\n exportedAt: new Date().toISOString(),\n message: `Successfully exported task ${args.taskId} to GitHub issue #${result.issue.number}`\n }\n };\n \n } catch (error) {\n mcpLog(`GitHub export failed: ${error.message}`);\n return {\n success: false,\n error: error.message\n };\n }\n}\n```\n\n### Validation Functions\n```javascript\n// scripts/modules/github/validation.js\nasync function validateExportOptions(options) {\n const { id: taskId, repo: repository, token } = options;\n \n // Validate task ID\n if (!taskId || !/^\\\\d+(\\\\.\\\\d+)*$/.test(taskId)) {\n throw new Error('Invalid task ID format');\n }\n \n // Validate repository format\n if (!repository || !/^[a-zA-Z0-9._-]+\\\\/[a-zA-Z0-9._-]+$/.test(repository)) {\n throw new Error('Repository must be in owner/repo format');\n }\n \n // Validate GitHub token\n const githubToken = token || process.env.GITHUB_TOKEN;\n if (!githubToken) {\n throw new Error('GitHub token is required');\n }\n \n if (!/^gh[ps]_[a-zA-Z0-9]{36,}$/.test(githubToken)) {\n console.warn(chalk.yellow('Warning: GitHub token format appears invalid'));\n }\n \n // Validate labels format\n if (options.labels) {\n const labels = options.labels.split(',').map(l => l.trim());\n for (const label of labels) {\n if (label.length > 50) {\n throw new Error(`Label \"${label}\" is too long (max 50 characters)`);\n }\n }\n }\n \n // Validate assignees format\n if (options.assignees) {\n const assignees = options.assignees.split(',').map(a => a.trim());\n for (const assignee of assignees) {\n if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(assignee)) {\n throw new Error(`Invalid GitHub username: ${assignee}`);\n }\n }\n }\n}\n```\n\n### Help Integration\n```javascript\n// Add to help system\nconst githubExportHelp = {\n command: 'github-export',\n description: 'Export Task Master task to GitHub issue',\n usage: 'task-master github-export --id=<taskId> --repo=<owner/repo> [options]',\n examples: [\n {\n command: 'task-master github-export --id=42 --repo=myorg/myproject',\n description: 'Export task 42 to GitHub repository'\n },\n {\n command: 'task-master github-export --id=42 --repo=myorg/myproject --labels=\"bug,urgent\" --assignees=\"john,jane\"',\n description: 'Export with custom labels and assignees'\n },\n {\n command: 'task-master github-export --id=42 --repo=myorg/myproject --dry-run',\n description: 'Preview the GitHub issue without creating it'\n },\n {\n command: 'task-master github-export --id=42 --repo=myorg/myproject --template=bug --sync',\n description: 'Export using bug template with sync enabled'\n }\n ],\n options: [\n { flag: '--id <taskId>', description: 'Task ID to export (required)' },\n { flag: '--repo <owner/repo>', description: 'GitHub repository (required)' },\n { flag: '--token <token>', description: 'GitHub Personal Access Token' },\n { flag: '--title <title>', description: 'Override issue title' },\n { flag: '--labels <labels>', description: 'Comma-separated labels' },\n { flag: '--assignees <users>', description: 'Comma-separated assignees' },\n { flag: '--milestone <milestone>', description: 'GitHub milestone' },\n { flag: '--template <template>', description: 'Issue template (bug, feature, epic)' },\n { flag: '--include-subtasks', description: 'Include subtasks as checklist' },\n { flag: '--separate-subtasks', description: 'Create separate issues for subtasks' },\n { flag: '--dry-run', description: 'Preview without creating' },\n { flag: '--force', description: 'Overwrite existing GitHub link' },\n { flag: '--no-link-back', description: 'Skip Task Master reference in issue' },\n { flag: '--sync', description: 'Enable automatic synchronization' }\n ]\n};\n```\n\n### Testing Requirements\n- Unit tests for CLI option parsing and validation\n- Integration tests for MCP tool functionality\n- End-to-end tests with real GitHub repositories\n- Error handling tests for various failure scenarios\n- Dry-run functionality testing\n- Template system testing\n- Subtask export testing (both checklist and separate issues)\n- Authentication and authorization testing\n- Rate limiting and retry logic testing", + "status": "pending", + "dependencies": [ + 3 + ], + "parentTaskId": 101 + }, + { + "id": 5, + "title": "Create Comprehensive Testing Suite and Documentation", + "description": "Implement thorough testing for the GitHub export system and create comprehensive documentation", + "details": "## Implementation Requirements\n\n### Testing Strategy\n\n#### 1. Unit Tests\n```javascript\n// tests/unit/github-export.test.js\ndescribe('GitHub Export System', () => {\n describe('GitHubExportService', () => {\n test('should validate repository access', async () => {\n const service = new GitHubExportService('mock-token');\n const mockGitHub = jest.spyOn(service, 'validateRepositoryAccess');\n \n await service.exportTask(mockTask, 'owner', 'repo');\n expect(mockGitHub).toHaveBeenCalledWith('owner', 'repo');\n });\n \n test('should handle authentication errors', async () => {\n const service = new GitHubExportService('invalid-token');\n \n await expect(service.exportTask(mockTask, 'owner', 'repo'))\n .rejects.toThrow('Authentication failed');\n });\n \n test('should respect rate limits', async () => {\n const service = new GitHubExportService('valid-token');\n const rateLimiter = jest.spyOn(service.rateLimiter, 'removeTokens');\n \n await service.exportTask(mockTask, 'owner', 'repo');\n expect(rateLimiter).toHaveBeenCalled();\n });\n });\n \n describe('TaskToGitHubFormatter', () => {\n test('should format task title correctly', () => {\n const formatter = new TaskToGitHubFormatter();\n const task = { id: 42, title: 'Test Task', priority: 'high' };\n \n const result = formatter.formatTitle(task);\n expect(result).toBe('🔥 [Task 42] Test Task');\n });\n \n test('should truncate long titles', () => {\n const formatter = new TaskToGitHubFormatter();\n const longTitle = 'A'.repeat(300);\n const task = { id: 1, title: longTitle };\n \n const result = formatter.formatTitle(task);\n expect(result.length).toBeLessThanOrEqual(250);\n expect(result).toEndWith('...');\n });\n \n test('should format subtasks as checklist', () => {\n const formatter = new TaskToGitHubFormatter();\n const task = {\n id: 1,\n title: 'Parent Task',\n subtasks: [\n { title: 'Subtask 1', status: 'done' },\n { title: 'Subtask 2', status: 'pending' }\n ]\n };\n \n const result = formatter.formatBody(task);\n expect(result).toContain('- [x] **Subtask 1**');\n expect(result).toContain('- [ ] **Subtask 2**');\n });\n \n test('should generate appropriate labels', () => {\n const formatter = new TaskToGitHubFormatter();\n const task = { priority: 'high', complexityScore: 9 };\n \n const labels = formatter.formatLabels(task);\n expect(labels).toContain('task-master');\n expect(labels).toContain('priority:high');\n expect(labels).toContain('complexity:high');\n });\n });\n \n describe('GitHubLinkManager', () => {\n test('should add GitHub link to task metadata', async () => {\n const linkManager = new GitHubLinkManager(mockGitHubService);\n const taskId = '42';\n const issueUrl = 'https://github.com/owner/repo/issues/123';\n \n await linkManager.addGitHubLinkToTask(taskId, issueUrl, 123, 'owner/repo');\n \n const task = await getTask(taskId);\n expect(task.metadata.githubIssue).toBeDefined();\n expect(task.metadata.githubIssue.url).toBe(issueUrl);\n expect(task.metadata.githubIssue.number).toBe(123);\n });\n \n test('should validate GitHub links', async () => {\n const linkManager = new GitHubLinkManager(mockGitHubService);\n const linkInfo = {\n repository: 'owner/repo',\n number: 123,\n status: 'active'\n };\n \n mockGitHubService.getIssue.mockResolvedValue({ state: 'open' });\n \n const result = await linkManager.validateGitHubLink('42', linkInfo);\n expect(result.valid).toBe(true);\n expect(result.status).toBe('active');\n });\n });\n});\n```\n\n#### 2. Integration Tests\n```javascript\n// tests/integration/github-export-integration.test.js\ndescribe('GitHub Export Integration', () => {\n let testRepository;\n let githubToken;\n \n beforeAll(() => {\n githubToken = process.env.GITHUB_TEST_TOKEN;\n testRepository = process.env.GITHUB_TEST_REPO || 'taskmaster-test/test-repo';\n \n if (!githubToken) {\n throw new Error('GITHUB_TEST_TOKEN environment variable required for integration tests');\n }\n });\n \n test('should export task to real GitHub repository', async () => {\n const task = createTestTask();\n const service = new GitHubExportService(githubToken);\n \n const result = await service.exportTask(task, testRepository, {\n labels: ['test', 'automated'],\n template: 'default'\n });\n \n expect(result.success).toBe(true);\n expect(result.issueUrl).toMatch(/https:\\\\/\\\\/github\\\\.com\\\\/.+\\\\/issues\\\\/\\\\d+/);\n \n // Cleanup: Close the test issue\n await service.updateIssue(testRepository, result.issue.number, { state: 'closed' });\n });\n \n test('should handle repository permission errors', async () => {\n const task = createTestTask();\n const service = new GitHubExportService(githubToken);\n \n await expect(service.exportTask(task, 'private/inaccessible-repo'))\n .rejects.toThrow(/permission|access/i);\n });\n \n test('should respect GitHub API rate limits', async () => {\n const service = new GitHubExportService(githubToken);\n const tasks = Array.from({ length: 10 }, () => createTestTask());\n \n const startTime = Date.now();\n \n for (const task of tasks) {\n await service.exportTask(task, testRepository);\n }\n \n const endTime = Date.now();\n const duration = endTime - startTime;\n \n // Should take some time due to rate limiting\n expect(duration).toBeGreaterThan(1000);\n });\n});\n```\n\n#### 3. CLI Tests\n```javascript\n// tests/cli/github-export-cli.test.js\ndescribe('GitHub Export CLI', () => {\n test('should validate required options', async () => {\n const result = await runCLI(['github-export']);\n \n expect(result.exitCode).toBe(1);\n expect(result.stderr).toContain('required option');\n });\n \n test('should perform dry run correctly', async () => {\n const result = await runCLI([\n 'github-export',\n '--id=42',\n '--repo=owner/repo',\n '--dry-run'\n ]);\n \n expect(result.exitCode).toBe(0);\n expect(result.stdout).toContain('DRY RUN');\n expect(result.stdout).toContain('GitHub Issue Preview');\n });\n \n test('should handle invalid task ID', async () => {\n const result = await runCLI([\n 'github-export',\n '--id=invalid',\n '--repo=owner/repo'\n ]);\n \n expect(result.exitCode).toBe(1);\n expect(result.stderr).toContain('Invalid task ID');\n });\n \n test('should validate repository format', async () => {\n const result = await runCLI([\n 'github-export',\n '--id=42',\n '--repo=invalid-format'\n ]);\n \n expect(result.exitCode).toBe(1);\n expect(result.stderr).toContain('owner/repo format');\n });\n});\n```\n\n#### 4. MCP Tool Tests\n```javascript\n// tests/mcp/github-export-mcp.test.js\ndescribe('GitHub Export MCP Tool', () => {\n test('should export task via MCP', async () => {\n const args = {\n taskId: '42',\n repository: 'owner/repo',\n token: 'test-token',\n options: {\n labels: ['test'],\n dryRun: true\n }\n };\n \n const result = await githubExportDirect(args, mockLog, { session: mockSession });\n \n expect(result.success).toBe(true);\n expect(result.data.taskId).toBe('42');\n });\n \n test('should handle MCP tool errors', async () => {\n const args = {\n taskId: 'invalid',\n repository: 'owner/repo'\n };\n \n const result = await githubExportDirect(args, mockLog, { session: mockSession });\n \n expect(result.success).toBe(false);\n expect(result.error).toBeDefined();\n });\n});\n```\n\n### Mock Data and Utilities\n```javascript\n// tests/utils/github-mocks.js\nexport function createTestTask() {\n return {\n id: Math.floor(Math.random() * 1000),\n title: 'Test Task',\n description: 'This is a test task for GitHub export',\n details: 'Implementation details for the test task',\n priority: 'medium',\n status: 'pending',\n subtasks: [\n { title: 'Test Subtask 1', status: 'done' },\n { title: 'Test Subtask 2', status: 'pending' }\n ]\n };\n}\n\nexport function mockGitHubAPI() {\n return {\n getIssue: jest.fn(),\n createIssue: jest.fn(),\n updateIssue: jest.fn(),\n getRepository: jest.fn()\n };\n}\n\nexport function createMockGitHubResponse(issueNumber = 123) {\n return {\n id: issueNumber,\n number: issueNumber,\n title: 'Test Issue',\n body: 'Test issue body',\n state: 'open',\n html_url: `https://github.com/owner/repo/issues/${issueNumber}`,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString()\n };\n}\n```\n\n### Documentation\n\n#### 1. User Guide\n```markdown\n# GitHub Export Feature\n\n## Overview\nThe GitHub Export feature allows you to create GitHub issues directly from your Task Master tasks, maintaining bidirectional links between tasks and issues.\n\n## Setup\n\n### 1. GitHub Token\nCreate a GitHub Personal Access Token with the following permissions:\n- `repo` (for private repositories)\n- `public_repo` (for public repositories)\n\nSet the token as an environment variable:\n```bash\nexport GITHUB_TOKEN=your_token_here\n```\n\n### 2. Basic Usage\n```bash\n# Export a task to GitHub\ntask-master github-export --id=42 --repo=myorg/myproject\n\n# Export with custom labels and assignees\ntask-master github-export --id=42 --repo=myorg/myproject \\\\\n --labels=\"bug,urgent\" --assignees=\"john,jane\"\n\n# Preview before creating\ntask-master github-export --id=42 --repo=myorg/myproject --dry-run\n```\n\n## Advanced Features\n\n### Templates\nUse predefined templates for different issue types:\n```bash\n# Bug report template\ntask-master github-export --id=42 --repo=myorg/myproject --template=bug\n\n# Feature request template\ntask-master github-export --id=42 --repo=myorg/myproject --template=feature\n```\n\n### Subtask Handling\n```bash\n# Include subtasks as checklist items\ntask-master github-export --id=42 --repo=myorg/myproject --include-subtasks\n\n# Create separate issues for each subtask\ntask-master github-export --id=42 --repo=myorg/myproject --separate-subtasks\n```\n\n### Synchronization\n```bash\n# Enable automatic synchronization\ntask-master github-export --id=42 --repo=myorg/myproject --sync\n```\n\n## Troubleshooting\n\n### Common Issues\n1. **Authentication Error**: Verify your GitHub token has the correct permissions\n2. **Repository Not Found**: Ensure the repository exists and you have access\n3. **Rate Limit Exceeded**: Wait for the rate limit to reset or use a different token\n\n### Link Management\n```bash\n# Validate all GitHub links\ntask-master github-link --validate\n\n# Sync specific task with GitHub\ntask-master github-link --sync 42\n\n# Remove GitHub link from task\ntask-master github-link --remove 42\n```\n```\n\n#### 2. API Documentation\n```markdown\n# GitHub Export API Reference\n\n## MCP Tool: github_export_task\n\n### Parameters\n- `taskId` (string, required): Task ID to export\n- `repository` (string, required): GitHub repository in owner/repo format\n- `token` (string, optional): GitHub Personal Access Token\n- `options` (object, optional): Export configuration\n\n### Options Object\n- `title` (string): Override issue title\n- `labels` (array): GitHub labels to add\n- `assignees` (array): GitHub usernames to assign\n- `milestone` (string): GitHub milestone\n- `template` (string): Issue template (bug, feature, epic, default)\n- `includeSubtasks` (boolean): Include subtasks as checklist\n- `separateSubtasks` (boolean): Create separate issues for subtasks\n- `dryRun` (boolean): Preview without creating\n- `force` (boolean): Overwrite existing GitHub link\n- `linkBack` (boolean): Add Task Master reference to issue\n- `enableSync` (boolean): Enable automatic synchronization\n\n### Response\n```json\n{\n \"success\": true,\n \"data\": {\n \"taskId\": \"42\",\n \"repository\": \"owner/repo\",\n \"issueUrl\": \"https://github.com/owner/repo/issues/123\",\n \"issueNumber\": 123,\n \"exportedAt\": \"2024-01-15T10:30:00.000Z\",\n \"message\": \"Successfully exported task 42 to GitHub issue #123\"\n }\n}\n```\n```\n\n### Performance Testing\n```javascript\n// tests/performance/github-export-performance.test.js\ndescribe('GitHub Export Performance', () => {\n test('should export large task within time limit', async () => {\n const largeTask = createLargeTask(); // Task with many subtasks and long content\n const service = new GitHubExportService('test-token');\n \n const startTime = performance.now();\n await service.exportTask(largeTask, 'owner/repo');\n const endTime = performance.now();\n \n expect(endTime - startTime).toBeLessThan(5000); // Should complete in under 5 seconds\n });\n \n test('should handle concurrent exports', async () => {\n const service = new GitHubExportService('test-token');\n const tasks = Array.from({ length: 5 }, () => createTestTask());\n \n const promises = tasks.map(task => service.exportTask(task, 'owner/repo'));\n const results = await Promise.all(promises);\n \n results.forEach(result => {\n expect(result.success).toBe(true);\n });\n });\n});\n```\n\n### Test Configuration\n```javascript\n// jest.config.js additions\nmodule.exports = {\n // ... existing config\n testEnvironment: 'node',\n setupFilesAfterEnv: ['<rootDir>/tests/setup/github-setup.js'],\n testMatch: [\n '**/tests/**/*.test.js',\n '**/tests/**/*.spec.js'\n ],\n collectCoverageFrom: [\n 'scripts/modules/github/**/*.js',\n 'mcp-server/src/tools/github-*.js',\n 'mcp-server/src/core/direct-functions/github-*.js'\n ],\n coverageThreshold: {\n global: {\n branches: 80,\n functions: 80,\n lines: 80,\n statements: 80\n }\n }\n};\n```\n\n### Continuous Integration\n```yaml\n# .github/workflows/github-export-tests.yml\nname: GitHub Export Tests\n\non: [push, pull_request]\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v3\n - uses: actions/setup-node@v3\n with:\n node-version: '18'\n - run: npm ci\n - run: npm run test:github-export\n env:\n GITHUB_TEST_TOKEN: ${{ secrets.GITHUB_TEST_TOKEN }}\n GITHUB_TEST_REPO: ${{ secrets.GITHUB_TEST_REPO }}\n```", + "status": "pending", + "dependencies": [ + 4 + ], + "parentTaskId": 101 } ] } diff --git a/package.json b/package.json index edbfb251..fd6b5fc5 100644 --- a/package.json +++ b/package.json @@ -54,14 +54,16 @@ "ai": "^4.3.10", "boxen": "^8.0.1", "chalk": "^5.4.1", + "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "commander": "^11.1.0", "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.21.2", - "fastmcp": "^1.20.5", + "fastmcp": "^2.2.2", "figlet": "^1.8.0", "fuse.js": "^7.1.0", + "gpt-tokens": "^1.3.14", "gradient-string": "^3.0.0", "helmet": "^8.1.0", "inquirer": "^12.5.0", @@ -70,6 +72,7 @@ "ollama-ai-provider": "^1.2.0", "openai": "^4.89.0", "ora": "^8.2.0", + "task-master-ai": "^0.15.0", "uuid": "^11.1.0", "zod": "^3.23.8" }, diff --git a/scripts/modules/commands.js b/scripts/modules/commands.js index b83b31e7..a9c75901 100644 --- a/scripts/modules/commands.js +++ b/scripts/modules/commands.js @@ -1444,7 +1444,7 @@ function registerCommands(programInstance) { 'Additional custom context to include in the research prompt' ) .option( - '-t, --tree', + '--project-tree', 'Include project file tree structure in the research context' ) .option( @@ -1578,7 +1578,7 @@ function registerCommands(programInstance) { taskIds: taskIds, filePaths: filePaths, customContext: options.context ? options.context.trim() : null, - includeProjectTree: !!options.tree, + includeProjectTree: !!options.projectTree, saveTarget: options.save ? options.save.trim() : null, detailLevel: options.detail ? options.detail.toLowerCase() : 'medium', tasksPath: tasksPath, diff --git a/scripts/modules/task-manager.js b/scripts/modules/task-manager.js index f2b4d43e..e8af0023 100644 --- a/scripts/modules/task-manager.js +++ b/scripts/modules/task-manager.js @@ -50,7 +50,7 @@ export { taskExists, isTaskDependentOn, moveTask, - performResearch, readComplexityReport, - migrateProject + migrateProject, + performResearch }; diff --git a/scripts/modules/ui.js b/scripts/modules/ui.js index bb37c6f3..115279f8 100644 --- a/scripts/modules/ui.js +++ b/scripts/modules/ui.js @@ -924,6 +924,11 @@ function displayHelp() { name: 'expand --all', args: '[--force] [--research]', desc: 'Expand all pending tasks with subtasks' + }, + { + name: 'research', + args: '"<prompt>" [-i=<task_ids>] [-f=<file_paths>] [-c="<context>"] [--project-tree] [-s=<save_file>] [-d=<detail_level>]', + desc: 'Perform AI-powered research queries with project context' } ] }, diff --git a/scripts/modules/utils/fuzzyTaskSearch.js b/scripts/modules/utils/fuzzyTaskSearch.js index c8fcac2f..a533d35e 100644 --- a/scripts/modules/utils/fuzzyTaskSearch.js +++ b/scripts/modules/utils/fuzzyTaskSearch.js @@ -276,11 +276,7 @@ export class FuzzyTaskSearch { * @returns {Array<string>} Array of task ID strings */ getTaskIds(searchResults) { - return searchResults.results.map((task) => { - // Use searchableId if available (for flattened tasks with subtasks) - // Otherwise fall back to regular id - return task.searchableId || task.id.toString(); - }); + return searchResults.results.map((task) => task.id.toString()); } /**