UNPKG

mcp-adr-analysis-server

Version:

MCP server for analyzing Architectural Decision Records and project architecture

476 lines (437 loc) 19.7 kB
/** * Research question generation utilities using prompt-driven AI analysis * Implements intelligent research question generation and task tracking */ import { McpAdrError } from '../types/index.js'; /** * Correlate problems with knowledge graph */ export async function correlateProblemKnowledge(problems, knowledgeGraph) { try { const { generateProblemKnowledgeCorrelationPrompt } = await import('../prompts/research-question-prompts.js'); const correlationPrompt = generateProblemKnowledgeCorrelationPrompt(problems, knowledgeGraph); const instructions = ` # Problem-Knowledge Correlation Instructions This analysis will correlate identified problems with the architectural knowledge graph to identify research opportunities. ## Correlation Analysis - **Problems**: ${problems.length} problems identified - **Technologies**: ${knowledgeGraph.technologies.length} technologies in knowledge graph - **Patterns**: ${knowledgeGraph.patterns.length} patterns in knowledge graph - **ADRs**: ${knowledgeGraph.adrs.length} ADRs in knowledge graph - **Relationships**: ${knowledgeGraph.relationships.length} relationships mapped ## Next Steps 1. **Submit the correlation prompt** to an AI agent for comprehensive analysis 2. **Parse the JSON response** to get correlation analysis and research opportunities 3. **Review knowledge gaps** and prioritize research areas 4. **Use findings** to generate targeted research questions ## Expected AI Response Format The AI will return a JSON object with: - \`correlationAnalysis\`: Overall correlation statistics and confidence - \`problemCorrelations\`: Detailed problem-knowledge correlations - \`knowledgeGaps\`: Identified gaps in the knowledge graph - \`researchOpportunities\`: Prioritized research opportunities - \`recommendations\`: Actionable recommendations for research planning ## Usage Example \`\`\`typescript const result = await correlateProblemKnowledge(problems, knowledgeGraph); // Submit result.correlationPrompt to AI agent // Parse AI response for correlation analysis \`\`\` `; return { correlationPrompt, instructions, }; } catch (error) { throw new McpAdrError(`Failed to correlate problems with knowledge: ${error instanceof Error ? error.message : String(error)}`, 'CORRELATION_ERROR'); } } /** * Find relevant ADRs and patterns for research context */ export async function findRelevantAdrPatterns(researchContext, adrDirectory = 'docs/adrs') { try { // Use actual ADR discovery instead of prompts const { discoverAdrsInDirectory } = await import('./adr-discovery.js'); // Actually read ADR files const discoveryResult = await discoverAdrsInDirectory(adrDirectory, true, process.cwd()); // Extract patterns from project (simplified for this implementation) const availablePatterns = extractArchitecturalPatterns(); const relevancePrompt = ` # Relevant ADR Pattern Identification Based on actual ADR file analysis, here are the discovered ADRs with their full content: ## Discovered ADRs (${discoveryResult.totalAdrs} total) ${discoveryResult.adrs.length > 0 ? discoveryResult.adrs.map((adr, index) => ` ### ${index + 1}. ${adr.title} - **File**: ${adr.filename} - **Status**: ${adr.status} - **Path**: ${adr.path} ${adr.metadata?.number ? `- **Number**: ${adr.metadata.number}` : ''} #### ADR Content: \`\`\`markdown ${adr.content || 'Content not available'} \`\`\` --- `).join('\n') : 'No ADRs found in the specified directory.'} ## Research Context Analysis **Topic**: ${researchContext.topic} **Category**: ${researchContext.category} **Scope**: ${researchContext.scope} **Objectives**: ${researchContext.objectives.join(', ')} **Constraints**: ${researchContext.constraints?.join(', ') || 'None specified'} **Timeline**: ${researchContext.timeline || 'Not specified'} ## Available Architectural Patterns ${availablePatterns.map((pattern, index) => ` ### ${index + 1}. ${pattern.name} - **Category**: ${pattern.category} - **Description**: ${pattern.description} - **Applications**: Various architectural applications `).join('')} ## Pattern Relevance Assessment For each discovered ADR and available pattern: 1. Analyze relevance to the research context based on **actual ADR content** 2. Identify potential applications and benefits 3. Assess implementation complexity and trade-offs 4. Generate specific recommendations for adoption 5. Prioritize patterns by impact and feasibility `; const instructions = ` # Relevant ADR and Pattern Discovery Instructions This analysis provides **actual ADR content** to identify ADRs and patterns relevant to the research context. ## Discovery Scope - **Research Topic**: ${researchContext.topic} - **Research Category**: ${researchContext.category} - **ADR Directory**: ${adrDirectory} - **ADRs Found**: ${discoveryResult.totalAdrs} files - **ADRs with Content**: ${discoveryResult.adrs.filter(adr => adr.content).length} ADRs - **Available Patterns**: ${availablePatterns.length} patterns - **Research Objectives**: ${researchContext.objectives.length} objectives ## Discovered ADR Summary ${discoveryResult.adrs.map(adr => `- **${adr.title}** (${adr.status})`).join('\n')} ## Next Steps 1. **Submit the relevance prompt** to an AI agent for analysis based on **actual ADR content** 2. **Parse the JSON response** to get relevant ADRs and patterns 3. **Review research implications** and constraints 4. **Use findings** to inform research question generation ## Expected AI Response Format The AI will return a JSON object with: - \`relevanceAnalysis\`: Overall relevance statistics and confidence based on actual content - \`relevantAdrs\`: ADRs relevant to the research context with specific reasoning - \`relevantPatterns\`: Patterns applicable to the research with evidence from ADRs - \`researchImplications\`: Constraints, opportunities, dependencies, conflicts derived from ADR content - \`researchGuidance\`: Specific guidance for research approach based on existing decisions ## Usage Example \`\`\`typescript const result = await findRelevantAdrPatterns(researchContext, adrDirectory); // Submit result.relevancePrompt to AI agent // Parse AI response for relevant knowledge based on actual ADR content \`\`\` `; return { relevancePrompt, instructions, }; } catch (error) { throw new McpAdrError(`Failed to find relevant ADRs and patterns: ${error instanceof Error ? error.message : String(error)}`, 'RELEVANCE_ANALYSIS_ERROR'); } } /** * Generate context-aware research questions */ export async function generateContextAwareQuestions(researchContext, relevantKnowledge, projectPath = process.cwd()) { try { // Use actual file operations to scan project structure const { scanProjectStructure } = await import('./actual-file-operations.js'); const { generateContextAwareResearchQuestionsPrompt } = await import('../prompts/research-question-prompts.js'); // Actually scan project context const projectStructure = await scanProjectStructure(projectPath, { readContent: false }); const projectContext = { technologies: extractTechnologiesFromStructure(projectStructure), architecture: inferArchitectureType(projectStructure), domain: inferDomainType(projectStructure), scale: inferProjectScale(projectStructure), }; // Generate file creation prompts for research questions const timestamp = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format const researchFileName = `research-questions-${timestamp}.md`; const researchDir = `${projectPath}/docs/research`; const researchFilePath = `${researchDir}/${researchFileName}`; const questionPrompt = generateContextAwareResearchQuestionsPrompt({ ...researchContext, constraints: researchContext.constraints || [], timeline: researchContext.timeline || 'Not specified', }, relevantKnowledge, projectContext); const instructions = ` # Context-Aware Research Question Generation Instructions This analysis will generate specific, actionable research questions based on comprehensive context analysis and save them to the docs/research directory. ## Question Generation Context - **Research Topic**: ${researchContext.topic} - **Project Technologies**: ${projectContext.technologies.join(', ')} - **Architecture Type**: ${projectContext.architecture} - **Domain**: ${projectContext.domain} - **Project Scale**: ${projectContext.scale} - **Total Files**: ${projectStructure.totalFiles} - **Directories**: ${projectStructure.directories.length} - **Relevant ADRs**: ${relevantKnowledge.adrs.length} - **Relevant Patterns**: ${relevantKnowledge.patterns.length} - **Knowledge Gaps**: ${relevantKnowledge.gaps.length} - **Research Opportunities**: ${relevantKnowledge.opportunities.length} ## File Creation Requirements ### Step 1: Create Research Directory Ensure the research directory exists: ${researchDir} ### Step 2: Generate Research Questions Execute the research question generation prompt below to create comprehensive research questions. ### Step 3: Save Research Questions to File After generating the research questions, create a research questions file: **File Path**: ${researchFilePath} **File Name**: ${researchFileName} The file should contain: - Generated research questions in structured markdown format - Research plan with timelines and priorities - Methodology and approach details - Quality assurance criteria - Expected outcomes and impact ## Next Steps 1. **Ensure docs/research directory exists** before proceeding 2. **Submit the question prompt** to an AI agent for comprehensive question generation 3. **Parse the JSON response** to get structured research questions 4. **Create markdown file** with the research questions at ${researchFilePath} 5. **Review research plan** and prioritize questions 6. **Create research tasks** using the task tracking system ## Expected AI Response Format The AI will return a JSON object with: - \`researchQuestionGeneration\`: Generation metadata and quality metrics - \`primaryQuestions\`: Core research questions with detailed specifications - \`secondaryQuestions\`: Supporting questions for comprehensive coverage - \`methodologicalQuestions\`: Questions about research approach and methodology - \`researchPlan\`: Phased research plan with timelines and dependencies - \`qualityAssurance\`: Quality assurance and validation approach - \`expectedImpact\`: Expected impact and benefits of the research ## File Persistence After generating the research questions, the AI agent must: 1. **Format the questions** into a structured markdown document 2. **Create the research file** at: ${researchFilePath} 3. **Include all generated content** in the file for future reference 4. **Confirm file creation** and provide file location ## Usage Example \`\`\`typescript const result = await generateContextAwareQuestions(context, knowledge, projectPath); // 1. Execute directory creation prompt // 2. Submit result.questionPrompt to AI agent // 3. Parse AI response for research questions and plan // 4. Create markdown file with research questions \`\`\` `; return { questionPrompt, instructions, }; } catch (error) { throw new McpAdrError(`Failed to generate context-aware questions: ${error instanceof Error ? error.message : String(error)}`, 'QUESTION_GENERATION_ERROR'); } } /** * Create research task tracking system */ export async function createResearchTaskTracking(researchQuestions, currentProgress) { try { const { generateResearchTaskTrackingPrompt } = await import('../prompts/research-question-prompts.js'); const trackingPrompt = generateResearchTaskTrackingPrompt(researchQuestions, currentProgress); const instructions = ` # Research Task Tracking Instructions This analysis will create a comprehensive task tracking and management system for research execution. ## Tracking Scope - **Research Questions**: ${researchQuestions.length} questions to track - **Current Progress**: ${currentProgress?.length || 0} progress entries - **Question Types**: ${Array.from(new Set(researchQuestions.map(q => q.type))).join(', ')} - **Priority Levels**: ${Array.from(new Set(researchQuestions.map(q => q.priority))).join(', ')} ## Next Steps 1. **Submit the tracking prompt** to an AI agent for system creation 2. **Parse the JSON response** to get comprehensive tracking system 3. **Implement tracking** in project management tools 4. **Begin research execution** with regular progress updates ## Expected AI Response Format The AI will return a JSON object with: - \`researchTaskTracking\`: Overall tracking metadata and configuration - \`researchTasks\`: Detailed tasks with progress tracking and dependencies - \`milestones\`: Key milestones and checkpoints - \`riskManagement\`: Risk identification and mitigation strategies - \`progressMetrics\`: Quantitative progress measurements - \`communicationPlan\`: Stakeholder communication and reporting - \`qualityAssurance\`: Quality control and validation processes - \`recommendations\`: Process and management recommendations ## Usage Example \`\`\`typescript const result = await createResearchTaskTracking(questions, progress); // Submit result.trackingPrompt to AI agent // Parse AI response for task tracking system \`\`\` `; return { trackingPrompt, instructions, }; } catch (error) { throw new McpAdrError(`Failed to create research task tracking: ${error instanceof Error ? error.message : String(error)}`, 'TASK_TRACKING_ERROR'); } } /** * Extract technologies from project structure */ function extractTechnologiesFromStructure(projectStructure) { const technologies = []; // Analyze package files for technologies if (projectStructure.packageFiles) { projectStructure.packageFiles.forEach((file) => { if (file.filename === 'package.json' && file.content) { try { const packageData = JSON.parse(file.content); if (packageData.dependencies) { Object.keys(packageData.dependencies).forEach(dep => { if (dep.includes('react')) technologies.push('React'); if (dep.includes('vue')) technologies.push('Vue'); if (dep.includes('angular')) technologies.push('Angular'); if (dep.includes('express')) technologies.push('Express.js'); if (dep.includes('typescript')) technologies.push('TypeScript'); }); } } catch { // Invalid JSON, skip } } if (file.filename === 'requirements.txt') technologies.push('Python'); if (file.filename === 'Cargo.toml') technologies.push('Rust'); if (file.filename === 'go.mod') technologies.push('Go'); if (file.filename === 'pom.xml') technologies.push('Java/Maven'); }); } // Analyze config files if (projectStructure.configFiles) { projectStructure.configFiles.forEach((file) => { if (file.filename === 'tsconfig.json') technologies.push('TypeScript'); if (file.filename.includes('webpack')) technologies.push('Webpack'); if (file.filename.includes('vite')) technologies.push('Vite'); }); } // Analyze Docker files if (projectStructure.dockerFiles && projectStructure.dockerFiles.length > 0) { technologies.push('Docker'); } // Analyze Kubernetes files if (projectStructure.kubernetesFiles && projectStructure.kubernetesFiles.length > 0) { technologies.push('Kubernetes'); } // Analyze CI files if (projectStructure.ciFiles && projectStructure.ciFiles.length > 0) { technologies.push('CI/CD'); } return [...new Set(technologies)]; // Remove duplicates } /** * Extract architectural patterns from project structure */ function extractArchitecturalPatterns() { // Simplified pattern extraction - in a real implementation, this would be more sophisticated return [ { name: 'Microservices Architecture', description: 'Distributed architecture with independent services', category: 'architectural', }, { name: 'Layered Architecture', description: 'Hierarchical organization of components', category: 'architectural', }, { name: 'Event-Driven Architecture', description: 'Asynchronous communication through events', category: 'architectural', }, { name: 'Repository Pattern', description: 'Data access abstraction pattern', category: 'design', }, { name: 'Factory Pattern', description: 'Object creation abstraction pattern', category: 'design', }, ]; } /** * Infer architecture type from project structure */ function inferArchitectureType(projectStructure) { const directories = projectStructure.directories || []; if (directories.some((dir) => dir.includes('service') || dir.includes('microservice'))) { return 'microservices'; } if (directories.some((dir) => dir.includes('layer') || dir.includes('tier'))) { return 'layered'; } if (projectStructure.kubernetesFiles?.length > 0 || projectStructure.dockerFiles?.length > 0) { return 'cloud-native'; } if (directories.some((dir) => dir.includes('component') || dir.includes('module'))) { return 'modular'; } return 'monolithic'; } /** * Infer domain type from project structure */ function inferDomainType(projectStructure) { const technologies = extractTechnologiesFromStructure(projectStructure); if (technologies.some((tech) => tech.toLowerCase().includes('react') || tech.toLowerCase().includes('vue') || tech.toLowerCase().includes('angular'))) { return 'web-application'; } if (technologies.some((tech) => tech.toLowerCase().includes('express') || tech.toLowerCase().includes('api'))) { return 'api-service'; } if (technologies.some((tech) => tech.toLowerCase().includes('data') || tech.toLowerCase().includes('analytics'))) { return 'data-platform'; } if (projectStructure.dockerFiles?.length > 0 || projectStructure.kubernetesFiles?.length > 0) { return 'infrastructure-platform'; } return 'general-software'; } /** * Infer project scale from project structure */ function inferProjectScale(projectStructure) { const fileCount = projectStructure.totalFiles || 0; const dirCount = projectStructure.directories?.length || 0; if (fileCount > 1000 || dirCount > 100) { return 'enterprise'; } if (fileCount > 100 || dirCount > 20) { return 'medium'; } return 'small'; } //# sourceMappingURL=research-questions.js.map