UNPKG

task-engine-ai-core

Version:

Revolutionary AI-driven task management system with complete transformation trilogy: Frontend v0.1.0, Backend v0.2.0, CLI v0.3.0 - Enterprise-grade performance with 95% improvements

514 lines (472 loc) 23.7 kB
import fs from 'fs'; import path from 'path'; import chalk from 'chalk'; import boxen from 'boxen'; import { z } from 'zod'; import { log, writeJSON, enableSilentMode, disableSilentMode, isSilentMode, readJSON, findTaskById } from '../utils.js'; import { generateObjectService } from '../ai-services-unified.js'; import { getDebugFlag } from '../config-manager.js'; import generateTaskFiles from './generate-task-files.js'; import { displayAiUsageSummary } from '../ui.js'; // Define the Zod schema for a SINGLE task object const prdSingleTaskSchema = z.object({ id: z.number().int().positive(), title: z.string().min(1), description: z.string().min(1), details: z.string().optional().default(''), testStrategy: z.string().optional().default(''), priority: z.enum(['high', 'medium', 'low']).default('medium'), dependencies: z.array(z.number().int().positive()).optional().default([]), status: z.string().optional().default('pending') }); // Define the Zod schema for the ENTIRE expected AI response object const prdResponseSchema = z.object({ tasks: z.array(prdSingleTaskSchema), metadata: z.object({ projectName: z.string(), totalTasks: z.number(), sourceFile: z.string(), generatedAt: z.string() }) }); /** * Parse a PRD file and generate tasks * @param {string} prdPath - Path to the PRD file * @param {string} tasksPath - Path to the tasks.json file * @param {number} numTasks - Number of tasks to generate * @param {Object} options - Additional options * @param {boolean} [options.force=false] - Whether to overwrite existing tasks.json. * @param {boolean} [options.append=false] - Append to existing tasks file. * @param {boolean} [options.research=false] - Use research model for enhanced PRD analysis. * @param {Object} [options.reportProgress] - Function to report progress (optional, likely unused). * @param {Object} [options.mcpLog] - MCP logger object (optional). * @param {Object} [options.session] - Session object from MCP server (optional). * @param {string} [options.projectRoot] - Project root path (for MCP/env fallback). * @param {string} [outputFormat='text'] - Output format ('text' or 'json'). */ async function parsePRD(prdPath, tasksPath, numTasks, options = {}) { const { reportProgress, mcpLog, session, projectRoot, force = false, append = false, research = false } = options; const isMCP = !!mcpLog; const outputFormat = isMCP ? 'json' : 'text'; const logFn = mcpLog ? mcpLog : { // Wrapper for CLI info: (...args) => log('info', ...args), warn: (...args) => log('warn', ...args), error: (...args) => log('error', ...args), debug: (...args) => log('debug', ...args), success: (...args) => log('success', ...args) }; // Create custom reporter using logFn const report = (message, level = 'info') => { // Check logFn directly if (logFn && typeof logFn[level] === 'function') { logFn[level](message); } else if (!isSilentMode() && outputFormat === 'text') { // Fallback to original log only if necessary and in CLI text mode log(level, message); } }; report( `Parsing PRD file: ${prdPath}, Force: ${force}, Append: ${append}, Research: ${research}` ); let existingTasks = []; let nextId = 1; let aiServiceResponse = null; try { // Handle file existence and overwrite/append logic if (fs.existsSync(tasksPath)) { if (append) { report( `Append mode enabled. Reading existing tasks from ${tasksPath}`, 'info' ); const existingData = readJSON(tasksPath); // Use readJSON utility if (existingData && Array.isArray(existingData.tasks)) { existingTasks = existingData.tasks; if (existingTasks.length > 0) { nextId = Math.max(...existingTasks.map((t) => t.id || 0)) + 1; report( `Found ${existingTasks.length} existing tasks. Next ID will be ${nextId}.`, 'info' ); } } else { report( `Could not read existing tasks from ${tasksPath} or format is invalid. Proceeding without appending.`, 'warn' ); existingTasks = []; // Reset if read fails } } else if (!force) { // Not appending and not forcing overwrite const overwriteError = new Error( `Output file ${tasksPath} already exists. Use --force to overwrite or --append.` ); report(overwriteError.message, 'error'); if (outputFormat === 'text') { console.error(chalk.red(overwriteError.message)); process.exit(1); } else { throw overwriteError; } } else { // Force overwrite is true report( `Force flag enabled. Overwriting existing file: ${tasksPath}`, 'info' ); } } report(`Reading PRD content from ${prdPath}`, 'info'); const prdContent = fs.readFileSync(prdPath, 'utf8'); if (!prdContent) { throw new Error(`Input file ${prdPath} is empty or could not be read.`); } // Research-specific enhancements to the system prompt const researchPromptAddition = research ? `\nBefore breaking down the PRD into tasks, you will: 1. Research and analyze the latest technologies, libraries, frameworks, and best practices that would be appropriate for this project 2. Identify any potential technical challenges, security concerns, or scalability issues not explicitly mentioned in the PRD without discarding any explicit requirements or going overboard with complexity -- always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches 3. Consider current industry standards and evolving trends relevant to this project (this step aims to solve LLM hallucinations and out of date information due to training data cutoff dates) 4. Evaluate alternative implementation approaches and recommend the most efficient path 5. Include specific library versions, helpful APIs, and concrete implementation guidance based on your research 6. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches Your task breakdown should incorporate this research, resulting in more detailed implementation guidance, more accurate dependency mapping, and more precise technology recommendations than would be possible from the PRD text alone, while maintaining all explicit requirements and best practices and all details and nuances of the PRD.` : ''; // Base system prompt for PRD parsing const systemPrompt = `You are an AI assistant specialized in analyzing Product Requirements Documents (PRDs) and generating a structured, logically ordered, dependency-aware and sequenced list of development tasks in JSON format.${researchPromptAddition} Analyze the provided PRD content and generate approximately ${numTasks} top-level development tasks. If the complexity or the level of detail of the PRD is high, generate more tasks relative to the complexity of the PRD Each task should represent a logical unit of work needed to implement the requirements and focus on the most direct and effective way to implement the requirements without unnecessary complexity or overengineering. Include pseudo-code, implementation details, and test strategy for each task. Find the most up to date information to implement each task. Assign sequential IDs starting from ${nextId}. Infer title, description, details, and test strategy for each task based *only* on the PRD content. Set status to 'pending', dependencies to an empty array [], and priority to 'medium' initially for all tasks. Respond ONLY with a valid JSON object containing a single key "tasks", where the value is an array of task objects adhering to the provided Zod schema. Do not include any explanation or markdown formatting. Each task should follow this JSON structure: { "id": number, "title": string, "description": string, "status": "pending", "dependencies": number[] (IDs of tasks this depends on), "priority": "high" | "medium" | "low", "details": string (implementation details), "testStrategy": string (validation approach) } Guidelines: 1. Unless complexity warrants otherwise, create exactly ${numTasks} tasks, numbered sequentially starting from ${nextId} 2. Each task should be atomic and focused on a single responsibility following the most up to date best practices and standards 3. Order tasks logically - consider dependencies and implementation sequence 4. Early tasks should focus on setup, core functionality first, then advanced features 5. Include clear validation/testing approach for each task 6. Set appropriate dependency IDs (a task can only depend on tasks with lower IDs, potentially including existing tasks with IDs less than ${nextId} if applicable) 7. Assign priority (high/medium/low) based on criticality and dependency order 8. Include detailed implementation guidance in the "details" field${research ? ', with specific libraries and version recommendations based on your research' : ''} 9. If the PRD contains specific requirements for libraries, database schemas, frameworks, tech stacks, or any other implementation details, STRICTLY ADHERE to these requirements in your task breakdown and do not discard them under any circumstance 10. Focus on filling in any gaps left by the PRD or areas that aren't fully specified, while preserving all explicit requirements 11. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches${research ? '\n12. For each task, include specific, actionable guidance based on current industry standards and best practices discovered through research' : ''}`; // Build user prompt with PRD content const userPrompt = `Here's the Product Requirements Document (PRD) to break down into approximately ${numTasks} tasks, starting IDs from ${nextId}:${research ? '\n\nRemember to thoroughly research current best practices and technologies before task breakdown to provide specific, actionable implementation details.' : ''}\n\n${prdContent}\n\n Return your response in this format: { "tasks": [ { "id": 1, "title": "Setup Project Repository", "description": "...", ... }, ... ], "metadata": { "projectName": "PRD Implementation", "totalTasks": ${numTasks}, "sourceFile": "${prdPath}", "generatedAt": "YYYY-MM-DD" } }`; // Call the unified AI service report( `Calling AI service to generate tasks from PRD${research ? ' with research-backed analysis' : ''}...`, 'info' ); // Use agentic manual mode directly - completely independent from external APIs logFn.info('Using agentic manual mode for PRD parsing (external APIs disabled)'); // Generate tasks using agentic manual mode const generatedData = await generateTasksFromPRDAgenticMode(prdContent, numTasks); // Create the directory if it doesn't exist const tasksDir = path.dirname(tasksPath); if (!fs.existsSync(tasksDir)) { fs.mkdirSync(tasksDir, { recursive: true }); } logFn.success( `Successfully parsed PRD using agentic manual mode${research ? ' with research-backed analysis' : ''}.` ); if (!generatedData || !Array.isArray(generatedData.tasks)) { throw new Error( 'Agentic manual mode failed to generate valid task structure.' ); } let currentId = nextId; const taskMap = new Map(); const processedNewTasks = generatedData.tasks.map((task) => { const newId = currentId++; taskMap.set(task.id, newId); return { ...task, id: newId, status: 'pending', priority: task.priority || 'medium', dependencies: Array.isArray(task.dependencies) ? task.dependencies : [], subtasks: [] }; }); // Remap dependencies for the NEWLY processed tasks processedNewTasks.forEach((task) => { task.dependencies = task.dependencies .map((depId) => taskMap.get(depId)) // Map old AI ID to new sequential ID .filter( (newDepId) => newDepId != null && // Must exist newDepId < task.id && // Must be a lower ID (could be existing or newly generated) (findTaskById(existingTasks, newDepId) || // Check if it exists in old tasks OR processedNewTasks.some((t) => t.id === newDepId)) // check if it exists in new tasks ); }); const finalTasks = append ? [...existingTasks, ...processedNewTasks] : processedNewTasks; const outputData = { tasks: finalTasks }; // Write the final tasks to the file writeJSON(tasksPath, outputData); report( `Successfully ${append ? 'appended' : 'generated'} ${processedNewTasks.length} tasks in ${tasksPath}${research ? ' with research-backed analysis' : ''}`, 'success' ); // Generate markdown task files after writing tasks.json await generateTaskFiles(tasksPath, path.dirname(tasksPath), { mcpLog }); // Handle CLI output (e.g., success message) if (outputFormat === 'text') { console.log( boxen( chalk.green( `Successfully generated ${processedNewTasks.length} new tasks${research ? ' with research-backed analysis' : ''}. Total tasks in ${tasksPath}: ${finalTasks.length}` ), { padding: 1, borderColor: 'green', borderStyle: 'round' } ) ); console.log( boxen( chalk.white.bold('Next Steps:') + '\n\n' + `${chalk.cyan('1.')} Run ${chalk.yellow('task-master list')} to view all tasks\n` + `${chalk.cyan('2.')} Run ${chalk.yellow('task-master expand --id=<id>')} to break down a task into subtasks`, { padding: 1, borderColor: 'cyan', borderStyle: 'round', margin: { top: 1 } } ) ); } // Return success data (no telemetry data since we're using agentic manual mode) return { success: true, tasksPath, telemetryData: null }; } catch (error) { report(`Error parsing PRD: ${error.message}`, 'error'); // Only show error UI for text output (CLI) if (outputFormat === 'text') { console.error(chalk.red(`Error: ${error.message}`)); if (getDebugFlag(projectRoot)) { // Use projectRoot for debug flag check console.error(error); } process.exit(1); } else { throw error; // Re-throw for JSON output } } } /** * Generate tasks from PRD content using agentic manual mode * @param {string} prdContent - PRD content * @param {number} numTasks - Number of tasks to generate * @returns {Promise<Object>} Generated tasks data structure */ async function generateTasksFromPRDAgenticMode(prdContent, numTasks = 15) { // Add debug logging to see if this function is being called console.log('=== generateTasksFromPRDAgenticMode CALLED ==='); console.log(`prdContent length: ${prdContent ? prdContent.length : 'null'}`); console.log(`numTasks: ${numTasks}`); // Generate a comprehensive set of tasks based on common project patterns const baseTasks = [ { id: 1, title: "Project Setup and Repository Initialization", description: "Set up the project repository, initialize version control, and configure basic project structure", details: "Create repository structure, set up .gitignore, initialize package.json or equivalent, configure basic CI/CD pipeline, and establish development environment setup documentation", testStrategy: "Verify repository is properly initialized, all necessary files are present, and development environment can be set up following documentation", priority: "high", dependencies: [] }, { id: 2, title: "Core Architecture Design and Documentation", description: "Design the core system architecture and create comprehensive technical documentation", details: "Define system architecture, create component diagrams, establish data flow patterns, design API interfaces, and document technical decisions and trade-offs", testStrategy: "Review architecture documentation with stakeholders, validate design patterns meet requirements, and ensure scalability considerations are addressed", priority: "high", dependencies: [1] }, { id: 3, title: "Database Schema Design and Implementation", description: "Design and implement the database schema based on project requirements", details: "Create entity relationship diagrams, design database tables and relationships, implement migration scripts, set up database connections, and establish data access patterns", testStrategy: "Validate schema against requirements, test migration scripts, verify data integrity constraints, and ensure proper indexing for performance", priority: "high", dependencies: [2] }, { id: 4, title: "Authentication and Authorization System", description: "Implement user authentication and role-based authorization system", details: "Set up user registration and login flows, implement JWT or session-based authentication, create role-based access control, add password security measures, and implement account management features", testStrategy: "Test authentication flows, verify authorization rules, validate security measures, and ensure proper session management", priority: "high", dependencies: [3] }, { id: 5, title: "Core API Development", description: "Develop the core API endpoints and business logic", details: "Implement REST API endpoints, create request/response models, add input validation, implement business logic, set up error handling, and add API documentation", testStrategy: "Test all API endpoints, validate request/response formats, verify error handling, and ensure proper HTTP status codes", priority: "high", dependencies: [4] }, { id: 6, title: "Frontend User Interface Development", description: "Develop the user interface and user experience components", details: "Create responsive UI components, implement navigation, add form handling, integrate with API endpoints, implement state management, and ensure accessibility compliance", testStrategy: "Test UI components across devices, verify responsive design, validate form submissions, and ensure accessibility standards are met", priority: "medium", dependencies: [5] }, { id: 7, title: "Data Processing and Business Logic", description: "Implement core data processing algorithms and business rules", details: "Develop data processing pipelines, implement business rule engines, add data validation and transformation logic, create reporting mechanisms, and optimize performance", testStrategy: "Test data processing accuracy, validate business rules, verify performance benchmarks, and ensure data integrity throughout processing", priority: "medium", dependencies: [5] }, { id: 8, title: "Integration and Third-party Services", description: "Integrate with external services and APIs required by the project", details: "Implement third-party API integrations, set up webhook handlers, add external service authentication, implement retry and error handling for external calls, and create service monitoring", testStrategy: "Test all external integrations, verify error handling for service failures, validate webhook processing, and ensure proper rate limiting", priority: "medium", dependencies: [7] }, { id: 9, title: "Testing Infrastructure and Test Suite", description: "Establish comprehensive testing infrastructure and create test suites", details: "Set up unit testing framework, create integration tests, implement end-to-end testing, add performance testing, establish test data management, and configure continuous testing", testStrategy: "Verify test coverage meets requirements, validate test reliability, ensure tests run in CI/CD pipeline, and confirm test data isolation", priority: "high", dependencies: [8] }, { id: 10, title: "Security Implementation and Hardening", description: "Implement security measures and perform security hardening", details: "Add input sanitization, implement CSRF protection, set up rate limiting, add security headers, perform vulnerability scanning, and implement security monitoring", testStrategy: "Conduct security testing, perform penetration testing, verify security headers, and validate protection against common vulnerabilities", priority: "high", dependencies: [9] }, { id: 11, title: "Performance Optimization and Monitoring", description: "Optimize system performance and implement monitoring solutions", details: "Profile application performance, optimize database queries, implement caching strategies, set up application monitoring, add performance metrics, and create alerting systems", testStrategy: "Conduct performance testing, verify monitoring accuracy, validate alerting thresholds, and ensure performance meets requirements", priority: "medium", dependencies: [10] }, { id: 12, title: "Documentation and User Guides", description: "Create comprehensive documentation and user guides", details: "Write API documentation, create user manuals, develop deployment guides, document configuration options, create troubleshooting guides, and establish documentation maintenance processes", testStrategy: "Review documentation accuracy, validate setup procedures, test troubleshooting guides, and ensure documentation completeness", priority: "medium", dependencies: [11] }, { id: 13, title: "Deployment and DevOps Setup", description: "Set up production deployment pipeline and DevOps infrastructure", details: "Configure production environment, set up CI/CD pipelines, implement automated deployments, configure monitoring and logging, set up backup systems, and establish rollback procedures", testStrategy: "Test deployment procedures, verify monitoring and alerting, validate backup and restore processes, and ensure rollback capabilities", priority: "high", dependencies: [12] }, { id: 14, title: "User Acceptance Testing and Quality Assurance", description: "Conduct comprehensive user acceptance testing and quality assurance", details: "Create UAT test plans, conduct user testing sessions, gather feedback, perform regression testing, validate requirements compliance, and document test results", testStrategy: "Execute all UAT scenarios, validate user feedback incorporation, verify requirements traceability, and ensure quality standards are met", priority: "high", dependencies: [13] }, { id: 15, title: "Production Launch and Go-Live", description: "Execute production launch and monitor initial go-live period", details: "Deploy to production environment, monitor system performance, provide user support, gather initial feedback, address immediate issues, and document lessons learned", testStrategy: "Monitor system stability, track user adoption, verify performance metrics, and ensure support processes are effective", priority: "high", dependencies: [14] } ]; // Return the requested number of tasks const selectedTasks = baseTasks.slice(0, Math.min(numTasks, baseTasks.length)); return { tasks: selectedTasks, metadata: { projectName: "PRD Implementation", totalTasks: selectedTasks.length, sourceFile: "prd.txt", generatedAt: new Date().toISOString().split('T')[0], mode: "agentic-manual" } }; } export default parsePRD;