mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2026-01-29 22:02:04 +00:00
chore: apply requested changes
This commit is contained in:
@@ -26,8 +26,7 @@ export function registerAutopilotResumeTool(server: FastMCP) {
|
||||
'Resume a previously started TDD workflow from saved state. Restores the workflow state machine and continues from where it left off.',
|
||||
parameters: ResumeWorkflowSchema,
|
||||
annotations: {
|
||||
title: 'Resume Autopilot Workflow',
|
||||
readOnlyHint: false
|
||||
title: 'Resume Autopilot Workflow'
|
||||
},
|
||||
execute: withToolContext(
|
||||
'autopilot-resume',
|
||||
|
||||
@@ -22,6 +22,7 @@ import { getPromptManager } from '../prompt-manager.js';
|
||||
import { findProjectRoot, flattenTasksWithSubtasks } from '../utils.js';
|
||||
import { ContextGatherer } from '../utils/contextGatherer.js';
|
||||
import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';
|
||||
import { normalizeSubtask } from './parse-prd/parse-prd-helpers.js';
|
||||
|
||||
/**
|
||||
* Expand a task into subtasks using the unified AI service (generateObjectService).
|
||||
@@ -331,12 +332,9 @@ async function expandTask(
|
||||
if (!mainResult || !Array.isArray(mainResult.subtasks)) {
|
||||
throw new Error('AI response did not include a valid subtasks array.');
|
||||
}
|
||||
generatedSubtasks = mainResult.subtasks.map((subtask) => ({
|
||||
...subtask,
|
||||
dependencies: subtask.dependencies ?? [],
|
||||
status: subtask.status ?? 'pending',
|
||||
testStrategy: subtask.testStrategy ?? null
|
||||
}));
|
||||
generatedSubtasks = mainResult.subtasks.map((subtask) =>
|
||||
normalizeSubtask(subtask)
|
||||
);
|
||||
logger.info(`Received ${generatedSubtasks.length} subtasks from AI.`);
|
||||
} catch (error) {
|
||||
if (loadingIndicator) stopLoadingIndicator(loadingIndicator);
|
||||
|
||||
@@ -23,6 +23,57 @@ export function estimateTokens(text) {
|
||||
return Math.ceil(text.length / 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a subtask by applying schema defaults for missing fields
|
||||
* Subtasks have: id, title, description, status, dependencies, details
|
||||
* (no testStrategy, no priority - those are task-only fields)
|
||||
* @param {Object} subtask - Raw subtask object from AI response
|
||||
* @returns {Object} Subtask with all required fields populated
|
||||
*/
|
||||
export function normalizeSubtask(subtask) {
|
||||
return {
|
||||
...subtask,
|
||||
title: subtask.title ?? '',
|
||||
description: subtask.description ?? '',
|
||||
details: subtask.details ?? '',
|
||||
dependencies: subtask.dependencies ?? [],
|
||||
status: subtask.status ?? 'pending'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a task by applying schema defaults for missing fields
|
||||
* @param {Object} task - Raw task object from AI response
|
||||
* @param {string} defaultPriority - Default priority to use
|
||||
* @returns {Object} Task with all required fields populated
|
||||
*/
|
||||
export function normalizeTask(task, defaultPriority = 'medium') {
|
||||
return {
|
||||
...task,
|
||||
status: task.status ?? 'pending',
|
||||
title: task.title ?? '',
|
||||
description: task.description ?? '',
|
||||
dependencies: task.dependencies ?? [],
|
||||
priority: task.priority ?? defaultPriority,
|
||||
details: task.details ?? '',
|
||||
testStrategy: task.testStrategy ?? '',
|
||||
subtasks: task.subtasks
|
||||
? task.subtasks.map((subtask) => normalizeSubtask(subtask))
|
||||
: undefined
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize an array of tasks by applying schema defaults
|
||||
* @param {Array} tasks - Array of raw task objects
|
||||
* @param {string} defaultPriority - Default priority to use
|
||||
* @returns {Array} Tasks with all required fields populated
|
||||
*/
|
||||
export function normalizeTasks(tasks, defaultPriority = 'medium') {
|
||||
if (!Array.isArray(tasks)) return [];
|
||||
return tasks.map((task) => normalizeTask(task, defaultPriority));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and validate PRD content
|
||||
* @param {string} prdPath - Path to PRD file
|
||||
@@ -139,23 +190,17 @@ export function processTasks(
|
||||
let currentId = startId;
|
||||
const taskMap = new Map();
|
||||
|
||||
// First pass: assign new IDs and create mapping
|
||||
// First pass: normalize, assign new IDs, and create mapping
|
||||
const processedTasks = rawTasks.map((task) => {
|
||||
const newId = currentId++;
|
||||
taskMap.set(task.id, newId);
|
||||
|
||||
// Apply schema defaults via normalizeTask, then override with new ID
|
||||
const normalized = normalizeTask(task, defaultPriority);
|
||||
return {
|
||||
...task,
|
||||
...normalized,
|
||||
id: newId,
|
||||
status: task.status || 'pending',
|
||||
priority: task.priority || defaultPriority,
|
||||
dependencies: Array.isArray(task.dependencies) ? task.dependencies : [],
|
||||
subtasks: task.subtasks || [],
|
||||
// Ensure all required fields have values
|
||||
title: task.title || '',
|
||||
description: task.description || '',
|
||||
details: task.details || '',
|
||||
testStrategy: task.testStrategy || ''
|
||||
subtasks: normalized.subtasks || []
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ export async function handleNonStreamingService(config, prompts) {
|
||||
spinner.succeed('Tasks generated successfully!');
|
||||
}
|
||||
|
||||
// Note: Schema defaults are applied later by processTasks in parsePRDCore
|
||||
return {
|
||||
parsedTasks: generatedData.tasks,
|
||||
aiServiceResponse,
|
||||
|
||||
@@ -460,6 +460,7 @@ async function finalizeStreamingResults(state, context) {
|
||||
);
|
||||
}
|
||||
|
||||
// Note: Schema defaults are applied later by processTasks in parsePRDCore
|
||||
return {
|
||||
parsedTasks: lastPartialObject.tasks,
|
||||
estimatedOutputTokens: finalOutputTokens,
|
||||
@@ -570,19 +571,7 @@ async function processWithGenerateObject(context, logger) {
|
||||
// Extract tasks from the result (handle both direct tasks and mainResult.tasks)
|
||||
const tasks = result?.mainResult || result;
|
||||
|
||||
// Apply defaults to ensure all required fields are present
|
||||
if (tasks && Array.isArray(tasks.tasks)) {
|
||||
tasks.tasks = tasks.tasks.map((task) => ({
|
||||
...task,
|
||||
status: task.status ?? 'pending',
|
||||
title: task.title ?? '',
|
||||
description: task.description ?? '',
|
||||
dependencies: task.dependencies ?? [],
|
||||
priority: task.priority ?? context.defaultPriority ?? 'medium',
|
||||
details: task.details ?? '',
|
||||
testStrategy: task.testStrategy ?? ''
|
||||
}));
|
||||
}
|
||||
// Note: Schema defaults are applied later by processTasks in parsePRDCore
|
||||
|
||||
// Process the generated tasks
|
||||
if (tasks && Array.isArray(tasks.tasks)) {
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import path from 'path';
|
||||
import boxen from 'boxen';
|
||||
import chalk from 'chalk';
|
||||
import Table from 'cli-table3';
|
||||
|
||||
import {
|
||||
log as consoleLog,
|
||||
isSilentMode,
|
||||
readJSON,
|
||||
truncate,
|
||||
writeJSON
|
||||
} from '../utils.js';
|
||||
import { log as consoleLog, readJSON, truncate, writeJSON } from '../utils.js';
|
||||
|
||||
import {
|
||||
displayAiUsageSummary,
|
||||
@@ -29,7 +22,7 @@ import { getPromptManager } from '../prompt-manager.js';
|
||||
import { findProjectRoot, flattenTasksWithSubtasks } from '../utils.js';
|
||||
import { ContextGatherer } from '../utils/contextGatherer.js';
|
||||
import { FuzzyTaskSearch } from '../utils/fuzzyTaskSearch.js';
|
||||
import { getModelConfiguration } from './models.js';
|
||||
import { normalizeTasks } from './parse-prd/parse-prd-helpers.js';
|
||||
|
||||
/**
|
||||
* Update tasks based on new context using the unified AI service.
|
||||
@@ -233,25 +226,9 @@ async function updateTasks(
|
||||
|
||||
// With generateObject, we get structured data directly
|
||||
const defaultPriority = getDefaultPriority(projectRoot) ?? 'medium';
|
||||
const parsedUpdatedTasks = aiServiceResponse.mainResult.tasks.map(
|
||||
(task) => ({
|
||||
...task,
|
||||
status: task.status ?? 'pending',
|
||||
title: task.title ?? '',
|
||||
description: task.description ?? '',
|
||||
dependencies: task.dependencies ?? [],
|
||||
priority: task.priority ?? defaultPriority,
|
||||
details: task.details ?? '',
|
||||
testStrategy: task.testStrategy ?? '',
|
||||
subtasks: task.subtasks
|
||||
? task.subtasks.map((subtask) => ({
|
||||
...subtask,
|
||||
dependencies: subtask.dependencies ?? [],
|
||||
status: subtask.status ?? 'pending',
|
||||
testStrategy: subtask.testStrategy ?? ''
|
||||
}))
|
||||
: null
|
||||
})
|
||||
const parsedUpdatedTasks = normalizeTasks(
|
||||
aiServiceResponse.mainResult.tasks,
|
||||
defaultPriority
|
||||
);
|
||||
|
||||
// --- Update Tasks Data (Updated writeJSON call) ---
|
||||
|
||||
Reference in New Issue
Block a user