Eyal Toledano 5119cd2d8e v017 polish (#778)
* fix(research, tasks): Make research command and task updates tag-aware

* refactor(tasks): Prevent automatic task file generation across other locations

This commit refactors several core task management functions to prevent them from automatically regenerating individual task files after modifying the main `tasks.json`.

Previously, operations like `add-task`, `clear-subtasks`, `expand-task`, and `update-task-by-id` would immediately trigger `generateTaskFiles`. This could be slow and was often unnecessary.

The calls to `generateTaskFiles` have been removed or commented out from the core task functions. Users should now run `task-master generate` explicitly to update their individual task files.

Additionally, this commit includes fixes to the `move` command to make it fully tag-aware.

* fix: move and clear subtasks mcp commands

* chore: fix format

* chore: fix unit tests

---------

Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-06-15 03:47:56 +03:00

148 lines
3.5 KiB
JavaScript

import path from 'path';
import chalk from 'chalk';
import boxen from 'boxen';
import Table from 'cli-table3';
import { log, readJSON, writeJSON, truncate, isSilentMode } from '../utils.js';
import { displayBanner } from '../ui.js';
/**
* Clear subtasks from specified tasks
* @param {string} tasksPath - Path to the tasks.json file
* @param {string} taskIds - Task IDs to clear subtasks from
* @param {Object} context - Context object containing projectRoot and tag
*/
function clearSubtasks(tasksPath, taskIds, context = {}) {
const { projectRoot, tag } = context;
log('info', `Reading tasks from ${tasksPath}...`);
const data = readJSON(tasksPath, projectRoot, tag);
if (!data || !data.tasks) {
log('error', 'No valid tasks found.');
process.exit(1);
}
if (!isSilentMode()) {
console.log(
boxen(chalk.white.bold('Clearing Subtasks'), {
padding: 1,
borderColor: 'blue',
borderStyle: 'round',
margin: { top: 1, bottom: 1 }
})
);
}
// Handle multiple task IDs (comma-separated)
const taskIdArray = taskIds.split(',').map((id) => id.trim());
let clearedCount = 0;
// Create a summary table for the cleared subtasks
const summaryTable = new Table({
head: [
chalk.cyan.bold('Task ID'),
chalk.cyan.bold('Task Title'),
chalk.cyan.bold('Subtasks Cleared')
],
colWidths: [10, 50, 20],
style: { head: [], border: [] }
});
taskIdArray.forEach((taskId) => {
const id = parseInt(taskId, 10);
if (Number.isNaN(id)) {
log('error', `Invalid task ID: ${taskId}`);
return;
}
const task = data.tasks.find((t) => t.id === id);
if (!task) {
log('error', `Task ${id} not found`);
return;
}
if (!task.subtasks || task.subtasks.length === 0) {
log('info', `Task ${id} has no subtasks to clear`);
summaryTable.push([
id.toString(),
truncate(task.title, 47),
chalk.yellow('No subtasks')
]);
return;
}
const subtaskCount = task.subtasks.length;
task.subtasks = [];
clearedCount++;
log('info', `Cleared ${subtaskCount} subtasks from task ${id}`);
summaryTable.push([
id.toString(),
truncate(task.title, 47),
chalk.green(`${subtaskCount} subtasks cleared`)
]);
});
if (clearedCount > 0) {
writeJSON(tasksPath, data, projectRoot, tag);
// Show summary table
if (!isSilentMode()) {
console.log(
boxen(chalk.white.bold('Subtask Clearing Summary:'), {
padding: { left: 2, right: 2, top: 0, bottom: 0 },
margin: { top: 1, bottom: 0 },
borderColor: 'blue',
borderStyle: 'round'
})
);
console.log(summaryTable.toString());
}
// Success message
if (!isSilentMode()) {
console.log(
boxen(
chalk.green(
`Successfully cleared subtasks from ${chalk.bold(clearedCount)} task(s)`
),
{
padding: 1,
borderColor: 'green',
borderStyle: 'round',
margin: { top: 1 }
}
)
);
// Next steps suggestion
console.log(
boxen(
chalk.white.bold('Next Steps:') +
'\n\n' +
`${chalk.cyan('1.')} Run ${chalk.yellow('task-master expand --id=<id>')} to generate new subtasks\n` +
`${chalk.cyan('2.')} Run ${chalk.yellow('task-master list --with-subtasks')} to verify changes`,
{
padding: 1,
borderColor: 'cyan',
borderStyle: 'round',
margin: { top: 1 }
}
)
);
}
} else {
if (!isSilentMode()) {
console.log(
boxen(chalk.yellow('No subtasks were cleared'), {
padding: 1,
borderColor: 'yellow',
borderStyle: 'round',
margin: { top: 1 }
})
);
}
}
}
export default clearSubtasks;