Eyal Toledano b1390e4ddf refactor: enhance add-task fuzzy search and fix duplicate banner display
- **Remove hardcoded category system** in add-task that always matched 'Task management'
- **Eliminate arbitrary limits** in fuzzy search results (5→25 high relevance, 3→10 medium relevance, 8→20 detailed tasks)
- **Improve semantic weighting** in Fuse.js search (details=3, description=2, title=1.5) for better relevance
- **Fix duplicate banner issue** by removing console.clear() and redundant displayBanner() calls from UI functions
- **Enhance context generation** to rely on semantic similarity rather than rigid pattern matching
- **Preserve terminal history** to address GitHub issue #553 about eating terminal lines
- **Remove displayBanner() calls** from: displayHelp, displayNextTask, displayTaskById, displayComplexityReport, set-task-status, clear-subtasks, dependency-manager functions

The add-task system now provides truly relevant task context based on semantic similarity rather than arbitrary categories and limits, while maintaining a cleaner terminal experience.

Changes span: add-task.js, ui.js, set-task-status.js, clear-subtasks.js, list-tasks.js, dependency-manager.js

Closes #553
2025-06-07 20:23:55 -04:00

151 lines
3.9 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";
import generateTaskFiles from "./generate-task-files.js";
/**
* Clear subtasks from specified tasks
* @param {string} tasksPath - Path to the tasks.json file
* @param {string} taskIds - Task IDs to clear subtasks from
*/
function clearSubtasks(tasksPath, taskIds) {
log("info", `Reading tasks from ${tasksPath}...`);
const data = readJSON(tasksPath);
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 (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);
// 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());
}
// Regenerate task files to reflect changes
log("info", "Regenerating task files...");
generateTaskFiles(tasksPath, path.dirname(tasksPath));
// 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;