mcp-ai-agent-guidelines
Version:
A comprehensive Model Context Protocol server providing professional tools, resources, and prompts for implementing AI agent best practices
391 lines (372 loc) • 15.7 kB
JavaScript
// Iterative Coverage Enhancement & Dead Code Elimination Tool
// Provides comprehensive analysis and actionable steps for improving code coverage
// while identifying and suggesting removal of dead code
import { z } from "zod";
import { buildReferencesSection } from "./shared/prompt-utils.js";
const IterativeCoverageEnhancerSchema = z.object({
// Analysis Configuration
projectPath: z.string().optional().default("."),
language: z.string().default("typescript"),
framework: z.string().optional(),
// Coverage Analysis Options
analyzeCoverageGaps: z.boolean().optional().default(true),
detectDeadCode: z.boolean().optional().default(true),
generateTestSuggestions: z.boolean().optional().default(true),
adaptThresholds: z.boolean().optional().default(true),
// Current Coverage Data (from tools like vitest, jest, etc.)
currentCoverage: z
.object({
statements: z.number().min(0).max(100),
functions: z.number().min(0).max(100),
lines: z.number().min(0).max(100),
branches: z.number().min(0).max(100),
})
.optional(),
// Target Coverage Goals
targetCoverage: z
.object({
statements: z.number().min(0).max(100).optional(),
functions: z.number().min(0).max(100).optional(),
lines: z.number().min(0).max(100).optional(),
branches: z.number().min(0).max(100).optional(),
})
.optional(),
// Output Configuration
outputFormat: z
.enum(["markdown", "json", "text"])
.optional()
.default("markdown"),
includeReferences: z.boolean().optional().default(true),
includeCodeExamples: z.boolean().optional().default(true),
generateCIActions: z.boolean().optional().default(true),
});
export async function iterativeCoverageEnhancer(args) {
const input = IterativeCoverageEnhancerSchema.parse(args);
// Simulate coverage analysis (in real implementation, this would analyze actual code)
const analysis = await performCoverageAnalysis(input);
const sections = [
generateExecutiveSummary(analysis),
...(input.analyzeCoverageGaps
? [generateCoverageGapsSection(analysis.coverageGaps)]
: []),
...(input.detectDeadCode
? [generateDeadCodeSection(analysis.deadCode)]
: []),
...(input.generateTestSuggestions
? [generateTestSuggestionsSection(analysis.coverageGaps)]
: []),
...(input.adaptThresholds
? [
generateThresholdRecommendationsSection(analysis.thresholdRecommendations),
]
: []),
generateIterationPlanSection(analysis.iterationPlan),
...(input.generateCIActions ? [generateCIActionsSection()] : []),
];
const references = input.includeReferences
? buildReferencesSection([
"Coverage-driven development best practices: https://martinfowler.com/bliki/TestCoverage.html",
"Dead code elimination techniques: https://refactoring.guru/smells/dead-code",
"Test-driven development guide: https://testdriven.io/",
"The benefits of consistent testing: https://abseil.io/resources/swe-book/html/ch11.html#benefits_of_testing_code",
"GitHub’s Engineering System Success Playbook: https://resources.github.com/engineering-system-success-playbook/",
"Automated testing strategies: https://testing.googleblog.com/",
"Code coverage analysis: https://docs.github.com/en/actions/automating-builds-and-tests/about-continuous-integration",
])
: "";
const content = sections.join("\n\n") + (references ? `\n\n${references}` : "");
return {
content: [
{
type: "text",
text: content,
},
],
};
}
async function performCoverageAnalysis(input) {
// In a real implementation, this would:
// 1. Parse coverage reports (lcov, json, etc.)
// 2. Analyze source code for dead code
// 3. Generate test suggestions based on AST analysis
// 4. Calculate optimal threshold adjustments
const currentCov = input.currentCoverage || {
statements: 42.41,
functions: 26.98,
lines: 42.41,
branches: 88.29,
};
const targetCov = input.targetCoverage || {
statements: Math.min(currentCov.statements + 10, 95),
functions: Math.min(currentCov.functions + 15, 90),
lines: Math.min(currentCov.lines + 10, 95),
branches: Math.min(currentCov.branches + 5, 95),
};
// Mock coverage gaps analysis
const coverageGaps = [
{
file: "src/tools/example-tool.ts",
uncoveredLines: [45, 46, 67, 89, 92],
uncoveredFunctions: ["handleErrorCase", "validateInput"],
priority: "high",
effort: "medium",
testSuggestions: [
"Add test for error handling in handleErrorCase()",
"Test input validation edge cases",
"Add integration test for complete workflow",
],
},
{
file: "src/utils/helper-functions.ts",
uncoveredLines: [12, 13, 24],
uncoveredFunctions: ["formatOutput"],
priority: "medium",
effort: "low",
testSuggestions: [
"Test output formatting with different input types",
"Verify edge cases for empty/null inputs",
],
},
];
// Mock dead code detection
const deadCode = [
{
file: "src/utils/deprecated-helpers.ts",
type: "function",
name: "oldFormatFunction",
line: 15,
confidence: "high",
reason: "No references found, deprecated since v0.5.0",
},
{
file: "src/tools/legacy-tool.ts",
type: "import",
name: "unusedLibrary",
line: 3,
confidence: "medium",
reason: "Imported but never used in file",
},
];
// Mock threshold recommendations
const thresholdRecommendations = [
{
metric: "functions",
current: currentCov.functions,
recommended: Math.min(currentCov.functions + 5, 35),
rationale: "Gradual improvement targeting frequently used modules first",
},
{
metric: "statements",
current: currentCov.statements,
recommended: Math.min(currentCov.statements + 3, 50),
rationale: "Conservative increase to avoid coverage regression during development",
},
];
// Mock iteration plan
const iterationPlan = [
{
phase: 1,
description: "Dead Code Cleanup & High-Priority Gaps",
actions: [
"Remove identified dead code (2-3 hours)",
"Add tests for high-priority uncovered functions",
"Update coverage thresholds incrementally",
],
expectedImpact: {
coverageIncrease: 4.5,
deadCodeReduction: 80,
},
timeEstimate: "1-2 days",
},
{
phase: 2,
description: "Medium Priority Coverage Expansion",
actions: [
"Add tests for remaining uncovered utility functions",
"Implement integration tests for key workflows",
"Review and adjust coverage thresholds",
],
expectedImpact: {
coverageIncrease: 6.2,
deadCodeReduction: 20,
},
timeEstimate: "2-3 days",
},
];
return {
currentCoverage: currentCov,
targetCoverage: targetCov,
coverageGaps,
deadCode,
thresholdRecommendations,
iterationPlan,
};
}
function generateExecutiveSummary(analysis) {
const { currentCoverage, targetCoverage, coverageGaps, deadCode } = analysis;
return `# 🎯 Iterative Coverage Enhancement Report
## Executive Summary
| Metric | Current | Target | Gap |
|--------|---------|--------|-----|
| **Statements** | ${currentCoverage.statements.toFixed(1)}% | ${targetCoverage.statements?.toFixed(1) || "N/A"}% | ${targetCoverage.statements ? (targetCoverage.statements - currentCoverage.statements).toFixed(1) : "N/A"}% |
| **Functions** | ${currentCoverage.functions.toFixed(1)}% | ${targetCoverage.functions?.toFixed(1) || "N/A"}% | ${targetCoverage.functions ? (targetCoverage.functions - currentCoverage.functions).toFixed(1) : "N/A"}% |
| **Lines** | ${currentCoverage.lines.toFixed(1)}% | ${targetCoverage.lines?.toFixed(1) || "N/A"}% | ${targetCoverage.lines ? (targetCoverage.lines - currentCoverage.lines).toFixed(1) : "N/A"}% |
| **Branches** | ${currentCoverage.branches.toFixed(1)}% | ${targetCoverage.branches?.toFixed(1) || "N/A"}% | ${targetCoverage.branches ? (targetCoverage.branches - currentCoverage.branches).toFixed(1) : "N/A"}% |
### 📊 Analysis Results
- **Coverage Gaps Identified**: ${coverageGaps.length} files with uncovered code
- **Dead Code Detected**: ${deadCode.length} items ready for removal
- **Priority Actions**: ${coverageGaps.filter((g) => g.priority === "high").length} high-priority improvements
- **Estimated Cleanup Impact**: ${deadCode.filter((d) => d.confidence === "high").length} high-confidence removals`;
}
function generateCoverageGapsSection(gaps) {
const highPriority = gaps.filter((g) => g.priority === "high");
const mediumPriority = gaps.filter((g) => g.priority === "medium");
const lowPriority = gaps.filter((g) => g.priority === "low");
let section = `## 🔍 Coverage Gaps Analysis
### High Priority Gaps (${highPriority.length})`;
for (const gap of highPriority) {
section += `
#### ${gap.file}
- **Uncovered Lines**: ${gap.uncoveredLines.join(", ")}
- **Uncovered Functions**: ${gap.uncoveredFunctions.join(", ")}
- **Effort**: ${gap.effort}
- **Test Suggestions**:
${gap.testSuggestions.map((s) => ` - ${s}`).join("\n")}`;
}
if (mediumPriority.length > 0) {
section += `\n\n### Medium Priority Gaps (${mediumPriority.length})`;
for (const gap of mediumPriority) {
section += `\n- **${gap.file}**: ${gap.uncoveredFunctions.length} functions, ${gap.uncoveredLines.length} lines`;
}
}
if (lowPriority.length > 0) {
section += `\n\n### Low Priority Gaps (${lowPriority.length})`;
section += `\n*These can be addressed in future iterations.*`;
}
return section;
}
function generateDeadCodeSection(deadCode) {
const highConfidence = deadCode.filter((d) => d.confidence === "high");
const mediumConfidence = deadCode.filter((d) => d.confidence === "medium");
let section = `## 🗑️ Dead Code Detection
### High Confidence Removals (${highConfidence.length})`;
for (const item of highConfidence) {
section += `
#### ${item.file}:${item.line}
- **Type**: ${item.type}
- **Name**: \`${item.name}\`
- **Reason**: ${item.reason}`;
}
if (mediumConfidence.length > 0) {
section += `\n\n### Medium Confidence Removals (${mediumConfidence.length})`;
section += `\n*Review these manually before removal:*`;
for (const item of mediumConfidence) {
section += `\n- **${item.file}:${item.line}** - \`${item.name}\` (${item.reason})`;
}
}
return section;
}
function generateTestSuggestionsSection(gaps) {
let section = `## 🧪 Test Generation Suggestions
### Prioritized Test Development`;
const allSuggestions = gaps.flatMap((g) => g.testSuggestions.map((s) => ({
file: g.file,
suggestion: s,
priority: g.priority,
effort: g.effort,
})));
const byPriority = {
high: allSuggestions.filter((s) => s.priority === "high"),
medium: allSuggestions.filter((s) => s.priority === "medium"),
low: allSuggestions.filter((s) => s.priority === "low"),
};
for (const [priority, suggestions] of Object.entries(byPriority)) {
if (suggestions.length > 0) {
section += `\n\n#### ${priority.charAt(0).toUpperCase() + priority.slice(1)} Priority`;
for (const { file, suggestion } of suggestions) {
section += `\n- **${file}**: ${suggestion}`;
}
}
}
return section;
}
function generateThresholdRecommendationsSection(recommendations) {
let section = `## ⚙️ Adaptive Threshold Recommendations
### Proposed Coverage Threshold Updates`;
for (const rec of recommendations) {
section += `
#### ${rec.metric.charAt(0).toUpperCase() + rec.metric.slice(1)}
- **Current**: ${rec.current.toFixed(1)}%
- **Recommended**: ${rec.recommended.toFixed(1)}%
- **Rationale**: ${rec.rationale}`;
}
section += `\n\n### Configuration Update
\`\`\`typescript
// vitest.config.ts or similar
thresholds: {
${recommendations.map((r) => ` ${r.metric}: ${Math.floor(r.recommended)}, // ${r.rationale}`).join("\n")}
}
\`\`\``;
return section;
}
function generateIterationPlanSection(plan) {
let section = `## 📋 Iterative Enhancement Plan`;
for (const phase of plan) {
section += `
### Phase ${phase.phase}: ${phase.description}
**Timeline**: ${phase.timeEstimate}
**Actions**:
${phase.actions.map((a) => `- ${a}`).join("\n")}
**Expected Impact**:
- Coverage increase: +${phase.expectedImpact.coverageIncrease.toFixed(1)}%
- Dead code reduction: ${phase.expectedImpact.deadCodeReduction}%`;
}
return section;
}
function generateCIActionsSection() {
return `## 🔄 CI/CD Integration Actions
### GitHub Actions Workflow Example
\`\`\`yaml
name: Iterative Coverage Enhancement
on:
schedule:
- cron: '0 2 * * 1' # Weekly on Monday
workflow_dispatch:
jobs:
coverage-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run coverage analysis
run: npm run test:coverage:vitest
- name: Generate coverage enhancement report
run: |
npx mcp-ai-agent-guidelines iterative-coverage-enhancer \\
--current-coverage-from-file coverage/coverage-summary.json \\
--generate-ci-actions true
- name: Create PR if improvements found
# Add logic to create PR with suggested improvements
\`\`\`
### Automated Threshold Updates
The system can automatically adjust coverage thresholds based on:
- Current project velocity
- Historical coverage trends
- Dead code removal impact
- Team capacity and priorities
### Integration with Existing Tools
- **Coverage Reports**: Integrates with vitest, jest, nyc, c8, pytest-cov, coverage
- **Dead Code Detection**: AST analysis, dependency graph analysis
- **Test Generation**: Template-based test stub creation
- **Threshold Management**: Dynamic adjustment based on project metrics
### Further Information ℹ️
- [GitHub’s Engineering System Success Playbook](https://resources.github.com/engineering-system-success-playbook/)
- [GitHub Workflow Syntax](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax?search-overlay-input=coverage&search-overlay-ask-ai=true)
- [GitHub Copilot for Coverage](https://docs.github.com/en/copilot/tutorials/roll-out-at-scale/drive-downstream-impact/increase-test-coverage)`;
}
//# sourceMappingURL=iterative-coverage-enhancer.js.map