UNPKG

cortexweaver

Version:

CortexWeaver is a command-line interface (CLI) tool that orchestrates a swarm of specialized AI agents, powered by Claude Code and Gemini CLI, to assist in software development. It transforms a high-level project plan (plan.md) into a series of coordinate

221 lines (217 loc) 9.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TestResultDocumenterAgent = void 0; const agent_1 = require("../agent"); class TestResultDocumenterAgent extends agent_1.Agent { async initialize(config) { await super.initialize(config); if (!config.capabilities.includes('test-analysis')) { throw new Error('Test Result Documenter agent requires test-analysis capability'); } } async executeTask() { if (!this.currentTask || !this.taskContext) { throw new Error('No task or context available'); } this.validateTaskSpecification(); this.validateTestResultsAvailable(); await this.reportProgress('started', 'Beginning test result documentation'); try { const testResults = this.taskContext.testResults; const coverageData = testResults.coverage; const historicalData = await this.queryHistoricalTestData(); const documentationContent = await this.generateTestDocumentation(testResults, historicalData); const results = { testSummary: documentationContent.summary, coverageReport: documentationContent.coverage, failureAnalysis: this.analyzeFailures(testResults.failures || []), trendAnalysis: documentationContent.trends, recommendations: documentationContent.recommendations, charts: this.generateCharts(testResults, coverageData), metadata: { totalTests: testResults.totalTests || 0, passRate: testResults.passRate || 0, coveragePercentage: coverageData?.overall || 0, generatedAt: new Date().toISOString() } }; await this.storeTestReport(results); await this.reportProgress('completed', 'Test documentation generated successfully'); return results; } catch (error) { await this.reportProgress('failed', `Documentation generation failed: ${error.message}`); throw error; } } getPromptTemplate() { return `Test Documentation Agent: Generate comprehensive test reports with coverage analysis, failure categorization, trend analysis, and actionable recommendations. Context: {{testResults}}, Historical: {{historicalData}}.`; } validateTaskSpecification() { const requiredFields = ['testResults']; for (const field of requiredFields) { if (!this.taskContext?.[field]) { throw new Error(`Missing required field: ${field}`); } } } validateTestResultsAvailable() { if (!this.taskContext?.testResults) { throw new Error('No test results available for documentation'); } } async queryHistoricalTestData() { try { const projectId = this.taskContext?.projectId || 'unknown'; const reports = []; return this.processHistoricalData(reports); } catch (error) { console.warn('Failed to query historical test data:', error.message); return { trends: [], averages: {} }; } } processHistoricalData(reports) { if (!reports.length) return { trends: [], averages: {} }; const trends = reports.slice(-10).map(report => ({ date: report.generatedAt, passRate: report.metadata?.passRate || 0, coverage: report.metadata?.coveragePercentage || 0, totalTests: report.metadata?.totalTests || 0 })); const averages = { passRate: trends.reduce((sum, t) => sum + t.passRate, 0) / trends.length, coverage: trends.reduce((sum, t) => sum + t.coverage, 0) / trends.length }; return { trends, averages }; } async generateTestDocumentation(testResults, historicalData) { const promptContext = { testResults: JSON.stringify(testResults, null, 2), historicalData: JSON.stringify(historicalData, null, 2), projectName: this.taskContext?.projectName || 'Unknown Project' }; const prompt = this.formatPrompt(this.getPromptTemplate(), promptContext) + ` TEST RESULTS: ${JSON.stringify(testResults, null, 2)} HISTORICAL DATA: ${JSON.stringify(historicalData, null, 2)} Generate comprehensive test documentation including: 1. Executive summary of test results 2. Detailed coverage analysis with insights 3. Trend analysis comparing to historical data 4. Specific recommendations for improvement 5. Risk assessment and priority actions Format as structured JSON with summary, coverage, trends, and recommendations fields.`; const response = await this.sendToClaude(prompt); return this.parseDocumentationResponse(response.content); } parseDocumentationResponse(content) { try { const jsonMatch = content.match(/\{[\s\S]*\}/); if (jsonMatch) { return JSON.parse(jsonMatch[0]); } } catch (error) { console.warn('Failed to parse structured response, using fallback'); } return { summary: this.extractSection(content, 'summary') || 'Test results documented', coverage: this.extractSection(content, 'coverage') || 'Coverage analysis completed', trends: this.extractSection(content, 'trends') || 'Trend analysis performed', recommendations: this.extractRecommendations(content) }; } extractSection(content, section) { const regex = new RegExp(`${section}:?\\s*([^\\n]*(?:\\n(?!\\w+:)[^\\n]*)*)`, 'i'); const match = content.match(regex); return match ? match[1].trim() : ''; } extractRecommendations(content) { const lines = content.split('\n'); const recommendations = []; let inRecommendations = false; for (const line of lines) { if (line.toLowerCase().includes('recommendation')) { inRecommendations = true; continue; } if (inRecommendations && line.trim()) { if (line.match(/^\d+\.|\-|\*/)) { recommendations.push(line.trim()); } else if (!line.includes(':')) { recommendations.push(line.trim()); } } } return recommendations.length > 0 ? recommendations : ['Continue monitoring test health']; } analyzeFailures(failures) { return failures.map(failure => ({ testName: failure.name || 'Unknown test', reason: failure.message || 'Test failed', stackTrace: failure.stack, category: this.categorizeFailure(failure), priority: this.prioritizeFailure(failure) })); } categorizeFailure(failure) { const message = (failure.message || '').toLowerCase(); if (message.includes('timeout')) return 'timeout'; if (message.includes('assertion') || message.includes('expect')) return 'assertion'; if (message.includes('network') || message.includes('connection')) return 'network'; if (message.includes('permission') || message.includes('auth')) return 'permission'; return 'unknown'; } prioritizeFailure(failure) { const message = (failure.message || '').toLowerCase(); if (message.includes('critical') || message.includes('security')) return 'high'; if (message.includes('performance') || message.includes('timeout')) return 'medium'; return 'low'; } generateCharts(testResults, coverageData) { const charts = []; if (testResults.passed && testResults.failed) { charts.push({ type: 'pie', title: 'Test Results Distribution', data: [ { label: 'Passed', value: testResults.passed, color: '#28a745' }, { label: 'Failed', value: testResults.failed, color: '#dc3545' } ] }); } if (coverageData?.details) { charts.push({ type: 'bar', title: 'Coverage by Type', data: coverageData.details.map(detail => ({ label: detail.type, value: detail.percentage, color: detail.percentage > 80 ? '#28a745' : detail.percentage > 60 ? '#ffc107' : '#dc3545' })) }); } return charts; } async storeTestReport(results) { try { const projectId = this.taskContext?.projectId || 'unknown'; // Storage would be implemented here } catch (error) { console.warn('Failed to store test report:', error.message); } } } exports.TestResultDocumenterAgent = TestResultDocumenterAgent; //# sourceMappingURL=test-result-documenter.js.map