feat: adds remove-task command + MCP implementation.

This commit is contained in:
Eyal Toledano
2025-04-03 00:35:11 -04:00
parent 6442bf5ee1
commit cdd87ccc5e
15 changed files with 1204 additions and 26 deletions

View File

@@ -37,6 +37,126 @@ While this document details the implementation of Task Master's **CLI commands**
- ✅ DO: Include validation for required parameters
- ❌ DON'T: Implement business logic in command handlers
## Best Practices for Removal/Delete Commands
When implementing commands that delete or remove data (like `remove-task` or `remove-subtask`), follow these specific guidelines:
- **Confirmation Prompts**:
- ✅ **DO**: Include a confirmation prompt by default for destructive operations
- ✅ **DO**: Provide a `--yes` or `-y` flag to skip confirmation for scripting/automation
- ✅ **DO**: Show what will be deleted in the confirmation message
- ❌ **DON'T**: Perform destructive operations without user confirmation unless explicitly overridden
```javascript
// ✅ DO: Include confirmation for destructive operations
programInstance
.command('remove-task')
.description('Remove a task or subtask permanently')
.option('-i, --id <id>', 'ID of the task to remove')
.option('-y, --yes', 'Skip confirmation prompt', false)
.action(async (options) => {
// Validation code...
if (!options.yes) {
const confirm = await inquirer.prompt([{
type: 'confirm',
name: 'proceed',
message: `Are you sure you want to permanently delete task ${taskId}? This cannot be undone.`,
default: false
}]);
if (!confirm.proceed) {
console.log(chalk.yellow('Operation cancelled.'));
return;
}
}
// Proceed with removal...
});
```
- **File Path Handling**:
- ✅ **DO**: Use `path.join()` to construct file paths
- ✅ **DO**: Follow established naming conventions for tasks (e.g., `task_001.txt`)
- ✅ **DO**: Check if files exist before attempting to delete them
- ✅ **DO**: Handle file deletion errors gracefully
- ❌ **DON'T**: Construct paths with string concatenation
```javascript
// ✅ DO: Properly construct file paths
const taskFilePath = path.join(
path.dirname(tasksPath),
`task_${taskId.toString().padStart(3, '0')}.txt`
);
// ✅ DO: Check existence before deletion
if (fs.existsSync(taskFilePath)) {
try {
fs.unlinkSync(taskFilePath);
console.log(chalk.green(`Task file deleted: ${taskFilePath}`));
} catch (error) {
console.warn(chalk.yellow(`Could not delete task file: ${error.message}`));
}
}
```
- **Clean Up References**:
- ✅ **DO**: Clean up references to the deleted item in other parts of the data
- ✅ **DO**: Handle both direct and indirect references
- ✅ **DO**: Explain what related data is being updated
- ❌ **DON'T**: Leave dangling references
```javascript
// ✅ DO: Clean up references when deleting items
console.log(chalk.blue('Cleaning up task dependencies...'));
let referencesRemoved = 0;
// Update dependencies in other tasks
data.tasks.forEach(task => {
if (task.dependencies && task.dependencies.includes(taskId)) {
task.dependencies = task.dependencies.filter(depId => depId !== taskId);
referencesRemoved++;
}
});
if (referencesRemoved > 0) {
console.log(chalk.green(`Removed ${referencesRemoved} references to task ${taskId} from other tasks`));
}
```
- **Task File Regeneration**:
- ✅ **DO**: Regenerate task files after destructive operations
- ✅ **DO**: Pass all required parameters to generation functions
- ✅ **DO**: Provide an option to skip regeneration if needed
- ❌ **DON'T**: Assume default parameters will work
```javascript
// ✅ DO: Properly regenerate files after deletion
if (!options.skipGenerate) {
console.log(chalk.blue('Regenerating task files...'));
try {
// Note both parameters are explicitly provided
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
console.log(chalk.green('Task files regenerated successfully'));
} catch (error) {
console.warn(chalk.yellow(`Warning: Could not regenerate task files: ${error.message}`));
}
}
```
- **Alternative Suggestions**:
- ✅ **DO**: Suggest non-destructive alternatives when appropriate
- ✅ **DO**: Explain the difference between deletion and status changes
- ✅ **DO**: Include examples of alternative commands
```javascript
// ✅ DO: Suggest alternatives for destructive operations
console.log(chalk.yellow('Note: If you just want to exclude this task from active work, consider:'));
console.log(chalk.cyan(` task-master set-status --id=${taskId} --status=cancelled`));
console.log(chalk.cyan(` task-master set-status --id=${taskId} --status=deferred`));
console.log('This preserves the task and its history for reference.');
```
## Option Naming Conventions
- **Command Names**:

