Split monolithic task-master-core.js into separate function files within the mcp-server/src/core/direct-functions/ directory. This change: - Creates individual files for each direct function implementation - Moves findTasksJsonPath to a dedicated utils/path-utils.js file - Converts task-master-core.js to be a simple import/export hub - Improves maintainability and organization of the codebase - Reduces potential merge conflicts when multiple developers contribute - Follows standard module separation patterns Each function is now in its own self-contained file with clear imports and focused responsibility, while maintaining the same API endpoints.
209 lines
16 KiB
Plaintext
209 lines
16 KiB
Plaintext
---
|
|
description: Describes the high-level architecture of the Task Master CLI application.
|
|
globs: scripts/modules/*.js
|
|
alwaysApply: false
|
|
---
|
|
|
|
# Application Architecture Overview
|
|
|
|
- **Modular Structure**: The Task Master CLI is built using a modular architecture, with distinct modules responsible for different aspects of the application. This promotes separation of concerns, maintainability, and testability.
|
|
|
|
- **Main Modules and Responsibilities**:
|
|
|
|
- **[`commands.js`](mdc:scripts/modules/commands.js): Command Handling**
|
|
- **Purpose**: Defines and registers all CLI commands using Commander.js.
|
|
- **Responsibilities** (See also: [`commands.mdc`](mdc:.cursor/rules/commands.mdc)):
|
|
- Parses command-line arguments and options.
|
|
- Invokes appropriate functions from other modules to execute commands.
|
|
- Handles user input and output related to command execution.
|
|
- Implements input validation and error handling for CLI commands.
|
|
- **Key Components**:
|
|
- `programInstance` (Commander.js `Command` instance): Manages command definitions.
|
|
- `registerCommands(programInstance)`: Function to register all application commands.
|
|
- Command action handlers: Functions executed when a specific command is invoked.
|
|
|
|
- **[`task-manager.js`](mdc:scripts/modules/task-manager.js): Task Data Management**
|
|
- **Purpose**: Manages task data, including loading, saving, creating, updating, deleting, and querying tasks.
|
|
- **Responsibilities**:
|
|
- Reads and writes task data to `tasks.json` file.
|
|
- Implements functions for task CRUD operations (Create, Read, Update, Delete).
|
|
- Handles task parsing from PRD documents using AI.
|
|
- Manages task expansion and subtask generation.
|
|
- Updates task statuses and properties.
|
|
- Implements task listing and display logic.
|
|
- Performs task complexity analysis using AI.
|
|
- **Key Functions**:
|
|
- `readTasks(tasksPath)` / `writeTasks(tasksPath, tasksData)`: Load and save task data.
|
|
- `parsePRD(prdFilePath, outputPath, numTasks)`: Parses PRD document to create tasks.
|
|
- `expandTask(taskId, numSubtasks, useResearch, prompt, force)`: Expands a task into subtasks.
|
|
- `setTaskStatus(tasksPath, taskIdInput, newStatus)`: Updates task status.
|
|
- `listTasks(tasksPath, statusFilter, withSubtasks)`: Lists tasks with filtering and subtask display options.
|
|
- `analyzeComplexity(tasksPath, reportPath, useResearch, thresholdScore)`: Analyzes task complexity.
|
|
|
|
- **[`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js): Dependency Management**
|
|
- **Purpose**: Manages task dependencies, including adding, removing, validating, and fixing dependency relationships.
|
|
- **Responsibilities**:
|
|
- Adds and removes task dependencies.
|
|
- Validates dependency relationships to prevent circular dependencies and invalid references.
|
|
- Fixes invalid dependencies by removing non-existent or self-referential dependencies.
|
|
- Provides functions to check for circular dependencies.
|
|
- **Key Functions**:
|
|
- `addDependency(tasksPath, taskId, dependencyId)`: Adds a dependency between tasks.
|
|
- `removeDependency(tasksPath, taskId, dependencyId)`: Removes a dependency.
|
|
- `validateDependencies(tasksPath)`: Validates task dependencies.
|
|
- `fixDependencies(tasksPath)`: Fixes invalid task dependencies.
|
|
- `isCircularDependency(tasks, taskId, dependencyChain)`: Detects circular dependencies.
|
|
|
|
- **[`ui.js`](mdc:scripts/modules/ui.js): User Interface Components**
|
|
- **Purpose**: Handles all user interface elements, including displaying information, formatting output, and providing user feedback.
|
|
- **Responsibilities**:
|
|
- Displays task lists, task details, and command outputs in a formatted way.
|
|
- Uses `chalk` for colored output and `boxen` for boxed messages.
|
|
- Implements table display using `cli-table3`.
|
|
- Shows loading indicators using `ora`.
|
|
- Provides helper functions for status formatting, dependency display, and progress reporting.
|
|
- Suggests next actions to the user after command execution.
|
|
- **Key Functions**:
|
|
- `displayTaskList(tasks, statusFilter, withSubtasks)`: Displays a list of tasks in a table.
|
|
- `displayTaskDetails(task)`: Displays detailed information for a single task.
|
|
- `displayComplexityReport(reportPath)`: Displays the task complexity report.
|
|
- `startLoadingIndicator(message)` / `stopLoadingIndicator(indicator)`: Manages loading indicators.
|
|
- `getStatusWithColor(status)`: Returns status string with color formatting.
|
|
- `formatDependenciesWithStatus(dependencies, allTasks, inTable)`: Formats dependency list with status indicators.
|
|
|
|
- **[`ai-services.js`](mdc:scripts/modules/ai-services.js) (Conceptual): AI Integration**
|
|
- **Purpose**: Abstracts interactions with AI models (like Anthropic Claude and Perplexity AI) for various features. *Note: This module might be implicitly implemented within `task-manager.js` and `utils.js` or could be explicitly created for better organization as the project evolves.*
|
|
- **Responsibilities**:
|
|
- Handles API calls to AI services.
|
|
- Manages prompts and parameters for AI requests.
|
|
- Parses AI responses and extracts relevant information.
|
|
- Implements logic for task complexity analysis, task expansion, and PRD parsing using AI.
|
|
- **Potential Functions**:
|
|
- `getAIResponse(prompt, model, maxTokens, temperature)`: Generic function to interact with AI model.
|
|
- `analyzeTaskComplexityWithAI(taskDescription)`: Sends task description to AI for complexity analysis.
|
|
- `expandTaskWithAI(taskDescription, numSubtasks, researchContext)`: Generates subtasks using AI.
|
|
- `parsePRDWithAI(prdContent)`: Extracts tasks from PRD content using AI.
|
|
|
|
- **[`utils.js`](mdc:scripts/modules/utils.js): Utility Functions and Configuration**
|
|
- **Purpose**: Provides reusable utility functions and global configuration settings used across the application.
|
|
- **Responsibilities** (See also: [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc)):
|
|
- Manages global configuration settings loaded from environment variables and defaults.
|
|
- Implements logging utility with different log levels and output formatting.
|
|
- Provides file system operation utilities (read/write JSON files).
|
|
- Includes string manipulation utilities (e.g., `truncate`, `sanitizePrompt`).
|
|
- Offers task-specific utility functions (e.g., `formatTaskId`, `findTaskById`, `taskExists`).
|
|
- Implements graph algorithms like cycle detection for dependency management.
|
|
- **Key Components**:
|
|
- `CONFIG`: Global configuration object.
|
|
- `log(level, ...args)`: Logging function.
|
|
- `readJSON(filepath)` / `writeJSON(filepath, data)`: File I/O utilities for JSON files.
|
|
- `truncate(text, maxLength)`: String truncation utility.
|
|
- `formatTaskId(id)` / `findTaskById(tasks, taskId)`: Task ID and search utilities.
|
|
- `findCycles(subtaskId, dependencyMap)`: Cycle detection algorithm.
|
|
|
|
- **[`mcp-server/`](mdc:mcp-server/): MCP Server Integration**
|
|
- **Purpose**: Provides an MCP (Model Context Protocol) interface for Task Master, allowing integration with external tools like Cursor. Uses FastMCP framework.
|
|
- **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):
|
|
- Registers Task Master functionalities as tools consumable via MCP.
|
|
- Handles MCP requests via tool `execute` methods defined in `mcp-server/src/tools/*.js`.
|
|
- Tool `execute` methods call corresponding direct function wrappers.
|
|
- Direct function wrappers (`*Direct` functions) contain the main logic, including path resolution and optional caching.
|
|
- Tool `execute` methods use `handleApiResult` from [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js) to process the result from the direct function and format the final MCP response.
|
|
- Uses CLI execution via `executeTaskMasterCommand` as a fallback only when necessary.
|
|
- **Implements Caching**: Utilizes a caching layer (`ContextManager` with `lru-cache`). Caching logic is invoked *within* the direct function wrappers (located in [`mcp-server/src/core/direct-functions/`](mdc:mcp-server/src/core/direct-functions/)) using the `getCachedOrExecute` utility for performance-sensitive read operations (e.g., `listTasks`).
|
|
- Standardizes response formatting and data filtering using utilities in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
|
- **Key Components**:
|
|
- `mcp-server/src/server.js`: Main server setup and initialization.
|
|
- `mcp-server/src/tools/`: Directory containing individual tool definitions. Each tool's `execute` method orchestrates the call to core logic and handles the response.
|
|
- `mcp-server/src/core/utils/`: Directory containing utility functions like `path-utils.js` with `findTasksJsonPath`.
|
|
- `mcp-server/src/core/direct-functions/`: Directory containing individual files for each direct function wrapper (`*Direct`). These files contain the primary logic, including path resolution, core function calls, and caching.
|
|
- [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js): Acts as an import/export hub, collecting and exporting direct functions from the `direct-functions` directory and utility functions.
|
|
- `mcp-server/src/tools/utils.js`: Provides utilities like `handleApiResult`, `processMCPResponseData`, and `getCachedOrExecute`.
|
|
|
|
- **Data Flow and Module Dependencies**:
|
|
|
|
- **Commands Initiate Actions**: User commands entered via the CLI (handled by [`commands.js`](mdc:scripts/modules/commands.js)) are the entry points for most operations.
|
|
- **Command Handlers Delegate to Managers**: Command handlers in [`commands.js`](mdc:scripts/modules/commands.js) call functions in [`task-manager.js`](mdc:scripts/modules/task-manager.js) and [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js) to perform core task and dependency management logic.
|
|
- **UI for Presentation**: [`ui.js`](mdc:scripts/modules/ui.js) is used by command handlers and task/dependency managers to display information to the user. UI functions primarily consume data and format it for output, without modifying core application state.
|
|
- **Utilities for Common Tasks**: [`utils.js`](mdc:scripts/modules/utils.js) provides helper functions used by all other modules for configuration, logging, file operations, and common data manipulations.
|
|
- **AI Services Integration**: AI functionalities (complexity analysis, task expansion, PRD parsing) are invoked from [`task-manager.js`](mdc:scripts/modules/task-manager.js) and potentially [`commands.js`](mdc:scripts/modules/commands.js), likely using functions that would reside in a dedicated `ai-services.js` module or be integrated within `utils.js` or `task-manager.js`.
|
|
- **MCP Server Interaction**: External tools interact with the `mcp-server`, which then calls direct function wrappers (located in `mcp-server/src/core/direct-functions/` and exported via `task-master-core.js`) or falls back to `executeTaskMasterCommand`. Responses are formatted by `mcp-server/src/tools/utils.js`. See [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc) for details.
|
|
|
|
- **Testing Architecture**:
|
|
|
|
- **Test Organization Structure** (See also: [`tests.mdc`](mdc:.cursor/rules/tests.mdc)):
|
|
- **Unit Tests**: Located in `tests/unit/`, reflect the module structure with one test file per module
|
|
- **Integration Tests**: Located in `tests/integration/`, test interactions between modules
|
|
- **End-to-End Tests**: Located in `tests/e2e/`, test complete workflows from a user perspective
|
|
- **Test Fixtures**: Located in `tests/fixtures/`, provide reusable test data
|
|
|
|
- **Module Design for Testability**:
|
|
- **Explicit Dependencies**: Functions accept their dependencies as parameters rather than using globals
|
|
- **Functional Style**: Pure functions with minimal side effects make testing deterministic
|
|
- **Separate Logic from I/O**: Core business logic is separated from file system operations
|
|
- **Clear Module Interfaces**: Each module has well-defined exports that can be mocked in tests
|
|
- **Callback Isolation**: Callbacks are defined as separate functions for easier testing
|
|
- **Stateless Design**: Modules avoid maintaining internal state where possible
|
|
|
|
- **Mock Integration Patterns**:
|
|
- **External Libraries**: Libraries like `fs`, `commander`, and `@anthropic-ai/sdk` are mocked at module level
|
|
- **Internal Modules**: Application modules are mocked with appropriate spy functions
|
|
- **Testing Function Callbacks**: Callbacks are extracted from mock call arguments and tested in isolation
|
|
- **UI Elements**: Output functions from `ui.js` are mocked to verify display calls
|
|
|
|
- **Testing Flow**:
|
|
- Module dependencies are mocked (following Jest's hoisting behavior)
|
|
- Test modules are imported after mocks are established
|
|
- Spy functions are set up on module methods
|
|
- Tests call the functions under test and verify behavior
|
|
- Mocks are reset between test cases to maintain isolation
|
|
|
|
- **Benefits of this Architecture**:
|
|
|
|
- **Maintainability**: Modules are self-contained and focused, making it easier to understand, modify, and debug specific features.
|
|
- **Testability**: Each module can be tested in isolation (unit testing), and interactions between modules can be tested (integration testing).
|
|
- **Mocking Support**: The clear dependency boundaries make mocking straightforward
|
|
- **Test Isolation**: Each component can be tested without affecting others
|
|
- **Callback Testing**: Function callbacks can be extracted and tested independently
|
|
- **Reusability**: Utility functions and UI components can be reused across different parts of the application.
|
|
- **Scalability**: New features can be added as new modules or by extending existing ones without significantly impacting other parts of the application.
|
|
- **Clarity**: The modular structure provides a clear separation of concerns, making the codebase easier to navigate and understand for developers.
|
|
|
|
This architectural overview should help AI models understand the structure and organization of the Task Master CLI codebase, enabling them to more effectively assist with code generation, modification, and understanding.
|
|
|
|
## Implementing MCP Support for a Command
|
|
|
|
Follow these steps to add MCP support for an existing Task Master command (see [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for more detail):
|
|
|
|
1. **Ensure Core Logic Exists**: Verify the core functionality is implemented and exported from the relevant module in `scripts/modules/`.
|
|
|
|
2. **Create Direct Function File in `mcp-server/src/core/direct-functions/`**:
|
|
- Create a new file (e.g., `your-command.js`) in the `direct-functions` directory.
|
|
- Import necessary core functions from Task Master modules (e.g., `../../../../scripts/modules/task-manager.js`).
|
|
- Import utilities: `findTasksJsonPath` from `../utils/path-utils.js` and `getCachedOrExecute` from `../../tools/utils.js` if needed.
|
|
- Implement `async function yourCommandDirect(args, log)`:
|
|
- Parse `args` and determine necessary inputs (e.g., `tasksPath` via `findTasksJsonPath`).
|
|
- **If Caching**:
|
|
- Generate a unique `cacheKey` based on arguments defining the operation.
|
|
- Define an `async` function `coreActionFn` containing the call to the core logic.
|
|
- Call `const result = await getCachedOrExecute({ cacheKey, actionFn: coreActionFn, log });`.
|
|
- **If Not Caching**:
|
|
- Directly call the core logic function within a try/catch block.
|
|
- Format the return as `{ success: true/false, data/error, fromCache: boolean }`.
|
|
- Export the wrapper function.
|
|
|
|
3. **Update `task-master-core.js` with Import/Export**:
|
|
- Import your direct function: `import { yourCommandDirect } from './direct-functions/your-command.js';`
|
|
- Re-export it in the exports section.
|
|
- Add it to the `directFunctions` map: `yourCommand: yourCommandDirect`.
|
|
|
|
4. **Create MCP Tool (`mcp-server/src/tools/`)**:
|
|
- Create a new file (e.g., `your-command.js`).
|
|
- Import `z` for schema definition.
|
|
- Import `handleApiResult` from `./utils.js`.
|
|
- Import the `yourCommandDirect` wrapper function from `../core/task-master-core.js`.
|
|
- Implement `registerYourCommandTool(server)` following the standard pattern.
|
|
|
|
5. **Register Tool**: Import and call `registerYourCommandTool` in `mcp-server/src/tools/index.js`.
|
|
|
|
6. **Update `mcp.json`**: Add the new tool definition to the `tools` array in `.cursor/mcp.json`. |