Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions mcp-server/src/core/direct-functions/add-dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,9 @@ export async function addDependencyDirect(args, log) {
// Use provided path
const tasksPath = tasksJsonPath;

// Format IDs for the core function
const taskId =
id && id.includes && id.includes('.') ? id : parseInt(id, 10);
const dependencyId =
dependsOn && dependsOn.includes && dependsOn.includes('.')
? dependsOn
: parseInt(dependsOn, 10);
// Pass raw IDs (supporting ranges/lists and dot notation)
const taskId = id;
const dependencyId = dependsOn;

log.info(
`Adding dependency: task ${taskId} will depend on ${dependencyId}`
Expand Down
10 changes: 3 additions & 7 deletions mcp-server/src/core/direct-functions/remove-dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,9 @@ export async function removeDependencyDirect(args, log) {
// Use provided path
const tasksPath = tasksJsonPath;

// Format IDs for the core function
const taskId =
id && id.includes && id.includes('.') ? id : parseInt(id, 10);
const dependencyId =
dependsOn && dependsOn.includes && dependsOn.includes('.')
? dependsOn
: parseInt(dependsOn, 10);
// Preserve raw IDs for bulk operations (ranges and comma-separated lists)
const taskId = id;
const dependencyId = dependsOn;

log.info(
`Removing dependency: task ${taskId} no longer depends on ${dependencyId}`
Expand Down
13 changes: 10 additions & 3 deletions mcp-server/src/tools/add-dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,19 @@ import { resolveTag } from '../../../scripts/modules/utils.js';
export function registerAddDependencyTool(server) {
server.addTool({
name: 'add_dependency',
description: 'Add a dependency relationship between two tasks',
description:
'Add dependencies to task(s). Supports ranges and comma-separated lists (e.g., id="7-10", dependsOn="1-5").',
parameters: z.object({
id: z.string().describe('ID of task that will depend on another task'),
id: z
.string()
.describe(
'Task ID(s) that will depend on others (e.g., "7", "7-10", "7,8,9")'
),
dependsOn: z
.string()
.describe('ID of task that will become a dependency'),
.describe(
'Task ID(s) that will become dependencies (e.g., "1", "1-5", "1,3,5")'
),
file: z
.string()
.optional()
Expand Down
15 changes: 12 additions & 3 deletions mcp-server/src/tools/remove-dependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,19 @@ import { resolveTag } from '../../../scripts/modules/utils.js';
export function registerRemoveDependencyTool(server) {
server.addTool({
name: 'remove_dependency',
description: 'Remove a dependency from a task',
description:
'Remove dependencies from task(s). Supports ranges and comma-separated lists (e.g., id="7-10", dependsOn="1-5").',
parameters: z.object({
id: z.string().describe('Task ID to remove dependency from'),
dependsOn: z.string().describe('Task ID to remove as a dependency'),
id: z
.string()
.describe(
'Task ID(s) to remove dependencies from (e.g., "7", "7-10", "7,8,9")'
),
dependsOn: z
.string()
.describe(
'Task ID(s) to remove as dependencies (e.g., "1", "1-5", "1,3,5")'
),
file: z
.string()
.optional()
Expand Down
74 changes: 32 additions & 42 deletions scripts/modules/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -2495,9 +2495,17 @@ ${result.result}
// add-dependency command
programInstance
.command('add-dependency')
.description('Add a dependency to a task')
.option('-i, --id <id>', 'Task ID to add dependency to')
.option('-d, --depends-on <id>', 'Task ID that will become a dependency')
.description(
'Add dependencies to task(s). Supports ranges and comma-separated lists.'
)
.option(
'-i, --id <id>',
'Task ID(s) to add dependencies to (e.g., "7", "7-10", "7,8,9")'
)
.option(
'-d, --depends-on <id>',
'Task ID(s) that will become dependencies (e.g., "1", "1-5", "1,3,5")'
)
.option(
'-f, --file <file>',
'Path to the tasks file',
Expand Down Expand Up @@ -2529,32 +2537,27 @@ ${result.result}
process.exit(1);
}

// Handle subtask IDs correctly by preserving the string format for IDs containing dots
// Only use parseInt for simple numeric IDs
const formattedTaskId = taskId.includes('.')
? taskId
: parseInt(taskId, 10);
const formattedDependencyId = dependencyId.includes('.')
? dependencyId
: parseInt(dependencyId, 10);

await addDependency(
taskMaster.getTasksPath(),
formattedTaskId,
formattedDependencyId,
{
projectRoot: taskMaster.getProjectRoot(),
tag
}
);
// Pass raw IDs (supporting ranges/lists and dot notation)
await addDependency(taskMaster.getTasksPath(), taskId, dependencyId, {
projectRoot: taskMaster.getProjectRoot(),
tag
});
});

// remove-dependency command
programInstance
.command('remove-dependency')
.description('Remove a dependency from a task')
.option('-i, --id <id>', 'Task ID to remove dependency from')
.option('-d, --depends-on <id>', 'Task ID to remove as a dependency')
.description(
'Remove dependencies from task(s). Supports ranges and comma-separated lists.'
)
.option(
'-i, --id <id>',
'Task ID(s) to remove dependencies from (e.g., "7", "7-10", "7,8,9")'
)
.option(
'-d, --depends-on <id>',
'Task ID(s) to remove as dependencies (e.g., "1", "1-5", "1,3,5")'
)
Comment on lines +2551 to +2560
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Expose dry-run in remove-dependency and propagate to core

Mirror add-dependency for removals.

 .command('remove-dependency')
 .description(
   'Remove dependencies from task(s). Supports ranges and comma-separated lists.'
 )
 .option(
   '-i, --id <id>',
   'Task ID(s) to remove dependencies from (e.g., "7", "7-10", "7,8,9")'
 )
 .option(
   '-d, --depends-on <id>',
   'Task ID(s) to remove as dependencies (e.g., "1", "1-5", "1,3,5")'
 )
+.option('--dry-run', 'Validate and show changes without writing', false)
@@
-      await removeDependency(taskMaster.getTasksPath(), taskId, dependencyId, {
-        projectRoot: taskMaster.getProjectRoot(),
-        tag
-      });
+      await removeDependency(taskMaster.getTasksPath(), taskId, dependencyId, {
+        projectRoot: taskMaster.getProjectRoot(),
+        tag,
+        dryRun: !!options.dryRun
+      });

As per coding guidelines

Also applies to: 2592-2596

🤖 Prompt for AI Agents
In scripts/modules/commands.js around lines 2551-2560 (and also apply the same
change at 2592-2596), the remove-dependency CLI command lacks the dry-run option
and doesn't propagate the flag to the core removal logic; mirror the
add-dependency implementation by adding the dry-run option (e.g., '-n,
--dry-run') to the command options and ensure the command handler accepts the
dryRun boolean and forwards it into the core removeDependency function call (or
options object) so removals can be simulated without making changes.

.option(
'-f, --file <file>',
'Path to the tasks file',
Expand Down Expand Up @@ -2586,24 +2589,11 @@ ${result.result}
process.exit(1);
}

// Handle subtask IDs correctly by preserving the string format for IDs containing dots
// Only use parseInt for simple numeric IDs
const formattedTaskId = taskId.includes('.')
? taskId
: parseInt(taskId, 10);
const formattedDependencyId = dependencyId.includes('.')
? dependencyId
: parseInt(dependencyId, 10);

await removeDependency(
taskMaster.getTasksPath(),
formattedTaskId,
formattedDependencyId,
{
projectRoot: taskMaster.getProjectRoot(),
tag
}
);
// Pass raw IDs (supporting ranges/lists and dot notation)
await removeDependency(taskMaster.getTasksPath(), taskId, dependencyId, {
projectRoot: taskMaster.getProjectRoot(),
tag
});
});

// validate-dependencies command
Expand Down
Loading