refactor(mcp): Modularize direct functions in MCP server
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.
This commit is contained in:
5
.changeset/two-bats-smoke.md
Normal file
5
.changeset/two-bats-smoke.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"task-master-ai": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Split monolithic task-master-core.js into separate function files within
|
||||||
@@ -106,16 +106,18 @@ alwaysApply: false
|
|||||||
- **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):
|
- **Responsibilities** (See also: [`mcp.mdc`](mdc:.cursor/rules/mcp.mdc)):
|
||||||
- Registers Task Master functionalities as tools consumable via MCP.
|
- Registers Task Master functionalities as tools consumable via MCP.
|
||||||
- Handles MCP requests via tool `execute` methods defined in `mcp-server/src/tools/*.js`.
|
- Handles MCP requests via tool `execute` methods defined in `mcp-server/src/tools/*.js`.
|
||||||
- Tool `execute` methods call corresponding direct function wrappers in [`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js) for core logic execution.
|
- Tool `execute` methods call corresponding direct function wrappers.
|
||||||
- Direct function wrappers (`*Direct` functions) contain the main logic, including path resolution and optional caching.
|
- 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.
|
- 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.
|
- 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 ([`task-master-core.js`](mdc:mcp-server/src/core/task-master-core.js)) using the `getCachedOrExecute` utility for performance-sensitive read operations (e.g., `listTasks`).
|
- **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).
|
- Standardizes response formatting and data filtering using utilities in [`tools/utils.js`](mdc:mcp-server/src/tools/utils.js).
|
||||||
- **Key Components**:
|
- **Key Components**:
|
||||||
- `mcp-server/src/server.js`: Main server setup and initialization.
|
- `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/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/task-master-core.js`: Contains direct function wrappers (`*Direct`) that encapsulate core logic calls and caching.
|
- `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`.
|
- `mcp-server/src/tools/utils.js`: Provides utilities like `handleApiResult`, `processMCPResponseData`, and `getCachedOrExecute`.
|
||||||
|
|
||||||
- **Data Flow and Module Dependencies**:
|
- **Data Flow and Module Dependencies**:
|
||||||
@@ -125,7 +127,7 @@ alwaysApply: false
|
|||||||
- **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.
|
- **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.
|
- **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`.
|
- **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 in `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.
|
- **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**:
|
- **Testing Architecture**:
|
||||||
|
|
||||||
@@ -167,4 +169,41 @@ alwaysApply: false
|
|||||||
- **Scalability**: New features can be added as new modules or by extending existing ones without significantly impacting other 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.
|
- **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.
|
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`.
|
||||||
@@ -15,7 +15,7 @@ Changesets is used to manage package versioning and generate accurate `CHANGELOG
|
|||||||
- **Bug Fixes** (Fixes to existing functionality)
|
- **Bug Fixes** (Fixes to existing functionality)
|
||||||
- **Breaking Changes** (Changes that are not backward-compatible)
|
- **Breaking Changes** (Changes that are not backward-compatible)
|
||||||
- **Performance Improvements** (Enhancements to speed or resource usage)
|
- **Performance Improvements** (Enhancements to speed or resource usage)
|
||||||
- **Significant Refactoring** (Major code restructuring, even if external behavior is unchanged, as it might affect stability or maintainability)
|
- **Significant Refactoring** (Major code restructuring, even if external behavior is unchanged, as it might affect stability or maintainability) - *Such as reorganizing the MCP server's direct function implementations into separate files*
|
||||||
- **User-Facing Documentation Updates** (Changes to README, usage guides, public API docs)
|
- **User-Facing Documentation Updates** (Changes to README, usage guides, public API docs)
|
||||||
- **Dependency Updates** (Especially if they fix known issues or introduce significant changes)
|
- **Dependency Updates** (Especially if they fix known issues or introduce significant changes)
|
||||||
- **Build/Tooling Changes** (If they affect how consumers might build or interact with the package)
|
- **Build/Tooling Changes** (If they affect how consumers might build or interact with the package)
|
||||||
|
|||||||
@@ -361,4 +361,13 @@ alwaysApply: false
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Refer to [`utils.js`](mdc:scripts/modules/utils.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. Use [`commands.mdc`](mdc:.cursor/rules/commands.mdc) for CLI integration details.
|
Refer to [`utils.js`](mdc:scripts/modules/utils.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines. Use [`commands.mdc`](mdc:.cursor/rules/commands.mdc) for CLI integration details.
|
||||||
|
|
||||||
|
## MCP Server Utilities Structure
|
||||||
|
|
||||||
|
- **Core Utilities** (`mcp-server/src/core/utils/path-utils.js`):
|
||||||
|
- Contains path-related utilities like `findTasksJsonPath` that are used by direct function implementations.
|
||||||
|
- These are imported by direct function files in the `direct-functions/` directory.
|
||||||
|
|
||||||
|
- **MCP Tool Utilities** (`mcp-server/src/tools/utils.js`):
|
||||||
|
- Contains utilities related to MCP response handling and caching.
|
||||||
32
mcp-server/src/core/direct-functions/cache-stats.js
Normal file
32
mcp-server/src/core/direct-functions/cache-stats.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* cache-stats.js
|
||||||
|
* Direct function implementation for retrieving cache statistics
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { contextManager } from '../context-manager.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache statistics for monitoring
|
||||||
|
* @param {Object} args - Command arguments
|
||||||
|
* @param {Object} log - Logger object
|
||||||
|
* @returns {Object} - Cache statistics
|
||||||
|
*/
|
||||||
|
export async function getCacheStatsDirect(args, log) {
|
||||||
|
try {
|
||||||
|
log.info('Retrieving cache statistics');
|
||||||
|
const stats = contextManager.getStats();
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: stats
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error getting cache stats: ${error.message}`);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: {
|
||||||
|
code: 'CACHE_STATS_ERROR',
|
||||||
|
message: error.message || 'Unknown error occurred'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
72
mcp-server/src/core/direct-functions/list-tasks.js
Normal file
72
mcp-server/src/core/direct-functions/list-tasks.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* list-tasks.js
|
||||||
|
* Direct function implementation for listing tasks
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { listTasks } from '../../../../scripts/modules/task-manager.js';
|
||||||
|
import { getCachedOrExecute } from '../../tools/utils.js';
|
||||||
|
import { findTasksJsonPath } from '../utils/path-utils.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct function wrapper for listTasks with error handling and caching.
|
||||||
|
*
|
||||||
|
* @param {Object} args - Command arguments (projectRoot is expected to be resolved).
|
||||||
|
* @param {Object} log - Logger object.
|
||||||
|
* @returns {Promise<Object>} - Task list result { success: boolean, data?: any, error?: { code: string, message: string }, fromCache: boolean }.
|
||||||
|
*/
|
||||||
|
export async function listTasksDirect(args, log) {
|
||||||
|
let tasksPath;
|
||||||
|
try {
|
||||||
|
// Find the tasks path first - needed for cache key and execution
|
||||||
|
tasksPath = findTasksJsonPath(args, log);
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code === 'TASKS_FILE_NOT_FOUND') {
|
||||||
|
log.error(`Tasks file not found: ${error.message}`);
|
||||||
|
// Return the error structure expected by the calling tool/handler
|
||||||
|
return { success: false, error: { code: error.code, message: error.message }, fromCache: false };
|
||||||
|
}
|
||||||
|
log.error(`Unexpected error finding tasks file: ${error.message}`);
|
||||||
|
// Re-throw for outer catch or return structured error
|
||||||
|
return { success: false, error: { code: 'FIND_TASKS_PATH_ERROR', message: error.message }, fromCache: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate cache key *after* finding tasksPath
|
||||||
|
const statusFilter = args.status || 'all';
|
||||||
|
const withSubtasks = args.withSubtasks || false;
|
||||||
|
const cacheKey = `listTasks:${tasksPath}:${statusFilter}:${withSubtasks}`;
|
||||||
|
|
||||||
|
// Define the action function to be executed on cache miss
|
||||||
|
const coreListTasksAction = async () => {
|
||||||
|
try {
|
||||||
|
log.info(`Executing core listTasks function for path: ${tasksPath}, filter: ${statusFilter}, subtasks: ${withSubtasks}`);
|
||||||
|
const resultData = listTasks(tasksPath, statusFilter, withSubtasks, 'json');
|
||||||
|
|
||||||
|
if (!resultData || !resultData.tasks) {
|
||||||
|
log.error('Invalid or empty response from listTasks core function');
|
||||||
|
return { success: false, error: { code: 'INVALID_CORE_RESPONSE', message: 'Invalid or empty response from listTasks core function' } };
|
||||||
|
}
|
||||||
|
log.info(`Core listTasks function retrieved ${resultData.tasks.length} tasks`);
|
||||||
|
return { success: true, data: resultData };
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Core listTasks function failed: ${error.message}`);
|
||||||
|
return { success: false, error: { code: 'LIST_TASKS_CORE_ERROR', message: error.message || 'Failed to list tasks' } };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use the caching utility
|
||||||
|
try {
|
||||||
|
const result = await getCachedOrExecute({
|
||||||
|
cacheKey,
|
||||||
|
actionFn: coreListTasksAction,
|
||||||
|
log
|
||||||
|
});
|
||||||
|
log.info(`listTasksDirect completed. From cache: ${result.fromCache}`);
|
||||||
|
return result; // Returns { success, data/error, fromCache }
|
||||||
|
} catch(error) {
|
||||||
|
// Catch unexpected errors from getCachedOrExecute itself (though unlikely)
|
||||||
|
log.error(`Unexpected error during getCachedOrExecute for listTasks: ${error.message}`);
|
||||||
|
console.error(error.stack);
|
||||||
|
return { success: false, error: { code: 'CACHE_UTIL_ERROR', message: error.message }, fromCache: false };
|
||||||
|
}
|
||||||
|
}
|
||||||
104
mcp-server/src/core/direct-functions/parse-prd.js
Normal file
104
mcp-server/src/core/direct-functions/parse-prd.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* parse-prd.js
|
||||||
|
* Direct function implementation for parsing PRD documents
|
||||||
|
*/
|
||||||
|
|
||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
import { parsePRD } from '../../../../scripts/modules/task-manager.js';
|
||||||
|
import { findTasksJsonPath } from '../utils/path-utils.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct function wrapper for parsing PRD documents and generating tasks.
|
||||||
|
*
|
||||||
|
* @param {Object} args - Command arguments containing input, numTasks or tasks, and output options.
|
||||||
|
* @param {Object} log - Logger object.
|
||||||
|
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||||
|
*/
|
||||||
|
export async function parsePRDDirect(args, log) {
|
||||||
|
try {
|
||||||
|
log.info(`Parsing PRD document with args: ${JSON.stringify(args)}`);
|
||||||
|
|
||||||
|
// Check required parameters
|
||||||
|
if (!args.input) {
|
||||||
|
const errorMessage = 'No input file specified. Please provide an input PRD document path.';
|
||||||
|
log.error(errorMessage);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'MISSING_INPUT_FILE', message: errorMessage },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve input path (relative to project root if provided)
|
||||||
|
const projectRoot = args.projectRoot || process.cwd();
|
||||||
|
const inputPath = path.isAbsolute(args.input) ? args.input : path.resolve(projectRoot, args.input);
|
||||||
|
|
||||||
|
// Determine output path
|
||||||
|
let outputPath;
|
||||||
|
if (args.output) {
|
||||||
|
outputPath = path.isAbsolute(args.output) ? args.output : path.resolve(projectRoot, args.output);
|
||||||
|
} else {
|
||||||
|
// Default to tasks/tasks.json in the project root
|
||||||
|
outputPath = path.resolve(projectRoot, 'tasks', 'tasks.json');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify input file exists
|
||||||
|
if (!fs.existsSync(inputPath)) {
|
||||||
|
const errorMessage = `Input file not found: ${inputPath}`;
|
||||||
|
log.error(errorMessage);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'INPUT_FILE_NOT_FOUND', message: errorMessage },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse number of tasks - handle both string and number values
|
||||||
|
let numTasks = 10; // Default
|
||||||
|
if (args.numTasks) {
|
||||||
|
numTasks = typeof args.numTasks === 'string' ? parseInt(args.numTasks, 10) : args.numTasks;
|
||||||
|
if (isNaN(numTasks)) {
|
||||||
|
numTasks = 10; // Fallback to default if parsing fails
|
||||||
|
log.warn(`Invalid numTasks value: ${args.numTasks}. Using default: 10`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info(`Preparing to parse PRD from ${inputPath} and output to ${outputPath} with ${numTasks} tasks`);
|
||||||
|
|
||||||
|
// Execute core parsePRD function (which is not async but we'll await it to maintain consistency)
|
||||||
|
await parsePRD(inputPath, outputPath, numTasks);
|
||||||
|
|
||||||
|
// Since parsePRD doesn't return a value but writes to a file, we'll read the result
|
||||||
|
// to return it to the caller
|
||||||
|
if (fs.existsSync(outputPath)) {
|
||||||
|
const tasksData = JSON.parse(fs.readFileSync(outputPath, 'utf8'));
|
||||||
|
log.info(`Successfully parsed PRD and generated ${tasksData.tasks?.length || 0} tasks`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
message: `Successfully generated ${tasksData.tasks?.length || 0} tasks from PRD`,
|
||||||
|
taskCount: tasksData.tasks?.length || 0,
|
||||||
|
outputPath
|
||||||
|
},
|
||||||
|
fromCache: false // This operation always modifies state and should never be cached
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const errorMessage = `Tasks file was not created at ${outputPath}`;
|
||||||
|
log.error(errorMessage);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'OUTPUT_FILE_NOT_CREATED', message: errorMessage },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error parsing PRD: ${error.message}`);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'PARSE_PRD_ERROR', message: error.message || 'Unknown error parsing PRD' },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
99
mcp-server/src/core/direct-functions/update-tasks.js
Normal file
99
mcp-server/src/core/direct-functions/update-tasks.js
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* update-tasks.js
|
||||||
|
* Direct function implementation for updating tasks based on new context/prompt
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { updateTasks } from '../../../../scripts/modules/task-manager.js';
|
||||||
|
import { findTasksJsonPath } from '../utils/path-utils.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct function wrapper for updating tasks based on new context/prompt.
|
||||||
|
*
|
||||||
|
* @param {Object} args - Command arguments containing fromId, prompt, useResearch and file path options.
|
||||||
|
* @param {Object} log - Logger object.
|
||||||
|
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||||
|
*/
|
||||||
|
export async function updateTasksDirect(args, log) {
|
||||||
|
try {
|
||||||
|
log.info(`Updating tasks with args: ${JSON.stringify(args)}`);
|
||||||
|
|
||||||
|
// Check required parameters
|
||||||
|
if (!args.from) {
|
||||||
|
const errorMessage = 'No from ID specified. Please provide a task ID to start updating from.';
|
||||||
|
log.error(errorMessage);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'MISSING_FROM_ID', message: errorMessage },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args.prompt) {
|
||||||
|
const errorMessage = 'No prompt specified. Please provide a prompt with new context for task updates.';
|
||||||
|
log.error(errorMessage);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'MISSING_PROMPT', message: errorMessage },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse fromId - handle both string and number values
|
||||||
|
let fromId;
|
||||||
|
if (typeof args.from === 'string') {
|
||||||
|
fromId = parseInt(args.from, 10);
|
||||||
|
if (isNaN(fromId)) {
|
||||||
|
const errorMessage = `Invalid from ID: ${args.from}. Task ID must be a positive integer.`;
|
||||||
|
log.error(errorMessage);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'INVALID_FROM_ID', message: errorMessage },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fromId = args.from;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tasks file path
|
||||||
|
let tasksPath;
|
||||||
|
try {
|
||||||
|
tasksPath = findTasksJsonPath(args, log);
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error finding tasks file: ${error.message}`);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'TASKS_FILE_ERROR', message: error.message },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get research flag
|
||||||
|
const useResearch = args.research === true;
|
||||||
|
|
||||||
|
log.info(`Updating tasks from ID ${fromId} with prompt "${args.prompt}" and research: ${useResearch}`);
|
||||||
|
|
||||||
|
// Execute core updateTasks function
|
||||||
|
await updateTasks(tasksPath, fromId, args.prompt, useResearch);
|
||||||
|
|
||||||
|
// Since updateTasks doesn't return a value but modifies the tasks file,
|
||||||
|
// we'll return a success message
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
message: `Successfully updated tasks from ID ${fromId} based on the prompt`,
|
||||||
|
fromId,
|
||||||
|
tasksPath,
|
||||||
|
useResearch
|
||||||
|
},
|
||||||
|
fromCache: false // This operation always modifies state and should never be cached
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
log.error(`Error updating tasks: ${error.message}`);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: { code: 'UPDATE_TASKS_ERROR', message: error.message || 'Unknown error updating tasks' },
|
||||||
|
fromCache: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,353 +1,29 @@
|
|||||||
/**
|
/**
|
||||||
* task-master-core.js
|
* task-master-core.js
|
||||||
* Direct function imports from Task Master modules
|
* Central module that imports and re-exports all direct function implementations
|
||||||
*
|
* for improved organization and maintainability.
|
||||||
* This module provides direct access to Task Master core functions
|
|
||||||
* for improved performance and error handling compared to CLI execution.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import path from 'path';
|
// Import direct function implementations
|
||||||
import { fileURLToPath } from 'url';
|
import { listTasksDirect } from './direct-functions/list-tasks.js';
|
||||||
import { dirname } from 'path';
|
import { getCacheStatsDirect } from './direct-functions/cache-stats.js';
|
||||||
import fs from 'fs';
|
import { parsePRDDirect } from './direct-functions/parse-prd.js';
|
||||||
|
import { updateTasksDirect } from './direct-functions/update-tasks.js';
|
||||||
|
|
||||||
// Get the current module's directory
|
// Re-export utility functions
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
export { findTasksJsonPath } from './utils/path-utils.js';
|
||||||
const __dirname = dirname(__filename);
|
|
||||||
|
|
||||||
// Import Task Master modules
|
// Re-export all direct functions
|
||||||
import {
|
export {
|
||||||
listTasks,
|
listTasksDirect,
|
||||||
parsePRD,
|
getCacheStatsDirect,
|
||||||
updateTasks,
|
parsePRDDirect,
|
||||||
// We'll import more functions as we continue implementation
|
updateTasksDirect,
|
||||||
} from '../../../scripts/modules/task-manager.js';
|
};
|
||||||
|
|
||||||
// Import context manager
|
|
||||||
import { contextManager } from './context-manager.js';
|
|
||||||
import { getCachedOrExecute } from '../tools/utils.js'; // Import the utility here
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the absolute path to the tasks.json file based on project root and arguments.
|
|
||||||
* @param {Object} args - Command arguments, potentially including 'projectRoot' and 'file'.
|
|
||||||
* @param {Object} log - Logger object.
|
|
||||||
* @returns {string} - Absolute path to the tasks.json file.
|
|
||||||
* @throws {Error} - If tasks.json cannot be found.
|
|
||||||
*/
|
|
||||||
function findTasksJsonPath(args, log) {
|
|
||||||
// Assume projectRoot is already normalized absolute path if passed in args
|
|
||||||
// Or use getProjectRoot if we decide to centralize that logic
|
|
||||||
const projectRoot = args.projectRoot || process.cwd();
|
|
||||||
log.info(`Searching for tasks.json within project root: ${projectRoot}`);
|
|
||||||
|
|
||||||
const possiblePaths = [];
|
|
||||||
|
|
||||||
// 1. If a file is explicitly provided relative to projectRoot
|
|
||||||
if (args.file) {
|
|
||||||
possiblePaths.push(path.resolve(projectRoot, args.file));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Check the standard locations relative to projectRoot
|
|
||||||
possiblePaths.push(
|
|
||||||
path.join(projectRoot, 'tasks.json'),
|
|
||||||
path.join(projectRoot, 'tasks', 'tasks.json')
|
|
||||||
);
|
|
||||||
|
|
||||||
log.info(`Checking potential task file paths: ${possiblePaths.join(', ')}`);
|
|
||||||
|
|
||||||
// Find the first existing path
|
|
||||||
for (const p of possiblePaths) {
|
|
||||||
if (fs.existsSync(p)) {
|
|
||||||
log.info(`Found tasks file at: ${p}`);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no file was found, throw an error
|
|
||||||
const error = new Error(`Tasks file not found in any of the expected locations relative to ${projectRoot}: ${possiblePaths.join(', ')}`);
|
|
||||||
error.code = 'TASKS_FILE_NOT_FOUND';
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direct function wrapper for listTasks with error handling and caching.
|
|
||||||
*
|
|
||||||
* @param {Object} args - Command arguments (projectRoot is expected to be resolved).
|
|
||||||
* @param {Object} log - Logger object.
|
|
||||||
* @returns {Promise<Object>} - Task list result { success: boolean, data?: any, error?: { code: string, message: string }, fromCache: boolean }.
|
|
||||||
*/
|
|
||||||
export async function listTasksDirect(args, log) {
|
|
||||||
let tasksPath;
|
|
||||||
try {
|
|
||||||
// Find the tasks path first - needed for cache key and execution
|
|
||||||
tasksPath = findTasksJsonPath(args, log);
|
|
||||||
} catch (error) {
|
|
||||||
if (error.code === 'TASKS_FILE_NOT_FOUND') {
|
|
||||||
log.error(`Tasks file not found: ${error.message}`);
|
|
||||||
// Return the error structure expected by the calling tool/handler
|
|
||||||
return { success: false, error: { code: error.code, message: error.message }, fromCache: false };
|
|
||||||
}
|
|
||||||
log.error(`Unexpected error finding tasks file: ${error.message}`);
|
|
||||||
// Re-throw for outer catch or return structured error
|
|
||||||
return { success: false, error: { code: 'FIND_TASKS_PATH_ERROR', message: error.message }, fromCache: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate cache key *after* finding tasksPath
|
|
||||||
const statusFilter = args.status || 'all';
|
|
||||||
const withSubtasks = args.withSubtasks || false;
|
|
||||||
const cacheKey = `listTasks:${tasksPath}:${statusFilter}:${withSubtasks}`;
|
|
||||||
|
|
||||||
// Define the action function to be executed on cache miss
|
|
||||||
const coreListTasksAction = async () => {
|
|
||||||
try {
|
|
||||||
log.info(`Executing core listTasks function for path: ${tasksPath}, filter: ${statusFilter}, subtasks: ${withSubtasks}`);
|
|
||||||
const resultData = listTasks(tasksPath, statusFilter, withSubtasks, 'json');
|
|
||||||
|
|
||||||
if (!resultData || !resultData.tasks) {
|
|
||||||
log.error('Invalid or empty response from listTasks core function');
|
|
||||||
return { success: false, error: { code: 'INVALID_CORE_RESPONSE', message: 'Invalid or empty response from listTasks core function' } };
|
|
||||||
}
|
|
||||||
log.info(`Core listTasks function retrieved ${resultData.tasks.length} tasks`);
|
|
||||||
return { success: true, data: resultData };
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Core listTasks function failed: ${error.message}`);
|
|
||||||
return { success: false, error: { code: 'LIST_TASKS_CORE_ERROR', message: error.message || 'Failed to list tasks' } };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use the caching utility
|
|
||||||
try {
|
|
||||||
const result = await getCachedOrExecute({
|
|
||||||
cacheKey,
|
|
||||||
actionFn: coreListTasksAction,
|
|
||||||
log
|
|
||||||
});
|
|
||||||
log.info(`listTasksDirect completed. From cache: ${result.fromCache}`);
|
|
||||||
return result; // Returns { success, data/error, fromCache }
|
|
||||||
} catch(error) {
|
|
||||||
// Catch unexpected errors from getCachedOrExecute itself (though unlikely)
|
|
||||||
log.error(`Unexpected error during getCachedOrExecute for listTasks: ${error.message}`);
|
|
||||||
console.error(error.stack);
|
|
||||||
return { success: false, error: { code: 'CACHE_UTIL_ERROR', message: error.message }, fromCache: false };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cache statistics for monitoring
|
|
||||||
* @param {Object} args - Command arguments
|
|
||||||
* @param {Object} log - Logger object
|
|
||||||
* @returns {Object} - Cache statistics
|
|
||||||
*/
|
|
||||||
export async function getCacheStatsDirect(args, log) {
|
|
||||||
try {
|
|
||||||
log.info('Retrieving cache statistics');
|
|
||||||
const stats = contextManager.getStats();
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
data: stats
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error getting cache stats: ${error.message}`);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: {
|
|
||||||
code: 'CACHE_STATS_ERROR',
|
|
||||||
message: error.message || 'Unknown error occurred'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direct function wrapper for parsing PRD documents and generating tasks.
|
|
||||||
*
|
|
||||||
* @param {Object} args - Command arguments containing input, numTasks or tasks, and output options.
|
|
||||||
* @param {Object} log - Logger object.
|
|
||||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
|
||||||
*/
|
|
||||||
export async function parsePRDDirect(args, log) {
|
|
||||||
try {
|
|
||||||
log.info(`Parsing PRD document with args: ${JSON.stringify(args)}`);
|
|
||||||
|
|
||||||
// Check required parameters
|
|
||||||
if (!args.input) {
|
|
||||||
const errorMessage = 'No input file specified. Please provide an input PRD document path.';
|
|
||||||
log.error(errorMessage);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'MISSING_INPUT_FILE', message: errorMessage },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve input path (relative to project root if provided)
|
|
||||||
const projectRoot = args.projectRoot || process.cwd();
|
|
||||||
const inputPath = path.isAbsolute(args.input) ? args.input : path.resolve(projectRoot, args.input);
|
|
||||||
|
|
||||||
// Determine output path
|
|
||||||
let outputPath;
|
|
||||||
if (args.output) {
|
|
||||||
outputPath = path.isAbsolute(args.output) ? args.output : path.resolve(projectRoot, args.output);
|
|
||||||
} else {
|
|
||||||
// Default to tasks/tasks.json in the project root
|
|
||||||
outputPath = path.resolve(projectRoot, 'tasks', 'tasks.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify input file exists
|
|
||||||
if (!fs.existsSync(inputPath)) {
|
|
||||||
const errorMessage = `Input file not found: ${inputPath}`;
|
|
||||||
log.error(errorMessage);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'INPUT_FILE_NOT_FOUND', message: errorMessage },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse number of tasks - handle both string and number values
|
|
||||||
let numTasks = 10; // Default
|
|
||||||
if (args.numTasks) {
|
|
||||||
numTasks = typeof args.numTasks === 'string' ? parseInt(args.numTasks, 10) : args.numTasks;
|
|
||||||
if (isNaN(numTasks)) {
|
|
||||||
numTasks = 10; // Fallback to default if parsing fails
|
|
||||||
log.warn(`Invalid numTasks value: ${args.numTasks}. Using default: 10`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info(`Preparing to parse PRD from ${inputPath} and output to ${outputPath} with ${numTasks} tasks`);
|
|
||||||
|
|
||||||
// Execute core parsePRD function (which is not async but we'll await it to maintain consistency)
|
|
||||||
await parsePRD(inputPath, outputPath, numTasks);
|
|
||||||
|
|
||||||
// Since parsePRD doesn't return a value but writes to a file, we'll read the result
|
|
||||||
// to return it to the caller
|
|
||||||
if (fs.existsSync(outputPath)) {
|
|
||||||
const tasksData = JSON.parse(fs.readFileSync(outputPath, 'utf8'));
|
|
||||||
log.info(`Successfully parsed PRD and generated ${tasksData.tasks?.length || 0} tasks`);
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
data: {
|
|
||||||
message: `Successfully generated ${tasksData.tasks?.length || 0} tasks from PRD`,
|
|
||||||
taskCount: tasksData.tasks?.length || 0,
|
|
||||||
outputPath
|
|
||||||
},
|
|
||||||
fromCache: false // This operation always modifies state and should never be cached
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
const errorMessage = `Tasks file was not created at ${outputPath}`;
|
|
||||||
log.error(errorMessage);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'OUTPUT_FILE_NOT_CREATED', message: errorMessage },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error parsing PRD: ${error.message}`);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'PARSE_PRD_ERROR', message: error.message || 'Unknown error parsing PRD' },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direct function wrapper for updating tasks based on new context/prompt.
|
|
||||||
*
|
|
||||||
* @param {Object} args - Command arguments containing fromId, prompt, useResearch and file path options.
|
|
||||||
* @param {Object} log - Logger object.
|
|
||||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
|
||||||
*/
|
|
||||||
export async function updateTasksDirect(args, log) {
|
|
||||||
try {
|
|
||||||
log.info(`Updating tasks with args: ${JSON.stringify(args)}`);
|
|
||||||
|
|
||||||
// Check required parameters
|
|
||||||
if (!args.from) {
|
|
||||||
const errorMessage = 'No from ID specified. Please provide a task ID to start updating from.';
|
|
||||||
log.error(errorMessage);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'MISSING_FROM_ID', message: errorMessage },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args.prompt) {
|
|
||||||
const errorMessage = 'No prompt specified. Please provide a prompt with new context for task updates.';
|
|
||||||
log.error(errorMessage);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'MISSING_PROMPT', message: errorMessage },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse fromId - handle both string and number values
|
|
||||||
let fromId;
|
|
||||||
if (typeof args.from === 'string') {
|
|
||||||
fromId = parseInt(args.from, 10);
|
|
||||||
if (isNaN(fromId)) {
|
|
||||||
const errorMessage = `Invalid from ID: ${args.from}. Task ID must be a positive integer.`;
|
|
||||||
log.error(errorMessage);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'INVALID_FROM_ID', message: errorMessage },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fromId = args.from;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get tasks file path
|
|
||||||
let tasksPath;
|
|
||||||
try {
|
|
||||||
tasksPath = findTasksJsonPath(args, log);
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error finding tasks file: ${error.message}`);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'TASKS_FILE_ERROR', message: error.message },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get research flag
|
|
||||||
const useResearch = args.research === true;
|
|
||||||
|
|
||||||
log.info(`Updating tasks from ID ${fromId} with prompt "${args.prompt}" and research: ${useResearch}`);
|
|
||||||
|
|
||||||
// Execute core updateTasks function
|
|
||||||
await updateTasks(tasksPath, fromId, args.prompt, useResearch);
|
|
||||||
|
|
||||||
// Since updateTasks doesn't return a value but modifies the tasks file,
|
|
||||||
// we'll return a success message
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
data: {
|
|
||||||
message: `Successfully updated tasks from ID ${fromId} based on the prompt`,
|
|
||||||
fromId,
|
|
||||||
tasksPath,
|
|
||||||
useResearch
|
|
||||||
},
|
|
||||||
fromCache: false // This operation always modifies state and should never be cached
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
log.error(`Error updating tasks: ${error.message}`);
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
error: { code: 'UPDATE_TASKS_ERROR', message: error.message || 'Unknown error updating tasks' },
|
|
||||||
fromCache: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps Task Master functions to their direct implementation
|
* Maps Task Master functions to their direct implementation
|
||||||
|
* This map is used by tools to look up the appropriate function by name
|
||||||
*/
|
*/
|
||||||
export const directFunctions = {
|
export const directFunctions = {
|
||||||
list: listTasksDirect,
|
list: listTasksDirect,
|
||||||
|
|||||||
49
mcp-server/src/core/utils/path-utils.js
Normal file
49
mcp-server/src/core/utils/path-utils.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* path-utils.js
|
||||||
|
* Utility functions for file path operations in Task Master
|
||||||
|
*/
|
||||||
|
|
||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the absolute path to the tasks.json file based on project root and arguments.
|
||||||
|
* @param {Object} args - Command arguments, potentially including 'projectRoot' and 'file'.
|
||||||
|
* @param {Object} log - Logger object.
|
||||||
|
* @returns {string} - Absolute path to the tasks.json file.
|
||||||
|
* @throws {Error} - If tasks.json cannot be found.
|
||||||
|
*/
|
||||||
|
export function findTasksJsonPath(args, log) {
|
||||||
|
// Assume projectRoot is already normalized absolute path if passed in args
|
||||||
|
// Or use getProjectRoot if we decide to centralize that logic
|
||||||
|
const projectRoot = args.projectRoot || process.cwd();
|
||||||
|
log.info(`Searching for tasks.json within project root: ${projectRoot}`);
|
||||||
|
|
||||||
|
const possiblePaths = [];
|
||||||
|
|
||||||
|
// 1. If a file is explicitly provided relative to projectRoot
|
||||||
|
if (args.file) {
|
||||||
|
possiblePaths.push(path.resolve(projectRoot, args.file));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check the standard locations relative to projectRoot
|
||||||
|
possiblePaths.push(
|
||||||
|
path.join(projectRoot, 'tasks.json'),
|
||||||
|
path.join(projectRoot, 'tasks', 'tasks.json')
|
||||||
|
);
|
||||||
|
|
||||||
|
log.info(`Checking potential task file paths: ${possiblePaths.join(', ')}`);
|
||||||
|
|
||||||
|
// Find the first existing path
|
||||||
|
for (const p of possiblePaths) {
|
||||||
|
if (fs.existsSync(p)) {
|
||||||
|
log.info(`Found tasks file at: ${p}`);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no file was found, throw an error
|
||||||
|
const error = new Error(`Tasks file not found in any of the expected locations relative to ${projectRoot}: ${possiblePaths.join(', ')}`);
|
||||||
|
error.code = 'TASKS_FILE_NOT_FOUND';
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ This task involves completing the Model Context Protocol (MCP) server implementa
|
|||||||
7. Integrate the ModelContextProtocol SDK directly to streamline resource and tool registration, ensuring compatibility with FastMCP's transport mechanisms.
|
7. Integrate the ModelContextProtocol SDK directly to streamline resource and tool registration, ensuring compatibility with FastMCP's transport mechanisms.
|
||||||
8. Identify and address missing components or functionalities to meet FastMCP best practices, such as robust error handling, monitoring endpoints, and concurrency support.
|
8. Identify and address missing components or functionalities to meet FastMCP best practices, such as robust error handling, monitoring endpoints, and concurrency support.
|
||||||
9. Update documentation to include examples of using the MCP server with FastMCP, detailed setup instructions, and client integration guides.
|
9. Update documentation to include examples of using the MCP server with FastMCP, detailed setup instructions, and client integration guides.
|
||||||
|
10. Organize direct function implementations in a modular structure within the mcp-server/src/core/direct-functions/ directory for improved maintainability and organization.
|
||||||
|
|
||||||
The implementation must ensure compatibility with existing MCP clients and follow RESTful API design principles, while supporting concurrent requests and maintaining robust error handling.
|
The implementation must ensure compatibility with existing MCP clients and follow RESTful API design principles, while supporting concurrent requests and maintaining robust error handling.
|
||||||
|
|
||||||
@@ -28,15 +29,17 @@ Testing for the MCP server implementation will follow a comprehensive approach b
|
|||||||
- Test individual MCP server components in isolation
|
- Test individual MCP server components in isolation
|
||||||
- Mock all external dependencies including FastMCP SDK
|
- Mock all external dependencies including FastMCP SDK
|
||||||
- Test each tool implementation separately
|
- Test each tool implementation separately
|
||||||
|
- Test each direct function implementation in the direct-functions directory
|
||||||
- Verify direct function imports work correctly
|
- Verify direct function imports work correctly
|
||||||
- Test context management and caching mechanisms
|
- Test context management and caching mechanisms
|
||||||
- Example files: `context-manager.test.js`, `tool-registration.test.js`, `direct-imports.test.js`
|
- Example files: `context-manager.test.js`, `tool-registration.test.js`, `direct-functions/list-tasks.test.js`
|
||||||
|
|
||||||
2. **Integration Tests** (`tests/integration/mcp-server/`):
|
2. **Integration Tests** (`tests/integration/mcp-server/`):
|
||||||
- Test interactions between MCP server components
|
- Test interactions between MCP server components
|
||||||
- Verify proper tool registration with FastMCP
|
- Verify proper tool registration with FastMCP
|
||||||
- Test context flow between components
|
- Test context flow between components
|
||||||
- Validate error handling across module boundaries
|
- Validate error handling across module boundaries
|
||||||
|
- Test the integration between direct functions and their corresponding MCP tools
|
||||||
- Example files: `server-tool-integration.test.js`, `context-flow.test.js`
|
- Example files: `server-tool-integration.test.js`, `context-flow.test.js`
|
||||||
|
|
||||||
3. **End-to-End Tests** (`tests/e2e/mcp-server/`):
|
3. **End-to-End Tests** (`tests/e2e/mcp-server/`):
|
||||||
@@ -73,6 +76,12 @@ import { MCPServer, MCPError } from '@model-context-protocol/sdk';
|
|||||||
import { initMCPServer } from '../../scripts/mcp-server.js';
|
import { initMCPServer } from '../../scripts/mcp-server.js';
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Direct Function Testing
|
||||||
|
- Test each direct function in isolation
|
||||||
|
- Verify proper error handling and return formats
|
||||||
|
- Test with various input parameters and edge cases
|
||||||
|
- Verify integration with the task-master-core.js export hub
|
||||||
|
|
||||||
### Context Management Testing
|
### Context Management Testing
|
||||||
- Test context creation, retrieval, and manipulation
|
- Test context creation, retrieval, and manipulation
|
||||||
- Verify caching mechanisms work correctly
|
- Verify caching mechanisms work correctly
|
||||||
@@ -136,6 +145,11 @@ import { initMCPServer } from '../../scripts/mcp-server.js';
|
|||||||
- Verify proper message formatting
|
- Verify proper message formatting
|
||||||
- Test error handling in transport layer
|
- Test error handling in transport layer
|
||||||
|
|
||||||
|
6. **Direct Function Structure**
|
||||||
|
- Test the modular organization of direct functions
|
||||||
|
- Verify proper import/export through task-master-core.js
|
||||||
|
- Test utility functions in the utils directory
|
||||||
|
|
||||||
All tests will be automated and integrated into the CI/CD pipeline to ensure consistent quality.
|
All tests will be automated and integrated into the CI/CD pipeline to ensure consistent quality.
|
||||||
|
|
||||||
# Subtasks:
|
# Subtasks:
|
||||||
@@ -362,77 +376,454 @@ Following MCP implementation standards:\n\n1. Create updateTasksDirect function
|
|||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for updating a single task by ID with new information.
|
### Description: Create direct function wrapper and MCP tool for updating a single task by ID with new information.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create updateTaskByIdDirect function in task-master-core.js:\n - Import updateTaskById from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: taskId, prompt, useResearch\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create update-task.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import updateTaskByIdDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerUpdateTaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for updateTaskByIdDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create updateTaskByIdDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import updateTaskById from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: taskId, prompt, useResearch
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create update-task.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import updateTaskByIdDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerUpdateTaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for updateTaskByIdDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 19. Implement update-subtask MCP command [pending]
|
## 19. Implement update-subtask MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for appending information to a specific subtask.
|
### Description: Create direct function wrapper and MCP tool for appending information to a specific subtask.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create updateSubtaskByIdDirect function in task-master-core.js:\n - Import updateSubtaskById from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: subtaskId, prompt, useResearch\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create update-subtask.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import updateSubtaskByIdDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerUpdateSubtaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for updateSubtaskByIdDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create updateSubtaskByIdDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import updateSubtaskById from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: subtaskId, prompt, useResearch
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create update-subtask.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import updateSubtaskByIdDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerUpdateSubtaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for updateSubtaskByIdDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 20. Implement generate MCP command [pending]
|
## 20. Implement generate MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for generating task files from tasks.json.
|
### Description: Create direct function wrapper and MCP tool for generating task files from tasks.json.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create generateTaskFilesDirect function in task-master-core.js:\n - Import generateTaskFiles from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: tasksPath, outputDir\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create generate.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import generateTaskFilesDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerGenerateTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for generateTaskFilesDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create generateTaskFilesDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import generateTaskFiles from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: tasksPath, outputDir
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create generate.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import generateTaskFilesDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerGenerateTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for generateTaskFilesDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 21. Implement set-status MCP command [pending]
|
## 21. Implement set-status MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for setting task status.
|
### Description: Create direct function wrapper and MCP tool for setting task status.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create setTaskStatusDirect function in task-master-core.js:\n - Import setTaskStatus from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: taskId, status\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create set-status.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import setTaskStatusDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerSetStatusTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for setTaskStatusDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create setTaskStatusDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import setTaskStatus from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: taskId, status
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create set-status.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import setTaskStatusDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerSetStatusTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for setTaskStatusDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 22. Implement show-task MCP command [pending]
|
## 22. Implement show-task MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for showing task details.
|
### Description: Create direct function wrapper and MCP tool for showing task details.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create showTaskDirect function in task-master-core.js:\n - Import showTask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: taskId\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create show-task.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import showTaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerShowTaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for showTaskDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create showTaskDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import showTask from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: taskId
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create show-task.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import showTaskDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerShowTaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for showTaskDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 23. Implement next-task MCP command [pending]
|
## 23. Implement next-task MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for finding the next task to work on.
|
### Description: Create direct function wrapper and MCP tool for finding the next task to work on.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create nextTaskDirect function in task-master-core.js:\n - Import nextTask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments (no specific args needed except projectRoot/file)\n - Handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create next-task.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import nextTaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerNextTaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for nextTaskDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create nextTaskDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import nextTask from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments (no specific args needed except projectRoot/file)
|
||||||
|
- Handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create next-task.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import nextTaskDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerNextTaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for nextTaskDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 24. Implement expand-task MCP command [pending]
|
## 24. Implement expand-task MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for expanding a task into subtasks.
|
### Description: Create direct function wrapper and MCP tool for expanding a task into subtasks.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create expandTaskDirect function in task-master-core.js:\n - Import expandTask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: taskId, prompt, num, force, research\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create expand-task.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import expandTaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerExpandTaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for expandTaskDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create expandTaskDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import expandTask from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: taskId, prompt, num, force, research
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create expand-task.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import expandTaskDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerExpandTaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for expandTaskDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 25. Implement add-task MCP command [pending]
|
## 25. Implement add-task MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for adding new tasks.
|
### Description: Create direct function wrapper and MCP tool for adding new tasks.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create addTaskDirect function in task-master-core.js:\n - Import addTask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: prompt, priority, dependencies\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create add-task.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import addTaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerAddTaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for addTaskDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create addTaskDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import addTask from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: prompt, priority, dependencies
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create add-task.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import addTaskDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerAddTaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for addTaskDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 26. Implement add-subtask MCP command [pending]
|
## 26. Implement add-subtask MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for adding subtasks to existing tasks.
|
### Description: Create direct function wrapper and MCP tool for adding subtasks to existing tasks.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create addSubtaskDirect function in task-master-core.js:\n - Import addSubtask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: parentTaskId, title, description, details\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create add-subtask.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import addSubtaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerAddSubtaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for addSubtaskDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create addSubtaskDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import addSubtask from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: parentTaskId, title, description, details
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create add-subtask.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import addSubtaskDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerAddSubtaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for addSubtaskDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 27. Implement remove-subtask MCP command [pending]
|
## 27. Implement remove-subtask MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for removing subtasks from tasks.
|
### Description: Create direct function wrapper and MCP tool for removing subtasks from tasks.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create removeSubtaskDirect function in task-master-core.js:\n - Import removeSubtask from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: parentTaskId, subtaskId\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create remove-subtask.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import removeSubtaskDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerRemoveSubtaskTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for removeSubtaskDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create removeSubtaskDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import removeSubtask from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: parentTaskId, subtaskId
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create remove-subtask.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import removeSubtaskDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerRemoveSubtaskTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for removeSubtaskDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 28. Implement analyze MCP command [pending]
|
## 28. Implement analyze MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for analyzing task complexity.
|
### Description: Create direct function wrapper and MCP tool for analyzing task complexity.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create analyzeTaskComplexityDirect function in task-master-core.js:\n - Import analyzeTaskComplexity from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: taskId\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create analyze.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import analyzeTaskComplexityDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerAnalyzeTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for analyzeTaskComplexityDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create analyzeTaskComplexityDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import analyzeTaskComplexity from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: taskId
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create analyze.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import analyzeTaskComplexityDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerAnalyzeTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for analyzeTaskComplexityDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 29. Implement clear-subtasks MCP command [pending]
|
## 29. Implement clear-subtasks MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for clearing subtasks from a parent task.
|
### Description: Create direct function wrapper and MCP tool for clearing subtasks from a parent task.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create clearSubtasksDirect function in task-master-core.js:\n - Import clearSubtasks from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: taskId\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create clear-subtasks.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import clearSubtasksDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerClearSubtasksTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for clearSubtasksDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create clearSubtasksDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import clearSubtasks from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: taskId
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create clear-subtasks.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import clearSubtasksDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerClearSubtasksTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for clearSubtasksDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
## 30. Implement expand-all MCP command [pending]
|
## 30. Implement expand-all MCP command [pending]
|
||||||
### Dependencies: None
|
### Dependencies: None
|
||||||
### Description: Create direct function wrapper and MCP tool for expanding all tasks into subtasks.
|
### Description: Create direct function wrapper and MCP tool for expanding all tasks into subtasks.
|
||||||
### Details:
|
### Details:
|
||||||
Following MCP implementation standards:\n\n1. Create expandAllTasksDirect function in task-master-core.js:\n - Import expandAllTasks from task-manager.js\n - Handle file paths using findTasksJsonPath utility\n - Process arguments: prompt, num, force, research\n - Validate inputs and handle errors with try/catch\n - Return standardized { success, data/error } object\n - Add to directFunctions map\n\n2. Create expand-all.js MCP tool in mcp-server/src/tools/:\n - Import z from zod for parameter schema\n - Import executeMCPToolAction from ./utils.js\n - Import expandAllTasksDirect from task-master-core.js\n - Define parameters matching CLI options using zod schema\n - Implement registerExpandAllTool(server) with server.addTool\n - Use executeMCPToolAction in execute method\n\n3. Register in tools/index.js\n\n4. Add to .cursor/mcp.json with appropriate schema\n\n5. Write tests following testing guidelines:\n - Unit test for expandAllTasksDirect\n - Integration test for MCP tool
|
Following MCP implementation standards:
|
||||||
|
|
||||||
|
1. Create expandAllTasksDirect.js in mcp-server/src/core/direct-functions/:
|
||||||
|
- Import expandAllTasks from task-manager.js
|
||||||
|
- Handle file paths using findTasksJsonPath utility
|
||||||
|
- Process arguments: prompt, num, force, research
|
||||||
|
- Validate inputs and handle errors with try/catch
|
||||||
|
- Return standardized { success, data/error } object
|
||||||
|
|
||||||
|
2. Export from task-master-core.js:
|
||||||
|
- Import the function from its file
|
||||||
|
- Add to directFunctions map
|
||||||
|
|
||||||
|
3. Create expand-all.js MCP tool in mcp-server/src/tools/:
|
||||||
|
- Import z from zod for parameter schema
|
||||||
|
- Import executeMCPToolAction from ./utils.js
|
||||||
|
- Import expandAllTasksDirect from task-master-core.js
|
||||||
|
- Define parameters matching CLI options using zod schema
|
||||||
|
- Implement registerExpandAllTool(server) with server.addTool
|
||||||
|
- Use executeMCPToolAction in execute method
|
||||||
|
|
||||||
|
4. Register in tools/index.js
|
||||||
|
|
||||||
|
5. Add to .cursor/mcp.json with appropriate schema
|
||||||
|
|
||||||
|
6. Write tests following testing guidelines:
|
||||||
|
- Unit test for expandAllTasksDirect.js
|
||||||
|
- Integration test for MCP tool
|
||||||
|
|
||||||
|
## 31. Create Core Direct Function Structure [pending]
|
||||||
|
### Dependencies: None
|
||||||
|
### Description: Set up the modular directory structure for direct functions and update task-master-core.js to act as an import/export hub.
|
||||||
|
### Details:
|
||||||
|
1. Create the mcp-server/src/core/direct-functions/ directory structure
|
||||||
|
2. Update task-master-core.js to import and re-export functions from individual files
|
||||||
|
3. Create a utils directory for shared utility functions
|
||||||
|
4. Implement a standard template for direct function files
|
||||||
|
5. Create documentation for the new modular structure
|
||||||
|
6. Update existing imports in MCP tools to use the new structure
|
||||||
|
7. Create unit tests for the import/export hub functionality
|
||||||
|
8. Ensure backward compatibility with any existing code using the old structure
|
||||||
|
|
||||||
|
## 32. Refactor Existing Direct Functions to Modular Structure [pending]
|
||||||
|
### Dependencies: 23.31
|
||||||
|
### Description: Move existing direct function implementations from task-master-core.js to individual files in the new directory structure.
|
||||||
|
### Details:
|
||||||
|
1. Identify all existing direct functions in task-master-core.js
|
||||||
|
2. Create individual files for each function in mcp-server/src/core/direct-functions/
|
||||||
|
3. Move the implementation to the new files, ensuring consistent error handling
|
||||||
|
4. Update imports/exports in task-master-core.js
|
||||||
|
5. Create unit tests for each individual function file
|
||||||
|
6. Update documentation to reflect the new structure
|
||||||
|
7. Ensure all MCP tools reference the functions through task-master-core.js
|
||||||
|
8. Verify backward compatibility with existing code
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user