View File

@@ -15,6 +15,80 @@ The MCP server acts as a bridge between external tools (like Cursor) and the cor
- **Flow**: `External Tool (Cursor)` <-> `FastMCP Server` <-> `MCP Tools` (`mcp-server/src/tools/*.js`) <-> `Core Logic Wrappers` (`mcp-server/src/core/direct-functions/*.js`, exported via `task-master-core.js`) <-> `Core Modules` (`scripts/modules/*.js`)
- **Goal**: Provide a performant and reliable way for external tools to interact with Task Master functionality without directly invoking the CLI for every operation.
## Direct Function Implementation Best Practices
When implementing a new direct function in `mcp-server/src/core/direct-functions/`, follow these critical guidelines:
1. **Verify Function Dependencies**:
- ✅ **DO**: Check that all helper functions your direct function needs are properly exported from their source modules
- ✅ **DO**: Import these dependencies explicitly at the top of your file
- ❌ **DON'T**: Assume helper functions like `findTaskById` or `taskExists` are automatically available
- **Example**:
```javascript
// At top of direct-function file
import { removeTask, findTaskById, taskExists } from '../../../../scripts/modules/task-manager.js';
```
2. **Parameter Verification and Completeness**:
- ✅ **DO**: Verify the signature of core functions you're calling and ensure all required parameters are provided
- ✅ **DO**: Pass explicit values for required parameters rather than relying on defaults
- ✅ **DO**: Double-check parameter order against function definition
- ❌ **DON'T**: Omit parameters assuming they have default values
- **Example**:
```javascript
// Correct parameter handling in direct function
async function generateTaskFilesDirect(args, log) {
const tasksPath = findTasksJsonPath(args, log);
const outputDir = args.output || path.dirname(tasksPath);
try {
// Pass all required parameters
const result = await generateTaskFiles(tasksPath, outputDir);
return { success: true, data: result, fromCache: false };
} catch (error) {
// Error handling...
}
}
```
3. **Consistent File Path Handling**:
- ✅ **DO**: Use `path.join()` instead of string concatenation for file paths
- ✅ **DO**: Follow established file naming conventions (`task_001.txt` not `1.md`)
- ✅ **DO**: Use `path.dirname()` and other path utilities for manipulating paths
- ✅ **DO**: When paths relate to task files, follow the standard format: `task_${id.toString().padStart(3, '0')}.txt`
- ❌ **DON'T**: Create custom file path handling logic that diverges from established patterns
- **Example**:
```javascript
// Correct file path handling
const taskFilePath = path.join(
path.dirname(tasksPath),
`task_${taskId.toString().padStart(3, '0')}.txt`
);
```
4. **Comprehensive Error Handling**:
- ✅ **DO**: Wrap core function calls in try/catch blocks
- ✅ **DO**: Log errors with appropriate severity and context
- ✅ **DO**: Return standardized error objects with code and message
- ✅ **DO**: Handle file system errors separately from function-specific errors
- **Example**:
```javascript
try {
// Core function call
} catch (error) {
log.error(`Failed to execute command: ${error.message}`);
return {
success: false,
error: {
code: error.code || 'DIRECT_FUNCTION_ERROR',
message: error.message,
details: error.stack
},
fromCache: false
};
}
```
## Tool Definition and Execution
### Tool Structure

View File

