fix(core): Implement Boundary-First Tag Resolution (#943)
* refactor(context): Standardize tag and projectRoot handling across all task tools This commit unifies context management by adopting a boundary-first resolution strategy. All task-scoped tools now resolve `tag` and `projectRoot` at their entry point and forward these values to the underlying direct functions. This approach centralizes context logic, ensuring consistent behavior and enhanced flexibility in multi-tag environments. * fix(tag): Clean up tag handling in task functions and sync process This commit refines the handling of the `tag` parameter across multiple functions, ensuring consistent context management. The `tag` is now passed more efficiently in `listTasksDirect`, `setTaskStatusDirect`, and `syncTasksToReadme`, improving clarity and reducing redundancy. Additionally, a TODO comment has been added in `sync-readme.js` to address future tag support enhancements. * feat(tag): Implement Boundary-First Tag Resolution for consistent tag handling This commit introduces Boundary-First Tag Resolution in the task manager, ensuring consistent and deterministic tag handling across CLI and MCP. This change resolves potential race conditions and improves the reliability of tag-specific operations. Additionally, the `expandTask` function has been updated to use the resolved tag when writing JSON, enhancing data integrity during task updates. * chore(biome): formatting * fix(expand-task): Update writeJSON call to use tag instead of resolvedTag * fix(commands): Enhance complexity report path resolution and task initialization `resolveComplexityReportPath` function to streamline output path generation based on tag context and user-defined output. - Improved clarity and maintainability of command handling by centralizing path resolution logic. * Fix: unknown currentTag * fix(task-manager): Update generateTaskFiles calls to include tag and projectRoot parameters This commit modifies the `moveTask` and `updateSubtaskById` functions to pass the `tag` and `projectRoot` parameters to the `generateTaskFiles` function. This ensures that task files are generated with the correct context when requested, enhancing consistency in task management operations. * fix(commands): Refactor tag handling and complexity report path resolution This commit updates the `registerCommands` function to utilize `taskMaster.getCurrentTag()` for consistent tag retrieval across command actions. It also enhances the initialization of `TaskMaster` by passing the tag directly, improving clarity and maintainability. The complexity report path resolution is streamlined to ensure correct file naming based on the current tag context. * fix(task-master): Update complexity report path expectations in tests This commit modifies the `initTaskMaster` test to expect a valid string for the complexity report path, ensuring it matches the expected file naming convention. This change enhances test reliability by verifying the correct output format when the path is generated. * fix(set-task-status): Enhance logging and tag resolution in task status updates This commit improves the logging output in the `registerSetTaskStatusTool` function to include the tag context when setting task statuses. It also updates the tag handling by resolving the tag using the `resolveTag` utility, ensuring that the correct tag is used when updating task statuses. Additionally, the `setTaskStatus` function is modified to remove the tag parameter from the `readJSON` and `writeJSON` calls, streamlining the data handling process. * fix(commands, expand-task, task-manager): Add complexity report option and enhance path handling This commit introduces a new `--complexity-report` option in the `registerCommands` function, allowing users to specify a custom path for the complexity report. The `expandTask` function is updated to accept the `complexityReportPath` from the context, ensuring it is utilized correctly during task expansion. Additionally, the `setTaskStatus` function now includes the `tag` parameter in the `readJSON` and `writeJSON` calls, improving task status updates with proper context. The `initTaskMaster` function is also modified to create parent directories for output paths, enhancing file handling robustness. * fix(expand-task): Add complexityReportPath to context for task expansion tests This commit updates the test for the `expandTask` function by adding the `complexityReportPath` to the context object. This change ensures that the complexity report path is correctly utilized in the test, aligning with recent enhancements to complexity report handling in the task manager. * chore: implement suggested changes * fix(parse-prd): Clarify tag parameter description for task organization Updated the documentation for the `tag` parameter in the `parse-prd.js` file to provide a clearer context on its purpose for organizing tasks into separate task lists. * Fix Inconsistent tag resolution pattern. * fix: Enhance complexity report path handling with tag support This commit updates various functions to incorporate the `tag` parameter when resolving complexity report paths. The `expandTaskDirect`, `resolveComplexityReportPath`, and related tools now utilize the current tag context, improving consistency in task management. Additionally, the complexity report path is now correctly passed through the context in the `expand-task` and `set-task-status` tools, ensuring accurate report retrieval based on the active tag. * Updated the JSDoc for the `tag` parameter in the `show-task.js` file. * Remove redundant comment on tag parameter in readJSON call * Remove unused import for getTagAwareFilePath * Add missed complexityReportPath to args for task expansion * fix(tests): Enhance research tests with tag-aware functionality This commit updates the `research.test.js` file to improve the testing of the `performResearch` function by incorporating tag-aware functionality. Key changes include mocking the `findProjectRoot` to return a valid path, enhancing the `ContextGatherer` and `FuzzyTaskSearch` mocks, and adding comprehensive tests for tag parameter handling in various scenarios. The tests now cover passing different tag values, ensuring correct behavior when tags are provided, undefined, or null, and validating the integration of tags in task discovery and context gathering processes. * Remove unused import for * fix: Refactor complexity report path handling and improve argument destructuring This commit enhances the `expandTaskDirect` function by improving the destructuring of arguments for better readability. It also updates the `analyze.js` and `analyze-task-complexity.js` files to utilize the new `resolveComplexityReportOutputPath` function, ensuring tag-aware resolution of output paths. Additionally, logging has been added to provide clarity on the report path being used. * test: Add complexity report tag isolation tests and improve path handling This commit introduces a new test file for complexity report tag isolation, ensuring that different tags maintain separate complexity reports. It enhances the existing tests in `analyze-task-complexity.test.js` by updating expectations to use `expect.stringContaining` for file paths, improving robustness against path changes. The new tests cover various scenarios, including path resolution and report generation for both master and feature tags, ensuring no cross-tag contamination occurs. * Update scripts/modules/task-manager/list-tasks.js Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update scripts/modules/task-manager/list-tasks.js Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * test(complexity-report): Fix tag slugification in filename expectations - Update mocks to use slugifyTagForFilePath for cross-platform compatibility - Replace raw tag values with slugified versions in expected filenames - Fix test expecting 'feature/user-auth-v2' to expect 'feature-user-auth-v2' - Align test with actual filename generation logic that sanitizes special chars --------- Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
@@ -16,12 +16,14 @@ import {
|
||||
* @param {string} args.tasksJsonPath - Explicit path to the tasks.json file.
|
||||
* @param {string|number} args.id - Task ID to add dependency to
|
||||
* @param {string|number} args.dependsOn - Task ID that will become a dependency
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information
|
||||
*/
|
||||
export async function addDependencyDirect(args, log) {
|
||||
// Destructure expected args
|
||||
const { tasksJsonPath, id, dependsOn } = args;
|
||||
const { tasksJsonPath, id, dependsOn, tag, projectRoot } = args;
|
||||
try {
|
||||
log.info(`Adding dependency with args: ${JSON.stringify(args)}`);
|
||||
|
||||
@@ -76,8 +78,11 @@ export async function addDependencyDirect(args, log) {
|
||||
// Enable silent mode to prevent console logs from interfering with JSON response
|
||||
enableSilentMode();
|
||||
|
||||
// Create context object
|
||||
const context = { projectRoot, tag };
|
||||
|
||||
// Call the core function using the provided path
|
||||
await addDependency(tasksPath, taskId, dependencyId);
|
||||
await addDependency(tasksPath, taskId, dependencyId, context);
|
||||
|
||||
// Restore normal logging
|
||||
disableSilentMode();
|
||||
|
||||
@@ -24,6 +24,7 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
* @param {string} [args.tasksJsonPath] - Path to the tasks.json file (resolved by tool)
|
||||
* @param {boolean} [args.research=false] - Whether to use research capabilities for task creation
|
||||
* @param {string} [args.projectRoot] - Project root path
|
||||
* @param {string} [args.tag] - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @param {Object} context - Additional context (session)
|
||||
* @returns {Promise<Object>} - Result object { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
@@ -36,7 +37,8 @@ export async function addTaskDirect(args, log, context = {}) {
|
||||
dependencies,
|
||||
priority,
|
||||
research,
|
||||
projectRoot
|
||||
projectRoot,
|
||||
tag
|
||||
} = args;
|
||||
const { session } = context; // Destructure session from context
|
||||
|
||||
@@ -121,7 +123,8 @@ export async function addTaskDirect(args, log, context = {}) {
|
||||
mcpLog,
|
||||
projectRoot,
|
||||
commandName: 'add-task',
|
||||
outputType: 'mcp'
|
||||
outputType: 'mcp',
|
||||
tag
|
||||
},
|
||||
'json', // outputFormat
|
||||
manualTaskData, // Pass the manual task data
|
||||
@@ -147,7 +150,8 @@ export async function addTaskDirect(args, log, context = {}) {
|
||||
mcpLog,
|
||||
projectRoot,
|
||||
commandName: 'add-task',
|
||||
outputType: 'mcp'
|
||||
outputType: 'mcp',
|
||||
tag
|
||||
},
|
||||
'json', // outputFormat
|
||||
null, // manualTaskData is null for AI creation
|
||||
|
||||
@@ -22,6 +22,7 @@ import { createLogWrapper } from '../../tools/utils.js'; // Import the new utili
|
||||
* @param {number} [args.from] - Starting task ID in a range to analyze
|
||||
* @param {number} [args.to] - Ending task ID in a range to analyze
|
||||
* @param {string} [args.projectRoot] - Project root path.
|
||||
* @param {string} [args.tag] - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @param {Object} [context={}] - Context object containing session data
|
||||
* @param {Object} [context.session] - MCP session object
|
||||
@@ -37,7 +38,8 @@ export async function analyzeTaskComplexityDirect(args, log, context = {}) {
|
||||
projectRoot,
|
||||
ids,
|
||||
from,
|
||||
to
|
||||
to,
|
||||
tag
|
||||
} = args;
|
||||
|
||||
const logWrapper = createLogWrapper(log);
|
||||
@@ -91,7 +93,8 @@ export async function analyzeTaskComplexityDirect(args, log, context = {}) {
|
||||
projectRoot: projectRoot, // Pass projectRoot here
|
||||
id: ids, // Pass the ids parameter to the core function as 'id'
|
||||
from: from, // Pass from parameter
|
||||
to: to // Pass to parameter
|
||||
to: to, // Pass to parameter
|
||||
tag // forward tag
|
||||
};
|
||||
// --- End Initial Checks ---
|
||||
|
||||
@@ -112,7 +115,9 @@ export async function analyzeTaskComplexityDirect(args, log, context = {}) {
|
||||
session,
|
||||
mcpLog: logWrapper,
|
||||
commandName: 'analyze-complexity',
|
||||
outputType: 'mcp'
|
||||
outputType: 'mcp',
|
||||
projectRoot,
|
||||
tag
|
||||
});
|
||||
report = coreResult.report;
|
||||
} catch (error) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import path from 'path';
|
||||
* @param {string} [args.id] - Task IDs (comma-separated) to clear subtasks from
|
||||
* @param {boolean} [args.all] - Clear subtasks from all tasks
|
||||
* @param {string} [args.tag] - Tag context to operate on (defaults to current active tag)
|
||||
* @param {string} [args.projectRoot] - Project root path (for MCP/env fallback)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>}
|
||||
*/
|
||||
@@ -80,7 +81,7 @@ export async function clearSubtasksDirect(args, log) {
|
||||
};
|
||||
}
|
||||
|
||||
const currentTag = data.tag || 'master';
|
||||
const currentTag = data.tag || tag;
|
||||
const tasks = data.tasks;
|
||||
|
||||
// If all is specified, get all task IDs
|
||||
|
||||
@@ -18,6 +18,7 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
* @param {string} [args.prompt] - Additional context to guide subtask generation
|
||||
* @param {boolean} [args.force] - Force regeneration of subtasks for tasks that already have them
|
||||
* @param {string} [args.projectRoot] - Project root path.
|
||||
* @param {string} [args.tag] - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object from FastMCP
|
||||
* @param {Object} context - Context object containing session
|
||||
* @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>}
|
||||
@@ -25,7 +26,8 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
export async function expandAllTasksDirect(args, log, context = {}) {
|
||||
const { session } = context; // Extract session
|
||||
// Destructure expected args, including projectRoot
|
||||
const { tasksJsonPath, num, research, prompt, force, projectRoot } = args;
|
||||
const { tasksJsonPath, num, research, prompt, force, projectRoot, tag } =
|
||||
args;
|
||||
|
||||
// Create logger wrapper using the utility
|
||||
const mcpLog = createLogWrapper(log);
|
||||
@@ -44,7 +46,7 @@ export async function expandAllTasksDirect(args, log, context = {}) {
|
||||
enableSilentMode(); // Enable silent mode for the core function call
|
||||
try {
|
||||
log.info(
|
||||
`Calling core expandAllTasks with args: ${JSON.stringify({ num, research, prompt, force, projectRoot })}`
|
||||
`Calling core expandAllTasks with args: ${JSON.stringify({ num, research, prompt, force, projectRoot, tag })}`
|
||||
);
|
||||
|
||||
// Parse parameters (ensure correct types)
|
||||
@@ -60,7 +62,7 @@ export async function expandAllTasksDirect(args, log, context = {}) {
|
||||
useResearch,
|
||||
additionalContext,
|
||||
forceFlag,
|
||||
{ session, mcpLog, projectRoot },
|
||||
{ session, mcpLog, projectRoot, tag },
|
||||
'json'
|
||||
);
|
||||
|
||||
|
||||
@@ -35,8 +35,17 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
export async function expandTaskDirect(args, log, context = {}) {
|
||||
const { session } = context; // Extract session
|
||||
// Destructure expected args, including projectRoot
|
||||
const { tasksJsonPath, id, num, research, prompt, force, projectRoot, tag } =
|
||||
args;
|
||||
const {
|
||||
tasksJsonPath,
|
||||
id,
|
||||
num,
|
||||
research,
|
||||
prompt,
|
||||
force,
|
||||
projectRoot,
|
||||
tag,
|
||||
complexityReportPath
|
||||
} = args;
|
||||
|
||||
// Log session root data for debugging
|
||||
log.info(
|
||||
@@ -192,6 +201,7 @@ export async function expandTaskDirect(args, log, context = {}) {
|
||||
useResearch,
|
||||
additionalContext,
|
||||
{
|
||||
complexityReportPath,
|
||||
mcpLog,
|
||||
session,
|
||||
projectRoot,
|
||||
|
||||
@@ -53,10 +53,9 @@ export async function fixDependenciesDirect(args, log) {
|
||||
// Enable silent mode to prevent console logs from interfering with JSON response
|
||||
enableSilentMode();
|
||||
|
||||
const options = { projectRoot, tag };
|
||||
// Call the original command function using the provided path and proper context
|
||||
await fixDependenciesCommand(tasksPath, {
|
||||
context: { projectRoot, tag }
|
||||
});
|
||||
await fixDependenciesCommand(tasksPath, options);
|
||||
|
||||
// Restore normal logging
|
||||
disableSilentMode();
|
||||
|
||||
@@ -13,12 +13,16 @@ import {
|
||||
* Direct function wrapper for generateTaskFiles with error handling.
|
||||
*
|
||||
* @param {Object} args - Command arguments containing tasksJsonPath and outputDir.
|
||||
* @param {string} args.tasksJsonPath - Path to the tasks.json file.
|
||||
* @param {string} args.outputDir - Path to the output directory.
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object.
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
*/
|
||||
export async function generateTaskFilesDirect(args, log) {
|
||||
// Destructure expected args
|
||||
const { tasksJsonPath, outputDir } = args;
|
||||
const { tasksJsonPath, outputDir, projectRoot, tag } = args;
|
||||
try {
|
||||
log.info(`Generating task files with args: ${JSON.stringify(args)}`);
|
||||
|
||||
@@ -51,8 +55,12 @@ export async function generateTaskFilesDirect(args, log) {
|
||||
// Enable silent mode to prevent logs from being written to stdout
|
||||
enableSilentMode();
|
||||
|
||||
// The function is synchronous despite being awaited elsewhere
|
||||
generateTaskFiles(tasksPath, resolvedOutputDir);
|
||||
// Pass projectRoot and tag so the core respects context
|
||||
generateTaskFiles(tasksPath, resolvedOutputDir, {
|
||||
projectRoot,
|
||||
tag,
|
||||
mcpLog: log
|
||||
});
|
||||
|
||||
// Restore normal logging after task generation
|
||||
disableSilentMode();
|
||||
|
||||
@@ -13,12 +13,19 @@ import {
|
||||
* Direct function wrapper for listTasks with error handling and caching.
|
||||
*
|
||||
* @param {Object} args - Command arguments (now expecting tasksJsonPath explicitly).
|
||||
* @param {string} args.tasksJsonPath - Path to the tasks.json file.
|
||||
* @param {string} args.reportPath - Path to the report file.
|
||||
* @param {string} args.status - Status of the task.
|
||||
* @param {boolean} args.withSubtasks - Whether to include subtasks.
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object.
|
||||
* @returns {Promise<Object>} - Task list result { success: boolean, data?: any, error?: { code: string, message: string } }.
|
||||
*/
|
||||
export async function listTasksDirect(args, log, context = {}) {
|
||||
// Destructure the explicit tasksJsonPath from args
|
||||
const { tasksJsonPath, reportPath, status, withSubtasks, projectRoot } = args;
|
||||
const { tasksJsonPath, reportPath, status, withSubtasks, projectRoot, tag } =
|
||||
args;
|
||||
const { session } = context;
|
||||
|
||||
if (!tasksJsonPath) {
|
||||
@@ -52,8 +59,7 @@ export async function listTasksDirect(args, log, context = {}) {
|
||||
reportPath,
|
||||
withSubtasksFilter,
|
||||
'json',
|
||||
null, // tag
|
||||
{ projectRoot, session } // context
|
||||
{ projectRoot, session, tag }
|
||||
);
|
||||
|
||||
if (!resultData || !resultData.tasks) {
|
||||
|
||||
@@ -17,12 +17,14 @@ import {
|
||||
* @param {string} args.destinationId - ID of the destination (e.g., '7' or '7.3' or '7,8,9')
|
||||
* @param {string} args.file - Alternative path to the tasks.json file
|
||||
* @param {string} args.projectRoot - Project root directory
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {boolean} args.generateFiles - Whether to regenerate task files after moving (default: true)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<{success: boolean, data?: Object, error?: Object}>}
|
||||
*/
|
||||
export async function moveTaskDirect(args, log, context = {}) {
|
||||
const { session } = context;
|
||||
const { projectRoot, tag } = args;
|
||||
|
||||
// Validate required parameters
|
||||
if (!args.sourceId) {
|
||||
@@ -73,8 +75,8 @@ export async function moveTaskDirect(args, log, context = {}) {
|
||||
args.destinationId,
|
||||
generateFiles,
|
||||
{
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
projectRoot,
|
||||
tag
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -18,12 +18,15 @@ import {
|
||||
*
|
||||
* @param {Object} args - Command arguments
|
||||
* @param {string} args.tasksJsonPath - Explicit path to the tasks.json file.
|
||||
* @param {string} args.reportPath - Path to the report file.
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<Object>} - Next task result { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
*/
|
||||
export async function nextTaskDirect(args, log, context = {}) {
|
||||
// Destructure expected args
|
||||
const { tasksJsonPath, reportPath, projectRoot } = args;
|
||||
const { tasksJsonPath, reportPath, projectRoot, tag } = args;
|
||||
const { session } = context;
|
||||
|
||||
if (!tasksJsonPath) {
|
||||
@@ -46,7 +49,7 @@ export async function nextTaskDirect(args, log, context = {}) {
|
||||
log.info(`Finding next task from ${tasksJsonPath}`);
|
||||
|
||||
// Read tasks data using the provided path
|
||||
const data = readJSON(tasksJsonPath, projectRoot);
|
||||
const data = readJSON(tasksJsonPath, projectRoot, tag);
|
||||
if (!data || !data.tasks) {
|
||||
disableSilentMode(); // Disable before return
|
||||
return {
|
||||
|
||||
@@ -20,6 +20,13 @@ import { TASKMASTER_TASKS_FILE } from '../../../../src/constants/paths.js';
|
||||
* Direct function wrapper for parsing PRD documents and generating tasks.
|
||||
*
|
||||
* @param {Object} args - Command arguments containing projectRoot, input, output, numTasks options.
|
||||
* @param {string} args.input - Path to the input PRD file.
|
||||
* @param {string} args.output - Path to the output directory.
|
||||
* @param {string} args.numTasks - Number of tasks to generate.
|
||||
* @param {boolean} args.force - Whether to force parsing.
|
||||
* @param {boolean} args.append - Whether to append to the output file.
|
||||
* @param {boolean} args.research - Whether to use research mode.
|
||||
* @param {string} args.tag - Tag context for organizing tasks into separate task lists.
|
||||
* @param {Object} log - Logger object.
|
||||
* @param {Object} context - Context object containing session data.
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
@@ -34,7 +41,8 @@ export async function parsePRDDirect(args, log, context = {}) {
|
||||
force,
|
||||
append,
|
||||
research,
|
||||
projectRoot
|
||||
projectRoot,
|
||||
tag
|
||||
} = args;
|
||||
|
||||
// Create the standard logger wrapper
|
||||
@@ -152,6 +160,7 @@ export async function parsePRDDirect(args, log, context = {}) {
|
||||
session,
|
||||
mcpLog: logWrapper,
|
||||
projectRoot,
|
||||
tag,
|
||||
force,
|
||||
append,
|
||||
research,
|
||||
|
||||
@@ -14,12 +14,14 @@ import {
|
||||
* @param {string} args.tasksJsonPath - Explicit path to the tasks.json file.
|
||||
* @param {string|number} args.id - Task ID to remove dependency from
|
||||
* @param {string|number} args.dependsOn - Task ID to remove as a dependency
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>}
|
||||
*/
|
||||
export async function removeDependencyDirect(args, log) {
|
||||
// Destructure expected args
|
||||
const { tasksJsonPath, id, dependsOn } = args;
|
||||
const { tasksJsonPath, id, dependsOn, projectRoot, tag } = args;
|
||||
try {
|
||||
log.info(`Removing dependency with args: ${JSON.stringify(args)}`);
|
||||
|
||||
@@ -75,7 +77,10 @@ export async function removeDependencyDirect(args, log) {
|
||||
enableSilentMode();
|
||||
|
||||
// Call the core function using the provided tasksPath
|
||||
await removeDependency(tasksPath, taskId, dependencyId);
|
||||
await removeDependency(tasksPath, taskId, dependencyId, {
|
||||
projectRoot,
|
||||
tag
|
||||
});
|
||||
|
||||
// Restore normal logging
|
||||
disableSilentMode();
|
||||
|
||||
@@ -15,12 +15,14 @@ import {
|
||||
* @param {string} args.id - Subtask ID in format "parentId.subtaskId" (required)
|
||||
* @param {boolean} [args.convert] - Whether to convert the subtask to a standalone task
|
||||
* @param {boolean} [args.skipGenerate] - Skip regenerating task files
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>}
|
||||
*/
|
||||
export async function removeSubtaskDirect(args, log) {
|
||||
// Destructure expected args
|
||||
const { tasksJsonPath, id, convert, skipGenerate } = args;
|
||||
const { tasksJsonPath, id, convert, skipGenerate, projectRoot, tag } = args;
|
||||
try {
|
||||
// Enable silent mode to prevent console logs from interfering with JSON response
|
||||
enableSilentMode();
|
||||
@@ -82,7 +84,11 @@ export async function removeSubtaskDirect(args, log) {
|
||||
tasksPath,
|
||||
id,
|
||||
convertToTask,
|
||||
generateFiles
|
||||
generateFiles,
|
||||
{
|
||||
projectRoot,
|
||||
tag
|
||||
}
|
||||
);
|
||||
|
||||
// Restore normal logging
|
||||
|
||||
@@ -20,7 +20,8 @@ import {
|
||||
* @param {Object} args - Command arguments
|
||||
* @param {string} args.tasksJsonPath - Explicit path to the tasks.json file.
|
||||
* @param {string} args.id - The ID(s) of the task(s) or subtask(s) to remove (comma-separated for multiple).
|
||||
* @param {string} [args.tag] - Tag context to operate on (defaults to current active tag).
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<Object>} - Remove task result { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
*/
|
||||
@@ -117,7 +118,7 @@ export async function removeTaskDirect(args, log, context = {}) {
|
||||
removedTasks: result.removedTasks,
|
||||
message: result.message,
|
||||
tasksPath: tasksJsonPath,
|
||||
tag: data.tag || tag || 'master'
|
||||
tag
|
||||
}
|
||||
};
|
||||
} finally {
|
||||
|
||||
@@ -24,6 +24,7 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
* @param {string} [args.saveTo] - Automatically save to task/subtask ID (e.g., "15" or "15.2")
|
||||
* @param {boolean} [args.saveToFile=false] - Save research results to .taskmaster/docs/research/ directory
|
||||
* @param {string} [args.projectRoot] - Project root path
|
||||
* @param {string} [args.tag] - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @param {Object} context - Additional context (session)
|
||||
* @returns {Promise<Object>} - Result object { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
@@ -39,7 +40,8 @@ export async function researchDirect(args, log, context = {}) {
|
||||
detailLevel = 'medium',
|
||||
saveTo,
|
||||
saveToFile = false,
|
||||
projectRoot
|
||||
projectRoot,
|
||||
tag
|
||||
} = args;
|
||||
const { session } = context; // Destructure session from context
|
||||
|
||||
@@ -111,6 +113,7 @@ export async function researchDirect(args, log, context = {}) {
|
||||
includeProjectTree,
|
||||
detailLevel,
|
||||
projectRoot,
|
||||
tag,
|
||||
saveToFile
|
||||
};
|
||||
|
||||
@@ -169,7 +172,8 @@ ${result.result}`;
|
||||
mcpLog,
|
||||
commandName: 'research-save',
|
||||
outputType: 'mcp',
|
||||
projectRoot
|
||||
projectRoot,
|
||||
tag
|
||||
},
|
||||
'json'
|
||||
);
|
||||
@@ -200,7 +204,8 @@ ${result.result}`;
|
||||
mcpLog,
|
||||
commandName: 'research-save',
|
||||
outputType: 'mcp',
|
||||
projectRoot
|
||||
projectRoot,
|
||||
tag
|
||||
},
|
||||
'json',
|
||||
true // appendMode = true
|
||||
|
||||
@@ -14,6 +14,11 @@ import { nextTaskDirect } from './next-task.js';
|
||||
* Direct function wrapper for setTaskStatus with error handling.
|
||||
*
|
||||
* @param {Object} args - Command arguments containing id, status, tasksJsonPath, and projectRoot.
|
||||
* @param {string} args.id - The ID of the task to update.
|
||||
* @param {string} args.status - The new status to set for the task.
|
||||
* @param {string} args.tasksJsonPath - Path to the tasks.json file.
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object.
|
||||
* @param {Object} context - Additional context (session)
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
@@ -70,17 +75,12 @@ export async function setTaskStatusDirect(args, log, context = {}) {
|
||||
enableSilentMode(); // Enable silent mode before calling core function
|
||||
try {
|
||||
// Call the core function
|
||||
await setTaskStatus(
|
||||
tasksPath,
|
||||
taskId,
|
||||
newStatus,
|
||||
{
|
||||
mcpLog: log,
|
||||
projectRoot,
|
||||
session
|
||||
},
|
||||
await setTaskStatus(tasksPath, taskId, newStatus, {
|
||||
mcpLog: log,
|
||||
projectRoot,
|
||||
session,
|
||||
tag
|
||||
);
|
||||
});
|
||||
|
||||
log.info(`Successfully set task ${taskId} status to ${newStatus}`);
|
||||
|
||||
@@ -103,7 +103,8 @@ export async function setTaskStatusDirect(args, log, context = {}) {
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
reportPath: complexityReportPath,
|
||||
projectRoot: projectRoot
|
||||
projectRoot: projectRoot,
|
||||
tag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -19,6 +19,7 @@ import { findTasksPath } from '../utils/path-utils.js';
|
||||
* @param {string} args.reportPath - Explicit path to the complexity report file.
|
||||
* @param {string} [args.status] - Optional status to filter subtasks by.
|
||||
* @param {string} args.projectRoot - Absolute path to the project root directory (already normalized by tool).
|
||||
* @param {string} [args.tag] - Tag for the task
|
||||
* @param {Object} log - Logger object.
|
||||
* @param {Object} context - Context object containing session data.
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
@@ -26,7 +27,7 @@ import { findTasksPath } from '../utils/path-utils.js';
|
||||
export async function showTaskDirect(args, log) {
|
||||
// This function doesn't need session context since it only reads data
|
||||
// Destructure projectRoot and other args. projectRoot is assumed normalized.
|
||||
const { id, file, reportPath, status, projectRoot } = args;
|
||||
const { id, file, reportPath, status, projectRoot, tag } = args;
|
||||
|
||||
log.info(
|
||||
`Showing task direct function. ID: ${id}, File: ${file}, Status Filter: ${status}, ProjectRoot: ${projectRoot}`
|
||||
@@ -55,7 +56,7 @@ export async function showTaskDirect(args, log) {
|
||||
|
||||
// --- Rest of the function remains the same, using tasksJsonPath ---
|
||||
try {
|
||||
const tasksData = readJSON(tasksJsonPath, projectRoot);
|
||||
const tasksData = readJSON(tasksJsonPath, projectRoot, tag);
|
||||
if (!tasksData || !tasksData.tasks) {
|
||||
return {
|
||||
success: false,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
* @param {string} args.prompt - Information to append to the subtask.
|
||||
* @param {boolean} [args.research] - Whether to use research role.
|
||||
* @param {string} [args.projectRoot] - Project root path.
|
||||
* @param {string} [args.tag] - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object.
|
||||
* @param {Object} context - Context object containing session data.
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
@@ -27,7 +28,7 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
export async function updateSubtaskByIdDirect(args, log, context = {}) {
|
||||
const { session } = context;
|
||||
// Destructure expected args, including projectRoot
|
||||
const { tasksJsonPath, id, prompt, research, projectRoot } = args;
|
||||
const { tasksJsonPath, id, prompt, research, projectRoot, tag } = args;
|
||||
|
||||
const logWrapper = createLogWrapper(log);
|
||||
|
||||
@@ -112,6 +113,7 @@ export async function updateSubtaskByIdDirect(args, log, context = {}) {
|
||||
mcpLog: logWrapper,
|
||||
session,
|
||||
projectRoot,
|
||||
tag,
|
||||
commandName: 'update-subtask',
|
||||
outputType: 'mcp'
|
||||
},
|
||||
|
||||
@@ -21,6 +21,7 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
* @param {boolean} [args.research] - Whether to use research role.
|
||||
* @param {boolean} [args.append] - Whether to append timestamped information instead of full update.
|
||||
* @param {string} [args.projectRoot] - Project root path.
|
||||
* @param {string} [args.tag] - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object.
|
||||
* @param {Object} context - Context object containing session data.
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
@@ -28,7 +29,8 @@ import { createLogWrapper } from '../../tools/utils.js';
|
||||
export async function updateTaskByIdDirect(args, log, context = {}) {
|
||||
const { session } = context;
|
||||
// Destructure expected args, including projectRoot
|
||||
const { tasksJsonPath, id, prompt, research, append, projectRoot } = args;
|
||||
const { tasksJsonPath, id, prompt, research, append, projectRoot, tag } =
|
||||
args;
|
||||
|
||||
const logWrapper = createLogWrapper(log);
|
||||
|
||||
@@ -116,6 +118,7 @@ export async function updateTaskByIdDirect(args, log, context = {}) {
|
||||
mcpLog: logWrapper,
|
||||
session,
|
||||
projectRoot,
|
||||
tag,
|
||||
commandName: 'update-task',
|
||||
outputType: 'mcp'
|
||||
},
|
||||
|
||||
@@ -15,6 +15,12 @@ import {
|
||||
* Direct function wrapper for updating tasks based on new context.
|
||||
*
|
||||
* @param {Object} args - Command arguments containing projectRoot, from, prompt, research options.
|
||||
* @param {string} args.from - The ID of the task to update.
|
||||
* @param {string} args.prompt - The prompt to update the task with.
|
||||
* @param {boolean} args.research - Whether to use research mode.
|
||||
* @param {string} args.tasksJsonPath - Path to the tasks.json file.
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object.
|
||||
* @param {Object} context - Context object containing session data.
|
||||
* @returns {Promise<Object>} - Result object with success status and data/error information.
|
||||
|
||||
@@ -13,12 +13,14 @@ import fs from 'fs';
|
||||
* Validate dependencies in tasks.json
|
||||
* @param {Object} args - Function arguments
|
||||
* @param {string} args.tasksJsonPath - Explicit path to the tasks.json file.
|
||||
* @param {string} args.projectRoot - Project root path (for MCP/env fallback)
|
||||
* @param {string} args.tag - Tag for the task (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @returns {Promise<{success: boolean, data?: Object, error?: {code: string, message: string}}>}
|
||||
*/
|
||||
export async function validateDependenciesDirect(args, log) {
|
||||
// Destructure the explicit tasksJsonPath
|
||||
const { tasksJsonPath } = args;
|
||||
const { tasksJsonPath, projectRoot, tag } = args;
|
||||
|
||||
if (!tasksJsonPath) {
|
||||
log.error('validateDependenciesDirect called without tasksJsonPath');
|
||||
@@ -51,8 +53,9 @@ export async function validateDependenciesDirect(args, log) {
|
||||
// Enable silent mode to prevent console logs from interfering with JSON response
|
||||
enableSilentMode();
|
||||
|
||||
const options = { projectRoot, tag };
|
||||
// Call the original command function using the provided tasksPath
|
||||
await validateDependenciesCommand(tasksPath);
|
||||
await validateDependenciesCommand(tasksPath, options);
|
||||
|
||||
// Restore normal logging
|
||||
disableSilentMode();
|
||||
|
||||
@@ -121,6 +121,7 @@ export function resolveComplexityReportPath(args, log = silentLogger) {
|
||||
// Get explicit path from args.complexityReport if provided
|
||||
const explicitPath = args?.complexityReport;
|
||||
const rawProjectRoot = args?.projectRoot;
|
||||
const tag = args?.tag;
|
||||
|
||||
// If explicit path is provided and absolute, use it directly
|
||||
if (explicitPath && path.isAbsolute(explicitPath)) {
|
||||
@@ -139,7 +140,11 @@ export function resolveComplexityReportPath(args, log = silentLogger) {
|
||||
|
||||
// Use core findComplexityReportPath with explicit path and normalized projectRoot context
|
||||
if (projectRoot) {
|
||||
return coreFindComplexityReportPath(explicitPath, { projectRoot }, log);
|
||||
return coreFindComplexityReportPath(
|
||||
explicitPath,
|
||||
{ projectRoot, tag },
|
||||
log
|
||||
);
|
||||
}
|
||||
|
||||
// Fallback to core function without projectRoot context
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { addDependencyDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the addDependency tool with the MCP server
|
||||
@@ -33,14 +34,18 @@ export function registerAddDependencyTool(server) {
|
||||
),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
log.info(
|
||||
`Adding dependency for task ${args.id} to depend on ${args.dependsOn}`
|
||||
);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
tasksJsonPath = findTasksPath(
|
||||
@@ -61,7 +66,9 @@ export function registerAddDependencyTool(server) {
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
// Pass other relevant args
|
||||
id: args.id,
|
||||
dependsOn: args.dependsOn
|
||||
dependsOn: args.dependsOn,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
// Remove context object
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { addSubtaskDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the addSubtask tool with the MCP server
|
||||
@@ -52,17 +53,21 @@ export function registerAddSubtaskTool(server) {
|
||||
.describe(
|
||||
'Absolute path to the tasks file (default: tasks/tasks.json)'
|
||||
),
|
||||
tag: z.string().optional().describe('Tag context to operate on'),
|
||||
skipGenerate: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.describe('Skip regenerating task files'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(`Adding subtask with args: ${JSON.stringify(args)}`);
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
@@ -91,7 +96,7 @@ export function registerAddSubtaskTool(server) {
|
||||
dependencies: args.dependencies,
|
||||
skipGenerate: args.skipGenerate,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { addTaskDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the addTask tool with the MCP server
|
||||
@@ -58,6 +59,7 @@ export function registerAddTaskTool(server) {
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on'),
|
||||
research: z
|
||||
.boolean()
|
||||
.optional()
|
||||
@@ -67,6 +69,11 @@ export function registerAddTaskTool(server) {
|
||||
try {
|
||||
log.info(`Starting add-task with args: ${JSON.stringify(args)}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -93,7 +100,8 @@ export function registerAddTaskTool(server) {
|
||||
dependencies: args.dependencies,
|
||||
priority: args.priority,
|
||||
research: args.research,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -13,7 +13,9 @@ import {
|
||||
} from './utils.js';
|
||||
import { analyzeTaskComplexityDirect } from '../core/task-master-core.js'; // Assuming core functions are exported via task-master-core.js
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
import { COMPLEXITY_REPORT_FILE } from '../../../src/constants/paths.js';
|
||||
import { resolveComplexityReportOutputPath } from '../../../src/utils/path-utils.js';
|
||||
|
||||
/**
|
||||
* Register the analyze_project_complexity tool
|
||||
@@ -70,15 +72,22 @@ export function registerAnalyzeProjectComplexityTool(server) {
|
||||
.describe('Ending task ID in a range to analyze.'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
const toolName = 'analyze_project_complexity'; // Define tool name for logging
|
||||
|
||||
try {
|
||||
log.info(
|
||||
`Executing ${toolName} tool with args: ${JSON.stringify(args)}`
|
||||
);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
tasksJsonPath = findTasksPath(
|
||||
@@ -93,9 +102,14 @@ export function registerAnalyzeProjectComplexityTool(server) {
|
||||
);
|
||||
}
|
||||
|
||||
const outputPath = args.output
|
||||
? path.resolve(args.projectRoot, args.output)
|
||||
: path.resolve(args.projectRoot, COMPLEXITY_REPORT_FILE);
|
||||
const outputPath = resolveComplexityReportOutputPath(
|
||||
args.output,
|
||||
{
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
);
|
||||
|
||||
log.info(`${toolName}: Report output path: ${outputPath}`);
|
||||
|
||||
@@ -123,6 +137,7 @@ export function registerAnalyzeProjectComplexityTool(server) {
|
||||
threshold: args.threshold,
|
||||
research: args.research,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag,
|
||||
ids: args.ids,
|
||||
from: args.from,
|
||||
to: args.to
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { clearSubtasksDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the clearSubtasks tool with the MCP server
|
||||
@@ -46,6 +47,11 @@ export function registerClearSubtasksTool(server) {
|
||||
try {
|
||||
log.info(`Clearing subtasks with args: ${JSON.stringify(args)}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -65,8 +71,9 @@ export function registerClearSubtasksTool(server) {
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
id: args.id,
|
||||
all: args.all,
|
||||
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag || 'master'
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
import { complexityReportDirect } from '../core/task-master-core.js';
|
||||
import { COMPLEXITY_REPORT_FILE } from '../../../src/constants/paths.js';
|
||||
import { findComplexityReportPath } from '../core/utils/path-utils.js';
|
||||
import { getCurrentTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the complexityReport tool with the MCP server
|
||||
@@ -38,12 +39,16 @@ export function registerComplexityReportTool(server) {
|
||||
`Getting complexity report with args: ${JSON.stringify(args)}`
|
||||
);
|
||||
|
||||
const resolvedTag = getCurrentTag(args.projectRoot);
|
||||
|
||||
const pathArgs = {
|
||||
projectRoot: args.projectRoot,
|
||||
complexityReport: args.file
|
||||
complexityReport: args.file,
|
||||
tag: resolvedTag
|
||||
};
|
||||
|
||||
const reportPath = findComplexityReportPath(pathArgs, log);
|
||||
log.info('Reading complexity report from path: ', reportPath);
|
||||
|
||||
if (!reportPath) {
|
||||
return createErrorResponse(
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { expandAllTasksDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the expandAll tool with the MCP server
|
||||
@@ -57,7 +58,8 @@ export function registerExpandAllTool(server) {
|
||||
.optional()
|
||||
.describe(
|
||||
'Absolute path to the project root directory (derived from session if possible)'
|
||||
)
|
||||
),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
@@ -65,6 +67,10 @@ export function registerExpandAllTool(server) {
|
||||
`Tool expand_all execution started with args: ${JSON.stringify(args)}`
|
||||
);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
tasksJsonPath = findTasksPath(
|
||||
@@ -86,7 +92,8 @@ export function registerExpandAllTool(server) {
|
||||
research: args.research,
|
||||
prompt: args.prompt,
|
||||
force: args.force,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -10,7 +10,11 @@ import {
|
||||
withNormalizedProjectRoot
|
||||
} from './utils.js';
|
||||
import { expandTaskDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import {
|
||||
findTasksPath,
|
||||
findComplexityReportPath
|
||||
} from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the expand-task tool with the MCP server
|
||||
@@ -51,7 +55,10 @@ export function registerExpandTaskTool(server) {
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
log.info(`Starting expand-task with args: ${JSON.stringify(args)}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -66,6 +73,11 @@ export function registerExpandTaskTool(server) {
|
||||
);
|
||||
}
|
||||
|
||||
const complexityReportPath = findComplexityReportPath(
|
||||
{ ...args, tag: resolvedTag },
|
||||
log
|
||||
);
|
||||
|
||||
const result = await expandTaskDirect(
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
@@ -74,8 +86,9 @@ export function registerExpandTaskTool(server) {
|
||||
research: args.research,
|
||||
prompt: args.prompt,
|
||||
force: args.force,
|
||||
complexityReportPath,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag || 'master'
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { fixDependenciesDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
/**
|
||||
* Register the fixDependencies tool with the MCP server
|
||||
* @param {Object} server - FastMCP server instance
|
||||
@@ -31,6 +31,11 @@ export function registerFixDependenciesTool(server) {
|
||||
try {
|
||||
log.info(`Fixing dependencies with args: ${JSON.stringify(args)}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -49,7 +54,7 @@ export function registerFixDependenciesTool(server) {
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { generateTaskFilesDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
@@ -30,12 +31,17 @@ export function registerGenerateTool(server) {
|
||||
.describe('Output directory (default: same directory as tasks file)'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
log.info(`Generating task files with args: ${JSON.stringify(args)}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -58,7 +64,8 @@ export function registerGenerateTool(server) {
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
outputDir: outputDir,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
findTasksPath,
|
||||
findComplexityReportPath
|
||||
} from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Custom processor function that removes allTasks from the response
|
||||
@@ -67,7 +68,8 @@ export function registerShowTaskTool(server) {
|
||||
.string()
|
||||
.describe(
|
||||
'Absolute path to the project root directory (Optional, usually from session)'
|
||||
)
|
||||
),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
const { id, file, status, projectRoot } = args;
|
||||
@@ -76,6 +78,10 @@ export function registerShowTaskTool(server) {
|
||||
log.info(
|
||||
`Getting task details for ID: ${id}${status ? ` (filtering subtasks by status: ${status})` : ''} in root: ${projectRoot}`
|
||||
);
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
// Resolve the path to tasks.json using the NORMALIZED projectRoot from args
|
||||
let tasksJsonPath;
|
||||
@@ -99,7 +105,8 @@ export function registerShowTaskTool(server) {
|
||||
complexityReportPath = findComplexityReportPath(
|
||||
{
|
||||
projectRoot: projectRoot,
|
||||
complexityReport: args.complexityReport
|
||||
complexityReport: args.complexityReport,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
);
|
||||
@@ -113,7 +120,8 @@ export function registerShowTaskTool(server) {
|
||||
// Pass other relevant args
|
||||
id: id,
|
||||
status: status,
|
||||
projectRoot: projectRoot
|
||||
projectRoot: projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -15,6 +15,8 @@ import {
|
||||
resolveComplexityReportPath
|
||||
} from '../core/utils/path-utils.js';
|
||||
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the getTasks tool with the MCP server
|
||||
* @param {Object} server - FastMCP server instance
|
||||
@@ -51,12 +53,17 @@ export function registerListTasksTool(server) {
|
||||
),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
log.info(`Getting tasks with filters: ${JSON.stringify(args)}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
// Resolve the path to tasks.json using new path utilities
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -71,7 +78,10 @@ export function registerListTasksTool(server) {
|
||||
// Resolve the path to complexity report
|
||||
let complexityReportPath;
|
||||
try {
|
||||
complexityReportPath = resolveComplexityReportPath(args, session);
|
||||
complexityReportPath = resolveComplexityReportPath(
|
||||
{ ...args, tag: resolvedTag },
|
||||
session
|
||||
);
|
||||
} catch (error) {
|
||||
log.error(`Error finding complexity report: ${error.message}`);
|
||||
// This is optional, so we don't fail the operation
|
||||
@@ -84,7 +94,8 @@ export function registerListTasksTool(server) {
|
||||
status: args.status,
|
||||
withSubtasks: args.withSubtasks,
|
||||
reportPath: complexityReportPath,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { moveTaskDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the moveTask tool with the MCP server
|
||||
@@ -36,10 +37,15 @@ export function registerMoveTaskTool(server) {
|
||||
.string()
|
||||
.describe(
|
||||
'Root directory of the project (typically derived from session)'
|
||||
)
|
||||
),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
// Find tasks.json path if not provided
|
||||
let tasksJsonPath = args.file;
|
||||
|
||||
@@ -79,7 +85,8 @@ export function registerMoveTaskTool(server) {
|
||||
sourceId: fromId,
|
||||
destinationId: toId,
|
||||
tasksJsonPath,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
@@ -115,7 +122,8 @@ export function registerMoveTaskTool(server) {
|
||||
sourceId: args.from,
|
||||
destinationId: args.to,
|
||||
tasksJsonPath,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
resolveTasksPath,
|
||||
resolveComplexityReportPath
|
||||
} from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the nextTask tool with the MCP server
|
||||
@@ -34,11 +35,16 @@ export function registerNextTaskTool(server) {
|
||||
),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
log.info(`Finding next task with args: ${JSON.stringify(args)}`);
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
// Resolve the path to tasks.json using new path utilities
|
||||
let tasksJsonPath;
|
||||
@@ -54,7 +60,10 @@ export function registerNextTaskTool(server) {
|
||||
// Resolve the path to complexity report (optional)
|
||||
let complexityReportPath;
|
||||
try {
|
||||
complexityReportPath = resolveComplexityReportPath(args, session);
|
||||
complexityReportPath = resolveComplexityReportPath(
|
||||
{ ...args, tag: resolvedTag },
|
||||
session
|
||||
);
|
||||
} catch (error) {
|
||||
log.error(`Error finding complexity report: ${error.message}`);
|
||||
// This is optional, so we don't fail the operation
|
||||
@@ -65,7 +74,8 @@ export function registerNextTaskTool(server) {
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
reportPath: complexityReportPath,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
TASKMASTER_DOCS_DIR,
|
||||
TASKMASTER_TASKS_FILE
|
||||
} from '../../../src/constants/paths.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the parse_prd tool
|
||||
@@ -24,6 +25,7 @@ export function registerParsePRDTool(server) {
|
||||
server.addTool({
|
||||
name: 'parse_prd',
|
||||
description: `Parse a Product Requirements Document (PRD) text file to automatically generate initial tasks. Reinitializing the project is not necessary to run this tool. It is recommended to run parse-prd after initializing the project and creating/importing a prd.txt file in the project root's ${TASKMASTER_DOCS_DIR} directory.`,
|
||||
|
||||
parameters: z.object({
|
||||
input: z
|
||||
.string()
|
||||
@@ -33,6 +35,7 @@ export function registerParsePRDTool(server) {
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on'),
|
||||
output: z
|
||||
.string()
|
||||
.optional()
|
||||
@@ -63,7 +66,18 @@ export function registerParsePRDTool(server) {
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const result = await parsePRDDirect(args, log, { session });
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
const result = await parsePRDDirect(
|
||||
{
|
||||
...args,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
);
|
||||
return handleApiResult(
|
||||
result,
|
||||
log,
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { removeDependencyDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the removeDependency tool with the MCP server
|
||||
@@ -31,10 +32,15 @@ export function registerRemoveDependencyTool(server) {
|
||||
),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(
|
||||
`Removing dependency for task ${args.id} from ${args.dependsOn} with args: ${JSON.stringify(args)}`
|
||||
);
|
||||
@@ -57,7 +63,9 @@ export function registerRemoveDependencyTool(server) {
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
id: args.id,
|
||||
dependsOn: args.dependsOn
|
||||
dependsOn: args.dependsOn,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { removeSubtaskDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the removeSubtask tool with the MCP server
|
||||
@@ -44,10 +45,15 @@ export function registerRemoveSubtaskTool(server) {
|
||||
.describe('Skip regenerating task files'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(`Removing subtask with args: ${JSON.stringify(args)}`);
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
@@ -70,7 +76,8 @@ export function registerRemoveSubtaskTool(server) {
|
||||
id: args.id,
|
||||
convert: args.convert,
|
||||
skipGenerate: args.skipGenerate,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { removeTaskDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the remove-task tool with the MCP server
|
||||
@@ -45,6 +46,11 @@ export function registerRemoveTaskTool(server) {
|
||||
try {
|
||||
log.info(`Removing task(s) with ID(s): ${args.id}`);
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -66,7 +72,7 @@ export function registerRemoveTaskTool(server) {
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
id: args.id,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
withNormalizedProjectRoot
|
||||
} from './utils.js';
|
||||
import { researchDirect } from '../core/task-master-core.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the research tool with the MCP server
|
||||
@@ -19,6 +20,7 @@ export function registerResearchTool(server) {
|
||||
server.addTool({
|
||||
name: 'research',
|
||||
description: 'Perform AI-powered research queries with project context',
|
||||
|
||||
parameters: z.object({
|
||||
query: z.string().describe('Research query/prompt (required)'),
|
||||
taskIds: z
|
||||
@@ -61,10 +63,15 @@ export function registerResearchTool(server) {
|
||||
),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(
|
||||
`Starting research with query: "${args.query.substring(0, 100)}${args.query.length > 100 ? '...' : ''}"`
|
||||
);
|
||||
@@ -80,7 +87,8 @@ export function registerResearchTool(server) {
|
||||
detailLevel: args.detailLevel || 'medium',
|
||||
saveTo: args.saveTo,
|
||||
saveToFile: args.saveToFile || false,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
findComplexityReportPath
|
||||
} from '../core/utils/path-utils.js';
|
||||
import { TASK_STATUS_OPTIONS } from '../../../src/constants/task-status.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the setTaskStatus tool with the MCP server
|
||||
@@ -52,8 +53,15 @@ export function registerSetTaskStatusTool(server) {
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
log.info(`Setting status of task(s) ${args.id} to: ${args.status}`);
|
||||
|
||||
log.info(
|
||||
`Setting status of task(s) ${args.id} to: ${args.status} ${
|
||||
args.tag ? `in tag: ${args.tag}` : 'in current tag'
|
||||
}`
|
||||
);
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
let tasksJsonPath;
|
||||
try {
|
||||
@@ -73,7 +81,8 @@ export function registerSetTaskStatusTool(server) {
|
||||
complexityReportPath = findComplexityReportPath(
|
||||
{
|
||||
projectRoot: args.projectRoot,
|
||||
complexityReport: args.complexityReport
|
||||
complexityReport: args.complexityReport,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
);
|
||||
@@ -88,7 +97,7 @@ export function registerSetTaskStatusTool(server) {
|
||||
status: args.status,
|
||||
complexityReportPath,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { updateSubtaskByIdDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the update-subtask tool with the MCP server
|
||||
@@ -35,11 +36,17 @@ export function registerUpdateSubtaskTool(server) {
|
||||
file: z.string().optional().describe('Absolute path to the tasks file'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
const toolName = 'update_subtask';
|
||||
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(`Updating subtask with args: ${JSON.stringify(args)}`);
|
||||
|
||||
let tasksJsonPath;
|
||||
@@ -61,7 +68,8 @@ export function registerUpdateSubtaskTool(server) {
|
||||
id: args.id,
|
||||
prompt: args.prompt,
|
||||
research: args.research,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { updateTaskByIdDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the update-task tool with the MCP server
|
||||
@@ -43,11 +44,16 @@ export function registerUpdateTaskTool(server) {
|
||||
file: z.string().optional().describe('Absolute path to the tasks file'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
const toolName = 'update_task';
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(
|
||||
`Executing ${toolName} tool with args: ${JSON.stringify(args)}`
|
||||
);
|
||||
@@ -74,7 +80,8 @@ export function registerUpdateTaskTool(server) {
|
||||
prompt: args.prompt,
|
||||
research: args.research,
|
||||
append: args.append,
|
||||
projectRoot: args.projectRoot
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { updateTasksDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the update tool with the MCP server
|
||||
@@ -50,6 +51,11 @@ export function registerUpdateTool(server) {
|
||||
const toolName = 'update';
|
||||
const { from, prompt, research, file, projectRoot, tag } = args;
|
||||
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
|
||||
try {
|
||||
log.info(
|
||||
`Executing ${toolName} tool with normalized root: ${projectRoot}`
|
||||
@@ -73,7 +79,7 @@ export function registerUpdateTool(server) {
|
||||
prompt: prompt,
|
||||
research: research,
|
||||
projectRoot: projectRoot,
|
||||
tag: tag
|
||||
tag: resolvedTag
|
||||
},
|
||||
log,
|
||||
{ session }
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
} from './utils.js';
|
||||
import { validateDependenciesDirect } from '../core/task-master-core.js';
|
||||
import { findTasksPath } from '../core/utils/path-utils.js';
|
||||
import { resolveTag } from '../../../scripts/modules/utils.js';
|
||||
|
||||
/**
|
||||
* Register the validateDependencies tool with the MCP server
|
||||
@@ -25,10 +26,15 @@ export function registerValidateDependenciesTool(server) {
|
||||
file: z.string().optional().describe('Absolute path to the tasks file'),
|
||||
projectRoot: z
|
||||
.string()
|
||||
.describe('The directory of the project. Must be an absolute path.')
|
||||
.describe('The directory of the project. Must be an absolute path.'),
|
||||
tag: z.string().optional().describe('Tag context to operate on')
|
||||
}),
|
||||
execute: withNormalizedProjectRoot(async (args, { log, session }) => {
|
||||
try {
|
||||
const resolvedTag = resolveTag({
|
||||
projectRoot: args.projectRoot,
|
||||
tag: args.tag
|
||||
});
|
||||
log.info(`Validating dependencies with args: ${JSON.stringify(args)}`);
|
||||
|
||||
// Use args.projectRoot directly (guaranteed by withNormalizedProjectRoot)
|
||||
@@ -47,7 +53,9 @@ export function registerValidateDependenciesTool(server) {
|
||||
|
||||
const result = await validateDependenciesDirect(
|
||||
{
|
||||
tasksJsonPath: tasksJsonPath
|
||||
tasksJsonPath: tasksJsonPath,
|
||||
projectRoot: args.projectRoot,
|
||||
tag: resolvedTag
|
||||
},
|
||||
log
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user