UNPKG

task-master-neo-sdlc

Version:

Enhanced task management system with Neo SDLC agents and MCP tools for comprehensive, AI-driven software development lifecycle management.

720 lines (650 loc) 21.9 kB
/** * MCP SDLC Tools * * This module provides MCP tools for Neo SDLC agents, implementing features * based on the Model Context Protocol specification. */ import { z } from 'zod'; /** * Utility function to create an MCP tool response with content * @param {string|object} content - The content to return * @param {boolean} isError - Whether this is an error response * @returns {object} Formatted MCP tool response */ function createToolResponse(content, isError = false) { // Normalize content to array of content items const contentArray = Array.isArray(content) ? content : [content]; // Transform each item to proper MCP content format if needed const formattedContent = contentArray.map(item => { if (typeof item === 'string') { return { type: 'text', text: item }; } else if (item.type && (item.text || item.data)) { return item; } else if (Buffer.isBuffer(item)) { return { type: 'image', data: item.toString('base64'), mimeType: 'image/png' }; } return { type: 'text', text: JSON.stringify(item) }; }); return { content: formattedContent, ...(isError && { isError: true }) }; } /** * Creates image content for MCP tool responses * @param {object} options - Options for the image * @param {Buffer} options.buffer - Image buffer * @param {string} options.mimeType - MIME type of the image * @returns {object} Formatted image content */ function imageContent({ buffer, mimeType = 'image/png' }) { return { type: 'image', data: buffer.toString('base64'), mimeType }; } /** * Class for MCP SDLC tools */ class MCPSdlcTools { constructor(server) { this.server = server; this.setupTools(); } /** * Set up all SDLC tools */ setupTools() { this.setupRequirementsTools(); this.setupDesignTools(); this.setupCodeTools(); this.setupDocumentationTools(); this.setupTestingTools(); this.setupSecurityTools(); this.setupPlanningTools(); } /** * Set up requirements analysis tools */ setupRequirementsTools() { // Requirements extraction tool this.server.addTool({ name: 'extractRequirements', description: 'Extract functional and non-functional requirements from documents', parameters: z.object({ content: z.string().describe('Text content to extract requirements from'), type: z.enum(['functional', 'non-functional', 'all']).default('all').describe('Type of requirements to extract') }), execute: async (args) => { const requirements = await this.extractRequirements(args.content, args.type); return createToolResponse(requirements); } }); // Requirements validation tool this.server.addTool({ name: 'validateRequirements', description: 'Validate requirements against quality criteria', parameters: z.object({ requirements: z.array(z.object({ id: z.string(), description: z.string(), type: z.enum(['functional', 'non-functional']), priority: z.enum(['low', 'medium', 'high']).optional() })), criteria: z.array(z.string()).optional() }), execute: async (args) => { const validationResults = await this.validateRequirements(args.requirements, args.criteria); return createToolResponse(validationResults); } }); } /** * Set up design tools */ setupDesignTools() { // Architecture design tool this.server.addTool({ name: 'generateArchitecture', description: 'Generate architecture design based on requirements', parameters: z.object({ requirements: z.array(z.object({ id: z.string(), description: z.string(), type: z.enum(['functional', 'non-functional']) })), style: z.enum(['microservices', 'monolithic', 'serverless', 'event-driven']).optional(), outputFormat: z.enum(['text', 'diagram']).default('text') }), execute: async (args) => { const architecture = await this.generateArchitecture( args.requirements, args.style, args.outputFormat ); return createToolResponse(architecture); } }); // UX design tool this.server.addTool({ name: 'createUXDesign', description: 'Create UX designs and wireframes', parameters: z.object({ description: z.string().describe('Description of the UI to design'), type: z.enum(['wireframe', 'mockup', 'prototype']).default('wireframe'), platform: z.enum(['web', 'mobile', 'desktop']).default('web') }), execute: async (args) => { const uxDesign = await this.createUXDesign(args.description, args.type, args.platform); return createToolResponse(uxDesign); } }); } /** * Set up code generation and management tools */ setupCodeTools() { // Code generation tool this.server.addTool({ name: 'generateCode', description: 'Generate code based on specifications', parameters: z.object({ specification: z.string().describe('Detailed specification for code generation'), language: z.string().describe('Programming language to use'), framework: z.string().optional().describe('Framework to use'), patterns: z.array(z.string()).optional().describe('Design patterns to apply') }), execute: async (args) => { const code = await this.generateCode( args.specification, args.language, args.framework, args.patterns ); return createToolResponse(code); } }); // Code refactoring tool this.server.addTool({ name: 'refactorCode', description: 'Refactor code for better quality', parameters: z.object({ code: z.string().describe('Code to refactor'), language: z.string().describe('Programming language'), objectives: z.array(z.enum([ 'performance', 'readability', 'maintainability', 'security', 'testability' ])).describe('Refactoring objectives') }), execute: async (args) => { const refactoredCode = await this.refactorCode( args.code, args.language, args.objectives ); return createToolResponse(refactoredCode); } }); } /** * Set up documentation tools */ setupDocumentationTools() { // Documentation generation tool this.server.addTool({ name: 'generateDocumentation', description: 'Generate documentation from code or specifications', parameters: z.object({ content: z.string().describe('Code or specification to document'), type: z.enum(['api', 'user', 'technical', 'code']).describe('Type of documentation to generate'), format: z.enum(['markdown', 'html', 'text']).default('markdown').describe('Output format') }), execute: async (args) => { const documentation = await this.generateDocumentation( args.content, args.type, args.format ); return createToolResponse(documentation); } }); } /** * Set up testing tools */ setupTestingTools() { // Test case generation tool this.server.addTool({ name: 'generateTestCases', description: 'Generate test cases based on requirements or code', parameters: z.object({ input: z.string().describe('Requirements or code to generate tests for'), type: z.enum(['unit', 'integration', 'system', 'acceptance']).describe('Type of tests to generate'), framework: z.string().optional().describe('Testing framework to use') }), execute: async (args) => { const testCases = await this.generateTestCases( args.input, args.type, args.framework ); return createToolResponse(testCases); } }); // Code quality analysis tool this.server.addTool({ name: 'analyzeCodeQuality', description: 'Analyze code quality and suggest improvements', parameters: z.object({ code: z.string().describe('Code to analyze'), language: z.string().describe('Programming language'), metrics: z.array(z.enum([ 'complexity', 'duplication', 'maintainability', 'testability', 'security' ])).optional().default(['complexity', 'maintainability']) }), execute: async (args) => { const analysis = await this.analyzeCodeQuality( args.code, args.language, args.metrics ); return createToolResponse(analysis); } }); } /** * Set up security tools */ setupSecurityTools() { // Security analysis tool this.server.addTool({ name: 'analyzeSecurityVulnerabilities', description: 'Analyze code for security vulnerabilities', parameters: z.object({ code: z.string().describe('Code to analyze'), language: z.string().describe('Programming language'), framework: z.string().optional().describe('Framework used') }), execute: async (args) => { const vulnerabilities = await this.analyzeSecurityVulnerabilities( args.code, args.language, args.framework ); return createToolResponse(vulnerabilities); } }); } /** * Set up project planning tools */ setupPlanningTools() { // Task decomposition tool this.server.addTool({ name: 'decomposeTask', description: 'Break down a task into smaller, manageable subtasks', parameters: z.object({ task: z.string().describe('Task to decompose'), level: z.enum(['high', 'medium', 'detailed']).default('medium').describe('Level of detail'), format: z.enum(['list', 'tree', 'json']).default('list').describe('Output format') }), execute: async (args) => { const subtasks = await this.decomposeTask( args.task, args.level, args.format ); return createToolResponse(subtasks); } }); // Effort estimation tool this.server.addTool({ name: 'estimateEffort', description: 'Estimate effort for development tasks', parameters: z.object({ tasks: z.array(z.object({ id: z.string(), description: z.string(), complexity: z.enum(['low', 'medium', 'high']).optional() })), unitType: z.enum(['hours', 'days', 'points']).default('hours') }), execute: async (args) => { const estimates = await this.estimateEffort(args.tasks, args.unitType); return createToolResponse(estimates); } }); } // Implementation methods for the tools async extractRequirements(content, type) { // Implement requirements extraction logic const categories = { functional: [], nonFunctional: [] }; // Process content to extract requirements based on type // This would be implemented with actual analysis logic return { requirements: type === 'all' ? categories : categories[type], metadata: { source: 'document', extractionDate: new Date().toISOString() } }; } async validateRequirements(requirements, criteria = []) { // Default criteria if none provided const validationCriteria = criteria.length > 0 ? criteria : [ 'clear', 'testable', 'feasible', 'necessary', 'traceable' ]; // Validate each requirement against criteria const validationResults = requirements.map(req => { const criteriaResults = {}; validationCriteria.forEach(criterion => { // This would implement actual validation logic criteriaResults[criterion] = { pass: Math.random() > 0.3, // Simplified validation feedback: `Validation feedback for ${criterion}` }; }); return { id: req.id, results: criteriaResults, overallValid: Object.values(criteriaResults).every(r => r.pass) }; }); return { results: validationResults, summary: { total: requirements.length, valid: validationResults.filter(r => r.overallValid).length } }; } async generateArchitecture(requirements, style = 'microservices', outputFormat = 'text') { // Generate architecture based on requirements and style if (outputFormat === 'diagram') { // Return a diagram (text representation for now) return { diagramType: 'C4', content: "graph TD\n A[Client] --> B[API Gateway]\n B --> C[Service 1]\n B --> D[Service 2]\n C --> E[Database]\n D --> E" }; } // Return textual architecture description return { style, components: [ { name: 'API Gateway', responsibility: 'Handle external requests' }, { name: 'Service 1', responsibility: 'Business logic A' }, { name: 'Service 2', responsibility: 'Business logic B' }, { name: 'Database', type: 'SQL', responsibility: 'Data storage' } ], relationships: [ { from: 'API Gateway', to: 'Service 1', type: 'REST' }, { from: 'API Gateway', to: 'Service 2', type: 'REST' }, { from: 'Service 1', to: 'Database', type: 'ORM' }, { from: 'Service 2', to: 'Database', type: 'ORM' } ] }; } async createUXDesign(description, type = 'wireframe', platform = 'web') { // In a real implementation, this would generate actual wireframes or mockups // For now, return a description of what would be generated return { type, platform, elements: [ { type: 'header', content: 'Application Title' }, { type: 'navigation', items: ['Home', 'Products', 'About', 'Contact'] }, { type: 'content', description: 'Main content area with featured items' }, { type: 'footer', content: 'Copyright and links' } ], wireframeText: ` # Wireframe for ${platform} application ## Elements - Header with title and logo - Navigation menu with key sections - Main content area - Footer with links and copyright Based on: ${description} ` }; } async generateCode(specification, language, framework = null, patterns = []) { // Generate code based on specifications const code = `// Generated ${language} code for specification // Using ${framework || 'no specific framework'} // Applied patterns: ${patterns.join(', ') || 'none'} // This would be actual generated code in a real implementation function exampleFunction() { console.log("Hello from generated code"); } `; return { language, framework, patterns, code }; } async refactorCode(code, language, objectives) { // Apply refactoring based on objectives const refactoredCode = `// Refactored ${language} code // Improved for: ${objectives.join(', ')} // This would be actually refactored code in a real implementation function improvedFunction() { console.log("Hello from refactored code"); } `; return { original: code, refactored: refactoredCode, improvements: objectives.map(obj => ({ objective: obj, changes: [`Applied ${obj} improvement`] })) }; } async generateDocumentation(content, type, format = 'markdown') { // Generate documentation based on content and type // Format prefix based on output format const formatPrefix = format === 'markdown' ? '#' : format === 'html' ? '<h1>' : ''; const formatSuffix = format === 'html' ? '</h1>' : ''; const documentation = `${formatPrefix} Documentation for ${type} ${formatSuffix} This is an example of generated documentation. The actual implementation would analyze the provided content and generate appropriate documentation. ## Content Analysis - Type: ${type} - Format: ${format} - Content Length: ${content.length} characters `; return { type, format, content: documentation }; } async generateTestCases(input, type, framework = null) { // Generate test cases based on input // Example test cases for different test types const testCases = { unit: [ { id: 'TC001', name: 'Test function input validation', steps: ['...'] }, { id: 'TC002', name: 'Test calculation logic', steps: ['...'] } ], integration: [ { id: 'TC101', name: 'Test API endpoint response', steps: ['...'] }, { id: 'TC102', name: 'Test database interaction', steps: ['...'] } ], system: [ { id: 'TC201', name: 'Test end-to-end workflow', steps: ['...'] }, { id: 'TC202', name: 'Test system performance', steps: ['...'] } ], acceptance: [ { id: 'TC301', name: 'Verify user registration', steps: ['...'] }, { id: 'TC302', name: 'Verify checkout process', steps: ['...'] } ] }; return { type, framework, testCases: testCases[type], coverage: '85%', // Example coverage metric testCode: `// Example test code for ${framework || 'standard'} framework describe('Example test suite', () => { it('should pass this test', () => { expect(true).toBe(true); }); });` }; } async analyzeCodeQuality(code, language, metrics) { // Analyze code quality based on metrics const results = {}; metrics.forEach(metric => { // This would implement actual code quality analysis results[metric] = { score: Math.floor(Math.random() * 100), issues: [ { severity: 'medium', description: `Example ${metric} issue` } ], recommendations: [ `Improve ${metric} by doing X` ] }; }); return { language, metrics: results, summary: 'Code quality analysis summary would go here', overallScore: Math.floor(Math.random() * 100) }; } async analyzeSecurityVulnerabilities(code, language, framework = null) { // Analyze security vulnerabilities // Example vulnerability types const vulnerabilityTypes = [ 'SQL Injection', 'Cross-Site Scripting', 'Authentication Issues', 'Authorization Issues', 'Data Exposure' ]; // Generate sample vulnerabilities const vulnerabilities = Array(Math.floor(Math.random() * 3) + 1).fill().map((_, idx) => { const type = vulnerabilityTypes[Math.floor(Math.random() * vulnerabilityTypes.length)]; return { id: `VUL-${idx + 1}`, type, severity: ['low', 'medium', 'high'][Math.floor(Math.random() * 3)], location: `Line ${Math.floor(Math.random() * 100) + 1}`, description: `Example ${type} vulnerability`, remediation: `Fix by implementing proper input validation` }; }); return { language, framework, vulnerabilities, summary: { total: vulnerabilities.length, highSeverity: vulnerabilities.filter(v => v.severity === 'high').length, mediumSeverity: vulnerabilities.filter(v => v.severity === 'medium').length, lowSeverity: vulnerabilities.filter(v => v.severity === 'low').length } }; } async decomposeTask(task, level, format) { // Decompose task into subtasks based on level // Number of subtasks based on detail level const subtaskCount = { high: 3, medium: 5, detailed: 8 }[level]; // Generate subtasks const subtasks = Array(subtaskCount).fill().map((_, idx) => ({ id: `ST-${idx + 1}`, description: `Subtask ${idx + 1} for "${task}"`, estimatedEffort: `${Math.floor(Math.random() * 8) + 1} hours`, dependencies: idx > 0 ? [`ST-${idx}`] : [] })); // Format output based on requested format if (format === 'json') { return { task, level, subtasks }; } else if (format === 'tree') { return { type: 'tree', content: ` - ${task} ${subtasks.map(st => `- ${st.id}: ${st.description} (${st.estimatedEffort})`).join('\n ')} ` }; } else { // Default list format return { type: 'list', content: ` # Task Decomposition for: ${task} ${subtasks.map(st => `* ${st.id}: ${st.description} (${st.estimatedEffort})`).join('\n ')} ` }; } } async estimateEffort(tasks, unitType) { // Estimate effort for tasks const complexityMultipliers = { low: 1, medium: 2, high: 3 }; // Generate estimates const estimates = tasks.map(task => { const complexity = task.complexity || 'medium'; const baseEstimate = Math.floor(Math.random() * 3) + 1; const estimate = baseEstimate * complexityMultipliers[complexity]; return { id: task.id, description: task.description, complexity, estimate: `${estimate} ${unitType}` }; }); // Calculate total const totalEstimate = estimates.reduce((sum, task) => { return sum + parseInt(task.estimate.split(' ')[0]); }, 0); return { tasks: estimates, totalEstimate: `${totalEstimate} ${unitType}`, confidence: 'medium', assumptions: [ 'Assumes team is familiar with the technology stack', 'Does not include time for meetings and administrative tasks' ] }; } } // Export the classes and utility functions export { MCPSdlcTools, createToolResponse, imageContent };