@@ -31,6 +31,72 @@ The standard pattern for adding a feature follows this workflow:
5. **Configuration**: Update any configuration in [`utils.js`](mdc:scripts/modules/utils.js) if needed, following [`utilities.mdc`](mdc:.cursor/rules/utilities.mdc).
6. **Documentation**: Update help text and documentation in [dev_workflow.mdc](mdc:scripts/modules/dev_workflow.mdc)
## Critical Checklist for New Features
- **Comprehensive Function Exports**:
- ✅ **DO**: Export all helper functions and utility methods needed by your new function
- ✅ **DO**: Review dependencies and ensure functions like `findTaskById`, `taskExists` are exported
- ❌ **DON'T**: Assume internal functions are already exported - always check and add them explicitly
- **Example**: If implementing a feature that checks task existence, ensure the helper function is in exports:
```javascript
// At the bottom of your module file:
export {
// ... existing exports ...
yourNewFunction,
taskExists, // Helper function used by yourNewFunction
findTaskById, // Helper function used by yourNewFunction
};
```
- **Parameter Completeness**:
- ✅ **DO**: Pass all required parameters to functions you call within your implementation
- ✅ **DO**: Check function signatures before implementing calls to them
- ❌ **DON'T**: Assume default parameter values will handle missing arguments
- **Example**: When calling file generation, pass both required parameters:
```javascript
// ✅ DO: Pass all required parameters
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
// ❌ DON'T: Omit required parameters
await generateTaskFiles(tasksPath); // Error - missing outputDir parameter
```
- **Consistent File Path Handling**:
- ✅ **DO**: Use consistent file naming conventions: `task_${id.toString().padStart(3, '0')}.txt`
- ✅ **DO**: Use `path.join()` for composing file paths
- ✅ **DO**: Use appropriate file extensions (.txt for tasks, .json for data)
- ❌ **DON'T**: Hardcode path separators or inconsistent file extensions
- **Example**: Creating file paths for tasks:
```javascript
// ✅ DO: Use consistent file naming and path.join
const taskFileName = path.join(
path.dirname(tasksPath),
`task_${taskId.toString().padStart(3, '0')}.txt`
);
// ❌ DON'T: Use inconsistent naming or string concatenation
const taskFileName = path.dirname(tasksPath) + '/' + taskId + '.md';
```
- **Error Handling and Reporting**:
- ✅ **DO**: Use structured error objects with code and message properties
- ✅ **DO**: Include clear error messages identifying the specific problem
- ✅ **DO**: Handle both function-specific errors and potential file system errors
- ✅ **DO**: Log errors at appropriate severity levels
- **Example**: Structured error handling in core functions:
```javascript
try {
// Implementation...
} catch (error) {
log('error', `Error removing task: ${error.message}`);
throw {
code: 'REMOVE_TASK_ERROR',
message: error.message,
details: error.stack
};
}
```
```javascript
// 1. CORE LOGIC: Add function to appropriate module (example in task-manager.js)
/**

View File

@@ -153,11 +153,23 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Mark progress as tasks move through the development cycle.
### 12. Remove Task (`remove_task`)
* **MCP Tool:** `remove_task`
* **CLI Command:** `task-master remove-task [options]`
* **Description:** `Permanently remove a task or subtask from the Taskmaster tasks list.`
* **Key Parameters/Options:**
* `id`: `Required. The ID of the Taskmaster task (e.g., '5') or subtask (e.g., '5.2') to permanently remove.` (CLI: `-i, --id <id>`)
* `yes`: `Skip the confirmation prompt and immediately delete the task.` (CLI: `-y, --yes`)
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Permanently delete tasks or subtasks that are no longer needed in the project.
* **Notes:** Use with caution as this operation cannot be undone. Consider using 'blocked', 'cancelled', or 'deferred' status instead if you just want to exclude a task from active planning but keep it for reference. The command automatically cleans up dependency references in other tasks.
---
## Task Structure & Breakdown
### 12. Expand Task (`expand_task`)
### 13. Expand Task (`expand_task`)
* **MCP Tool:** `expand_task`
* **CLI Command:** `task-master expand [options]`
@@ -171,7 +183,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Generate a detailed implementation plan for a complex task before starting coding.
### 13. Expand All Tasks (`expand_all`)
### 14. Expand All Tasks (`expand_all`)
* **MCP Tool:** `expand_all`
* **CLI Command:** `task-master expand --all [options]` (Note: CLI uses the `expand` command with the `--all` flag)
@@ -184,7 +196,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Useful after initial task generation or complexity analysis to break down multiple tasks at once.
### 14. Clear Subtasks (`clear_subtasks`)
### 15. Clear Subtasks (`clear_subtasks`)
* **MCP Tool:** `clear_subtasks`
* **CLI Command:** `task-master clear-subtasks [options]`
@@ -195,7 +207,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Used before regenerating subtasks with `expand_task` if the previous breakdown needs replacement.
### 15. Remove Subtask (`remove_subtask`)
### 16. Remove Subtask (`remove_subtask`)
* **MCP Tool:** `remove_subtask`
* **CLI Command:** `task-master remove-subtask [options]`
@@ -211,7 +223,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
## Dependency Management
### 16. Add Dependency (`add_dependency`)
### 17. Add Dependency (`add_dependency`)
* **MCP Tool:** `add_dependency`
* **CLI Command:** `task-master add-dependency [options]`
@@ -222,7 +234,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Establish the correct order of execution between tasks.
### 17. Remove Dependency (`remove_dependency`)
### 18. Remove Dependency (`remove_dependency`)
* **MCP Tool:** `remove_dependency`
* **CLI Command:** `task-master remove-dependency [options]`
@@ -233,7 +245,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Update task relationships when the order of execution changes.
### 18. Validate Dependencies (`validate_dependencies`)
### 19. Validate Dependencies (`validate_dependencies`)
* **MCP Tool:** `validate_dependencies`
* **CLI Command:** `task-master validate-dependencies [options]`
@@ -242,7 +254,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Audit the integrity of your task dependencies.
### 19. Fix Dependencies (`fix_dependencies`)
### 20. Fix Dependencies (`fix_dependencies`)
* **MCP Tool:** `fix_dependencies`
* **CLI Command:** `task-master fix-dependencies [options]`
@@ -255,7 +267,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
## Analysis & Reporting
### 20. Analyze Complexity (`analyze_complexity`)
### 21. Analyze Complexity (`analyze_complexity`)
* **MCP Tool:** `analyze_complexity`
* **CLI Command:** `task-master analyze-complexity [options]`
@@ -267,7 +279,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
* `file`: `Path to your Taskmaster 'tasks.json' file (default relies on auto-detection).` (CLI: `-f, --file <file>`)
* **Usage:** Identify which tasks are likely too large and need further breakdown before implementation.
### 21. Complexity Report (`complexity_report`)
### 22. Complexity Report (`complexity_report`)
* **MCP Tool:** `complexity_report`
* **CLI Command:** `task-master complexity-report [options]`
@@ -280,7 +292,7 @@ This document provides a detailed reference for interacting with Taskmaster, cov
## File Generation
### 22. Generate Task Files (`generate`)
### 23. Generate Task Files (`generate`)
* **MCP Tool:** `generate`
* **CLI Command:** `task-master generate [options]`
@@ -295,5 +307,5 @@ This document provides a detailed reference for interacting with Taskmaster, cov
## Configuration & Metadata
- **Environment Variables**: Taskmaster relies on environment variables for configuration (API keys, model preferences, default settings). See [`dev_workflow.mdc`](mdc:.cursor/rules/dev_workflow.mdc) or the project README for a list.
- **`tasks.json`**: The core data file containing the array of tasks and their details. See [`tasks.mdc`](mdc:.cursor/rules/tasks.mdc).
- **`tasks.json`**: The core data file containing the array of tasks and their details. See [`tasks.mdc`](mdc:.cursor/rules/tasks.mdc) for details.
- **`task_xxx.md` files**: Individual markdown files generated by the `generate` command/tool, reflecting the content of `tasks.json`.