mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2025-07-04 15:41:26 +00:00

* 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>
148 lines
3.5 KiB
JavaScript
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;
|