From d06e45bf128da4644fc599deca927b75fbed24c4 Mon Sep 17 00:00:00 2001 From: Eyal Toledano Date: Mon, 31 Mar 2025 14:01:49 -0400 Subject: [PATCH] Implement fix-dependencies MCP command for automatically fixing invalid dependencies --- .changeset/two-bats-smoke.md | 1 + .../core/direct-functions/fix-dependencies.js | 55 +++++++++++++++++++ mcp-server/src/core/task-master-core.js | 7 ++- mcp-server/src/tools/fix-dependencies.js | 34 ++++++++++++ mcp-server/src/tools/index.js | 2 + 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 mcp-server/src/core/direct-functions/fix-dependencies.js create mode 100644 mcp-server/src/tools/fix-dependencies.js diff --git a/.changeset/two-bats-smoke.md b/.changeset/two-bats-smoke.md index 62679538..d868335b 100644 --- a/.changeset/two-bats-smoke.md +++ b/.changeset/two-bats-smoke.md @@ -18,5 +18,6 @@ - Implement clear-subtasks MCP command for clearing subtasks from parent tasks - Implement remove-dependency MCP command for removing dependencies from tasks - Implement validate-dependencies MCP command for checking validity of task dependencies +- Implement fix-dependencies MCP command for automatically fixing invalid dependencies - Document MCP server naming conventions in architecture.mdc and mcp.mdc files (file names use kebab-case, direct functions use camelCase with Direct suffix, tool registration functions use camelCase with Tool suffix, and MCP tool names use snake_case) - Enhance task show view with a color-coded progress bar for visualizing subtask completion percentage diff --git a/mcp-server/src/core/direct-functions/fix-dependencies.js b/mcp-server/src/core/direct-functions/fix-dependencies.js new file mode 100644 index 00000000..d5994a04 --- /dev/null +++ b/mcp-server/src/core/direct-functions/fix-dependencies.js @@ -0,0 +1,55 @@ +/** + * Direct function wrapper for fixDependenciesCommand + */ + +import { fixDependenciesCommand } from '../../../../scripts/modules/dependency-manager.js'; +import { findTasksJsonPath } from '../utils/path-utils.js'; +import fs from 'fs'; + +/** + * Fix invalid dependencies in tasks.json automatically + * @param {Object} args - Function arguments + * @param {string} [args.file] - Path to the tasks file + * @param {string} [args.projectRoot] - Project root directory + * @param {Object} log - Logger object + * @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>} + */ +export async function fixDependenciesDirect(args, log) { + try { + log.info(`Fixing invalid dependencies in tasks...`); + + // Determine the tasks file path + const tasksPath = args.file || await findTasksJsonPath(args.projectRoot); + + // Verify the file exists + if (!fs.existsSync(tasksPath)) { + return { + success: false, + error: { + code: 'FILE_NOT_FOUND', + message: `Tasks file not found at ${tasksPath}` + } + }; + } + + // Call the original command function + await fixDependenciesCommand(tasksPath); + + return { + success: true, + data: { + message: 'Dependencies fixed successfully', + tasksPath + } + }; + } catch (error) { + log.error(`Error fixing dependencies: ${error.message}`); + return { + success: false, + error: { + code: 'FIX_DEPENDENCIES_ERROR', + message: error.message + } + }; + } +} \ No newline at end of file diff --git a/mcp-server/src/core/task-master-core.js b/mcp-server/src/core/task-master-core.js index c7067ecb..5276d276 100644 --- a/mcp-server/src/core/task-master-core.js +++ b/mcp-server/src/core/task-master-core.js @@ -24,6 +24,7 @@ import { clearSubtasksDirect } from './direct-functions/clear-subtasks.js'; import { expandAllTasksDirect } from './direct-functions/expand-all-tasks.js'; import { removeDependencyDirect } from './direct-functions/remove-dependency.js'; import { validateDependenciesDirect } from './direct-functions/validate-dependencies.js'; +import { fixDependenciesDirect } from './direct-functions/fix-dependencies.js'; // Re-export utility functions export { findTasksJsonPath } from './utils/path-utils.js'; @@ -48,7 +49,8 @@ export const directFunctions = new Map([ ['clearSubtasksDirect', clearSubtasksDirect], ['expandAllTasksDirect', expandAllTasksDirect], ['removeDependencyDirect', removeDependencyDirect], - ['validateDependenciesDirect', validateDependenciesDirect] + ['validateDependenciesDirect', validateDependenciesDirect], + ['fixDependenciesDirect', fixDependenciesDirect] ]); // Re-export all direct function implementations @@ -71,5 +73,6 @@ export { clearSubtasksDirect, expandAllTasksDirect, removeDependencyDirect, - validateDependenciesDirect + validateDependenciesDirect, + fixDependenciesDirect }; \ No newline at end of file diff --git a/mcp-server/src/tools/fix-dependencies.js b/mcp-server/src/tools/fix-dependencies.js new file mode 100644 index 00000000..d74643ed --- /dev/null +++ b/mcp-server/src/tools/fix-dependencies.js @@ -0,0 +1,34 @@ +/** + * tools/fix-dependencies.js + * Tool for automatically fixing invalid task dependencies + */ + +import { z } from "zod"; +import { + handleApiResult, + createErrorResponse +} from "./utils.js"; +import { fixDependenciesDirect } from "../core/task-master-core.js"; + +/** + * Register the fixDependencies tool with the MCP server + * @param {Object} server - FastMCP server instance + */ +export function registerFixDependenciesTool(server) { + server.addTool({ + name: "fix_dependencies", + description: "Fix invalid dependencies in tasks automatically", + parameters: z.object({ + file: z.string().optional().describe("Path to the tasks file"), + projectRoot: z.string().optional().describe("Root directory of the project (default: current working directory)") + }), + handler: async ({ file, projectRoot }, { logger }) => { + try { + const result = await fixDependenciesDirect({ file, projectRoot }, logger); + return handleApiResult(result); + } catch (error) { + return createErrorResponse(error); + } + } + }); +} \ No newline at end of file diff --git a/mcp-server/src/tools/index.js b/mcp-server/src/tools/index.js index 4c7fd7df..43b4672b 100644 --- a/mcp-server/src/tools/index.js +++ b/mcp-server/src/tools/index.js @@ -22,6 +22,7 @@ import { registerClearSubtasksTool } from "./clear-subtasks.js"; import { registerExpandAllTool } from "./expand-all.js"; import { registerRemoveDependencyTool } from "./remove-dependency.js"; import { registerValidateDependenciesTool } from "./validate-dependencies.js"; +import { registerFixDependenciesTool } from "./fix-dependencies.js"; /** * Register all Task Master tools with the MCP server @@ -50,6 +51,7 @@ export function registerTaskMasterTools(server) { registerExpandAllTool(server); registerRemoveDependencyTool(server); registerValidateDependenciesTool(server); + registerFixDependenciesTool(server); logger.info("Successfully registered all Task Master tools"); } catch (error) {