fix(commands): Add missing context parameters to dependency and remove-subtask commands

- Add projectRoot and tag context to all dependency commands
- Add projectRoot and tag context to remove-subtask command
- Add --tag option to remove-subtask command
- Fixes critical bug where remove-subtask was deleting other tags due to missing context
- All dependency and subtask commands now properly handle tagged task lists
This commit is contained in:
Eyal Toledano
2025-06-13 00:46:45 -04:00
parent cac8c234d6
commit ddaa1dceef
118 changed files with 141 additions and 17437 deletions

View File

@@ -142,7 +142,7 @@ async function addSubtask(
// Generate task files if requested
if (generateFiles) {
log('info', 'Regenerating task files...');
await generateTaskFiles(tasksPath, path.dirname(tasksPath), context);
// await generateTaskFiles(tasksPath, path.dirname(tasksPath), context);
}
return newSubtask;

View File

@@ -575,7 +575,7 @@ async function addTask(
report('Generating task files...', 'info');
report('DEBUG: Calling generateTaskFiles...', 'debug');
// Pass mcpLog if available to generateTaskFiles
await generateTaskFiles(tasksPath, path.dirname(tasksPath), { mcpLog });
// await generateTaskFiles(tasksPath, path.dirname(tasksPath), { mcpLog });
report('DEBUG: generateTaskFiles finished.', 'debug');
// Show success message - only for text output (CLI)

View File

@@ -24,7 +24,7 @@ async function moveTask(
tasksPath,
sourceId,
destinationId,
generateFiles = true,
generateFiles = false,
options = {}
) {
// Check if we have comma-separated IDs (batch move)

View File

@@ -339,7 +339,7 @@ Guidelines:
);
// Generate markdown task files after writing tasks.json
await generateTaskFiles(tasksPath, path.dirname(tasksPath), { mcpLog });
// await generateTaskFiles(tasksPath, path.dirname(tasksPath), { mcpLog });
// Handle CLI output (e.g., success message)
if (outputFormat === 'text') {

View File

@@ -8,19 +8,21 @@ import generateTaskFiles from './generate-task-files.js';
* @param {string} subtaskId - ID of the subtask to remove in format "parentId.subtaskId"
* @param {boolean} convertToTask - Whether to convert the subtask to a standalone task
* @param {boolean} generateFiles - Whether to regenerate task files after removing the subtask
* @param {Object} context - Context object containing projectRoot and tag information
* @returns {Object|null} The removed subtask if convertToTask is true, otherwise null
*/
async function removeSubtask(
tasksPath,
subtaskId,
convertToTask = false,
generateFiles = true
generateFiles = true,
context = {}
) {
try {
log('info', `Removing subtask ${subtaskId}...`);
// Read the existing tasks
const data = readJSON(tasksPath);
// Read the existing tasks with proper context
const data = readJSON(tasksPath, context.projectRoot, context.tag);
if (!data || !data.tasks) {
throw new Error(`Invalid or missing tasks file at ${tasksPath}`);
}
@@ -63,7 +65,7 @@ async function removeSubtask(
// If parent has no more subtasks, remove the subtasks array
if (parentTask.subtasks.length === 0) {
delete parentTask.subtasks;
parentTask.subtasks = undefined;
}
let convertedTask = null;
@@ -100,13 +102,13 @@ async function removeSubtask(
log('info', `Subtask ${subtaskId} deleted`);
}
// Write the updated tasks back to the file
writeJSON(tasksPath, data);
// Write the updated tasks back to the file with proper context
writeJSON(tasksPath, data, context.projectRoot, context.tag);
// Generate task files if requested
if (generateFiles) {
log('info', 'Regenerating task files...');
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
// await generateTaskFiles(tasksPath, path.dirname(tasksPath), context);
}
return convertedTask;

View File

@@ -195,10 +195,10 @@ async function removeTask(tasksPath, taskIds, context = {}) {
// Generate updated task files ONCE, with context
try {
await generateTaskFiles(tasksPath, path.dirname(tasksPath), {
projectRoot,
tag: currentTag
});
// await generateTaskFiles(tasksPath, path.dirname(tasksPath), {
// projectRoot,
// tag: currentTag
// });
results.messages.push('Task files regenerated successfully.');
} catch (genError) {
const genErrMsg = `Failed to regenerate task files: ${genError.message}`;

View File

@@ -119,10 +119,10 @@ async function setTaskStatus(
validateTaskDependencies(data.tasks);
// Generate individual task files
log('info', 'Regenerating task files...');
await generateTaskFiles(tasksPath, path.dirname(tasksPath), {
mcpLog: options.mcpLog
});
// log('info', 'Regenerating task files...');
// await generateTaskFiles(tasksPath, path.dirname(tasksPath), {
// mcpLog: options.mcpLog
// });
// Display success message - only in CLI mode
if (!isMcpMode) {

View File

@@ -337,7 +337,7 @@ Output Requirements:
}
report('success', `Successfully updated subtask ${subtaskId}`);
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
// await generateTaskFiles(tasksPath, path.dirname(tasksPath));
if (outputFormat === 'text') {
if (loadingIndicator) {

View File

@@ -524,7 +524,7 @@ The changes described in the prompt should be thoughtfully applied to make the t
// --- Write File and Generate (Unchanged) ---
writeJSON(tasksPath, data);
report('success', `Successfully updated task ${taskId}`);
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
// await generateTaskFiles(tasksPath, path.dirname(tasksPath));
// --- End Write File ---
// --- Display CLI Telemetry ---

View File

@@ -477,7 +477,7 @@ The changes described in the prompt should be applied to ALL tasks in the list.`
'success',
`Successfully updated ${actualUpdateCount} tasks in ${tasksPath}`
);
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
// await generateTaskFiles(tasksPath, path.dirname(tasksPath));
if (outputFormat === 'text' && aiServiceResponse.telemetryData) {
displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli');