claude-flow-novice 2.2.4 ā 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -8
- package/scripts/.claude-flow/metrics/agent-metrics.json +1 -0
- package/scripts/.claude-flow/metrics/performance.json +9 -0
- package/scripts/.claude-flow/metrics/task-metrics.json +10 -0
- package/scripts/CLEANUP_OPTIMIZATION_REPORT.json +312 -0
- package/scripts/CLEANUP_PERFORMANCE_OPTIMIZATION.md +387 -0
- package/scripts/CLEANUP_QUICK_START.md +268 -0
- package/scripts/CLEANUP_TEST_RESULTS.md +205 -0
- package/scripts/README.md +339 -0
- package/scripts/ace-query.sh +384 -0
- package/scripts/agent-token-analysis.js +430 -0
- package/scripts/auto-setup.js +332 -0
- package/scripts/build/README.md +167 -0
- package/scripts/build/build-config.js +27 -0
- package/scripts/build/build-prompt-copier.sh +30 -0
- package/scripts/build/performance-monitor.js +869 -0
- package/scripts/build/prepare-publish.js +150 -0
- package/scripts/build/typescript-fixer.js +621 -0
- package/scripts/build/unified-builder.sh +428 -0
- package/scripts/build/update-bin-version.js +32 -0
- package/scripts/build/validate-agents.js +238 -0
- package/scripts/build-index.js +43 -0
- package/scripts/build-orchestrator.js +320 -0
- package/scripts/check-routing-stats.cjs +122 -0
- package/scripts/ci-validation.js +375 -0
- package/scripts/cleanup-blocking-coordination.sh +420 -0
- package/scripts/cleanup-idle-sessions.sh +59 -0
- package/scripts/collect-build-metrics.js +65 -0
- package/scripts/demo/README.md +79 -0
- package/scripts/demo/autoscaling-demo-simplified.js +963 -0
- package/scripts/demo/comprehensive-dashboard-test.js +693 -0
- package/scripts/demo/confidence-log.js +87 -0
- package/scripts/demo/confidence-report.js +82 -0
- package/scripts/demo/demo-multi-swarm-coordination.js +325 -0
- package/scripts/demo/demo-production-deployment.js +399 -0
- package/scripts/demo/demo-visualization-system.js +149 -0
- package/scripts/demo/performance-analysis.cjs +71 -0
- package/scripts/demo/performance-analysis.js +71 -0
- package/scripts/demo/test-autoscaling-demo.js +314 -0
- package/scripts/dependency-optimizer.js +349 -0
- package/scripts/dependency-security-assessment.js +331 -0
- package/scripts/deploy-sdk.sh +176 -0
- package/scripts/deployment-readiness-report.json +179 -0
- package/scripts/dev/README.md +264 -0
- package/scripts/dev/claude-flow-wrapper.sh +35 -0
- package/scripts/dev/claude-monitor.py +419 -0
- package/scripts/dev/claude-sparc.sh +562 -0
- package/scripts/dev/claude-wrapper.sh +17 -0
- package/scripts/dev/demo-phase3-compliance.js +172 -0
- package/scripts/dev/demo-task-system.ts +224 -0
- package/scripts/dev/deployment-validator.js +315 -0
- package/scripts/dev/spawn-claude-terminal.sh +32 -0
- package/scripts/dev/start-portal.sh +506 -0
- package/scripts/dev/start-web-ui.js +15 -0
- package/scripts/dev/stop-portal.sh +311 -0
- package/scripts/dev/validate-examples.ts +288 -0
- package/scripts/dev/validate-phase2.cjs +451 -0
- package/scripts/dev/validate-phase2.js +785 -0
- package/scripts/dev/validate-phase3.cjs +208 -0
- package/scripts/dev/validate-security-remediation.js +1 -0
- package/scripts/ecosystem.config.cjs +90 -0
- package/scripts/fix-js-extensions.js +167 -0
- package/scripts/generate-basic-types.js +73 -0
- package/scripts/generate-changelog.js +318 -0
- package/scripts/git-hooks/pre-commit.sh +143 -0
- package/scripts/health-checks.js +634 -0
- package/scripts/hook-wrapper.sh +54 -0
- package/scripts/install/README.md +375 -0
- package/scripts/install/REDIS_SETUP_VALIDATION.json +245 -0
- package/scripts/install/check-prerequisites.js +303 -0
- package/scripts/install/config-wizard.js +606 -0
- package/scripts/install/dependency-checker.js +385 -0
- package/scripts/install/health-check.js +765 -0
- package/scripts/install/install.js +256 -0
- package/scripts/install/installation-benchmark.js +461 -0
- package/scripts/install/quick-install.js +720 -0
- package/scripts/install/quick-start-wizard.js +295 -0
- package/scripts/install/redis-cli.js +289 -0
- package/scripts/install/redis-install-guides.md +407 -0
- package/scripts/install/redis-setup.js +559 -0
- package/scripts/install/redis-test.js +278 -0
- package/scripts/install/service-manager.js +672 -0
- package/scripts/install/setup.js +832 -0
- package/scripts/install/uninstall.js +526 -0
- package/scripts/install/update.js +461 -0
- package/scripts/install-pre-commit-hook.sh +127 -0
- package/scripts/legacy/README.md +272 -0
- package/scripts/legacy/batch-fix-ts.sh +54 -0
- package/scripts/legacy/build-migration.sh +105 -0
- package/scripts/legacy/build-monitor.js +209 -0
- package/scripts/legacy/build-with-filter.sh +84 -0
- package/scripts/legacy/build-workaround.sh +71 -0
- package/scripts/legacy/fix-ts-advanced.js +358 -0
- package/scripts/legacy/fix-ts-final.sh +50 -0
- package/scripts/legacy/fix-ts-targeted.sh +49 -0
- package/scripts/legacy/fix-typescript-errors.js +305 -0
- package/scripts/legacy/force-build.sh +63 -0
- package/scripts/legacy/optimize-performance.js +400 -0
- package/scripts/legacy/performance-monitor.js +263 -0
- package/scripts/legacy/performance-monitoring.js +532 -0
- package/scripts/legacy/performance-test-runner.js +645 -0
- package/scripts/legacy/quick-fix-ts.js +281 -0
- package/scripts/legacy/safe-build.sh +63 -0
- package/scripts/memory-monitor-coordinator.js +322 -0
- package/scripts/migrate-to-sdk.sh +520 -0
- package/scripts/migration/QUICK-START.md +189 -0
- package/scripts/migration/QUICK-START.md.backup-1760135091363 +189 -0
- package/scripts/migration/README.md +464 -0
- package/scripts/migration/TASK-1.3.2-COMPLETION-REPORT.md +500 -0
- package/scripts/migration/TASK-1.3.2-COMPLETION-REPORT.md.backup-1760135091348 +500 -0
- package/scripts/migration/UPDATE-PATHS-README.md +464 -0
- package/scripts/migration/UPDATE-PATHS-README.md.backup-1760135091337 +464 -0
- package/scripts/migration/example-patterns.json +19 -0
- package/scripts/migration/install-arm64.js +78 -0
- package/scripts/migration/install.js +83 -0
- package/scripts/migration/migrate-hooks.js +173 -0
- package/scripts/migration/migration-examples.ts +318 -0
- package/scripts/migration/reorganize-workspace.js +504 -0
- package/scripts/migration/test-update-paths.js +359 -0
- package/scripts/migration/update-paths.js +664 -0
- package/scripts/migration/validate-migration.js +647 -0
- package/scripts/monitor-loop.sh +65 -0
- package/scripts/monitor-memory.sh +47 -0
- package/scripts/monitor-migration.js +339 -0
- package/scripts/monitor.py +43 -0
- package/scripts/monitoring/README.md +178 -0
- package/scripts/monitoring/alert-monitor.sh +220 -0
- package/scripts/monitoring/analyze-resources.sh +199 -0
- package/scripts/monitoring/dashboards/rate-limiting-dashboard.json +211 -0
- package/scripts/monitoring/dynamic-monitor.sh +85 -0
- package/scripts/monitoring/launch-stability-test.sh +184 -0
- package/scripts/monitoring/monitor-test.sh +93 -0
- package/scripts/monitoring/pre-test-validation.sh +208 -0
- package/scripts/monitoring/quick-test-alerting.sh +118 -0
- package/scripts/monitoring/quick-test-rate-limiting.sh +206 -0
- package/scripts/monitoring/rate-limiting-monitor.sh +380 -0
- package/scripts/monitoring/resource-monitor.sh +126 -0
- package/scripts/monitoring/stability-monitor.js +429 -0
- package/scripts/monitoring/test-monitor-quick.sh +54 -0
- package/scripts/monitoring/view-alerts.sh +307 -0
- package/scripts/npm-metrics-collector.js +482 -0
- package/scripts/npm-package-validation.cjs +299 -0
- package/scripts/optimization/build-optimizer.js +438 -0
- package/scripts/optimization/config-validator.js +761 -0
- package/scripts/optimization/test-optimization.js +432 -0
- package/scripts/optimization/unified-activation.js +839 -0
- package/scripts/optimize-package-swarm.js +54 -0
- package/scripts/performance/ACTIVATION_COMMANDS.md +292 -0
- package/scripts/performance/sqlite-enhanced-activation.sh +583 -0
- package/scripts/performance/test-enhanced-backend.sh +504 -0
- package/scripts/performance-monitor.js +644 -0
- package/scripts/performance-test-runner.js +698 -0
- package/scripts/post-deployment-monitoring.js +350 -0
- package/scripts/post-edit-pipeline.js +2091 -0
- package/scripts/post-install-claude-md.js +78 -0
- package/scripts/postinstall.js +79 -0
- package/scripts/pre-publish-validation.cjs +212 -0
- package/scripts/pre-publish-validation.js +429 -0
- package/scripts/redis-lua/cleanup-blocking-coordination.lua +198 -0
- package/scripts/release-announcement.js +425 -0
- package/scripts/release-notification.js +248 -0
- package/scripts/release-rollback.js +376 -0
- package/scripts/release-validation.js +460 -0
- package/scripts/rollback-sdk.sh +66 -0
- package/scripts/run-production-validation.ts +590 -0
- package/scripts/run-stability-validation.sh +687 -0
- package/scripts/security/README.md +339 -0
- package/scripts/security/deployment-validation.cjs +279 -0
- package/scripts/security/envelope-encryption-confidence-report.cjs +422 -0
- package/scripts/security/install-git-hooks.sh +132 -0
- package/scripts/security/install-git-secrets.sh +295 -0
- package/scripts/security/rotate-api-keys.js +469 -0
- package/scripts/security/ruv-swarm-safe.js +74 -0
- package/scripts/security/security-audit.cjs +538 -0
- package/scripts/security/setup-redis-auth.sh +397 -0
- package/scripts/security/validate-envelope-encryption.cjs +340 -0
- package/scripts/security-scan.js +492 -0
- package/scripts/src/web/frontend/.claude-flow/metrics/agent-metrics.json +1 -0
- package/scripts/src/web/frontend/.claude-flow/metrics/performance.json +9 -0
- package/scripts/src/web/frontend/.claude-flow/metrics/task-metrics.json +10 -0
- package/scripts/switch-api.sh +158 -0
- package/scripts/sync-agents.js +290 -0
- package/scripts/test/50-agent-test.js +625 -0
- package/scripts/test/NEW_STABILITY_TEST_GUIDE.md +407 -0
- package/scripts/test/README.md +236 -0
- package/scripts/test/STABILITY_TEST_EXAMPLE.md +347 -0
- package/scripts/test/STABILITY_TEST_README.md +480 -0
- package/scripts/test/agent-worker.js +309 -0
- package/scripts/test/ai-coordination-test.js +650 -0
- package/scripts/test/ai-mesh-coordination-test.js +416 -0
- package/scripts/test/check-links.ts +274 -0
- package/scripts/test/check-performance-regression.ts +168 -0
- package/scripts/test/cli-agent-coordination-test.js +313 -0
- package/scripts/test/coordinator-multilingual-test.js +396 -0
- package/scripts/test/coordinator-transparency-demo.js +585 -0
- package/scripts/test/coverage-report.ts +692 -0
- package/scripts/test/generate-swarm-tests.js +633 -0
- package/scripts/test/integration-test-validation.cjs +253 -0
- package/scripts/test/load-test-swarm.js +576 -0
- package/scripts/test/mesh-coordination-zero-overlap-test.js +740 -0
- package/scripts/test/multilingual-hello-world-test.js +390 -0
- package/scripts/test/quick-multilingual-demo.js +464 -0
- package/scripts/test/real-agent-test.js +312 -0
- package/scripts/test/run-phase3-compliance-tests.js +427 -0
- package/scripts/test/run-stability-test-examples.sh +292 -0
- package/scripts/test/stability-results/stability-metrics.jsonl +83 -0
- package/scripts/test/stability-results/stability-test-report.json +128 -0
- package/scripts/test/stability-results/stability-test.log +1827 -0
- package/scripts/test/stability-test-50-agents.js +734 -0
- package/scripts/test/test-batch-tasks.ts +29 -0
- package/scripts/test/test-byzantine-resolution.js +246 -0
- package/scripts/test/test-claude-spawn-options.sh +63 -0
- package/scripts/test/test-cli-wizard.js +331 -0
- package/scripts/test/test-comprehensive.js +401 -0
- package/scripts/test/test-coordination-features.ts +238 -0
- package/scripts/test/test-fallback-systems.js +276 -0
- package/scripts/test/test-init-command.ts +302 -0
- package/scripts/test/test-mcp.ts +251 -0
- package/scripts/test/test-runner.ts +568 -0
- package/scripts/test/test-swarm-integration.sh +92 -0
- package/scripts/test/test-swarm.ts +142 -0
- package/scripts/test/validation-summary.ts +408 -0
- package/scripts/test-cleanup-performance.sh +416 -0
- package/scripts/test-dashboard-auth.cjs +203 -0
- package/scripts/test-docker-deployment.sh +207 -0
- package/scripts/test-npm-package.cjs +167 -0
- package/scripts/test-provider-routing.cjs +226 -0
- package/scripts/test-routing-telemetry.cjs +147 -0
- package/scripts/test-runner.cjs +154 -0
- package/scripts/test-zai-10k.cjs +81 -0
- package/scripts/test-zai-api.cjs +191 -0
- package/scripts/test-zai-diagnostic.cjs +151 -0
- package/scripts/test-zai-final.cjs +128 -0
- package/scripts/test-zai-with-env.cjs +85 -0
- package/scripts/utils/README.md +261 -0
- package/scripts/utils/clean-build-artifacts.sh +94 -0
- package/scripts/utils/cleanup-root.sh +69 -0
- package/scripts/utils/fix-cliffy-imports.js +307 -0
- package/scripts/utils/fix-duplicate-imports.js +114 -0
- package/scripts/utils/fix-error-handling.cjs +70 -0
- package/scripts/utils/fix-import-paths.js +104 -0
- package/scripts/utils/fix-imports.js +116 -0
- package/scripts/utils/fix-shebang.js +78 -0
- package/scripts/utils/fix-test-modules.js +27 -0
- package/scripts/utils/fix-timezone-issue-246.js +200 -0
- package/scripts/utils/fix-ts-comprehensive.py +182 -0
- package/scripts/utils/fix-ts-targeted-batch.js +250 -0
- package/scripts/utils/remove-benchmark-conflicts.sh +140 -0
- package/scripts/utils/simple-test-fixer.js +190 -0
- package/scripts/utils/validate-metrics-structure.cjs +144 -0
- package/scripts/validate-agent-hooks.js +506 -0
- package/scripts/validate-changelog.js +241 -0
- package/scripts/validate-coordination-cli.js +69 -0
- package/scripts/validate-coordination-toggle-integration.cjs +501 -0
- package/scripts/validate-docker-infrastructure.sh +502 -0
- package/scripts/validate-entry-points.js +300 -0
- package/scripts/validate-stage3-performance.ts +377 -0
- package/scripts/validate-template-bundling.js +180 -0
- package/scripts/validation/README.md +33 -0
- package/scripts/validation/acl-security-validation.cjs +214 -0
- package/scripts/validation/acl-security-validation.js +402 -0
- package/scripts/validation/byzantine-verification.js +407 -0
- package/scripts/validation/final-phase-2-consensus.cjs +219 -0
- package/scripts/validation/final-security-validation.js +791 -0
- package/scripts/validation/final-wasm-validation.cjs +840 -0
- package/scripts/validation/integration-test-analysis.js +105 -0
- package/scripts/validation/phase-0-comprehensive-validation.js +474 -0
- package/scripts/validation/phase-0-consensus-report.js +139 -0
- package/scripts/validation/phase-0-final-report.js +112 -0
- package/scripts/validation/phase-0-redis-consensus-report.js +129 -0
- package/scripts/validation/phase-0-validation-improved.js +490 -0
- package/scripts/validation/phase-0-validation-test.js +65 -0
- package/scripts/validation/phase-1-consensus-report.cjs +342 -0
- package/scripts/validation/phase-1-consensus-validation.cjs +551 -0
- package/scripts/validation/phase-1-consensus-validation.js +551 -0
- package/scripts/validation/phase-2-consensus-report.cjs +186 -0
- package/scripts/validation/phase-2-validation.cjs +171 -0
- package/scripts/validation/phase-2-validation.js +171 -0
- package/scripts/validation/phase-4-consensus-report.js +181 -0
- package/scripts/validation/phase-4-final-validation.js +351 -0
- package/scripts/validation/phase-5-consensus-report.cjs +113 -0
- package/scripts/validation/phase-5-consensus-report.js +113 -0
- package/scripts/validation/security-analysis.js +49 -0
- package/scripts/validation/security-validation.js +492 -0
- package/scripts/validation/simple-security-validation.js +464 -0
- package/scripts/verify-installation.js +112 -0
- package/scripts/verify-mcp-server.js +86 -0
- package/scripts/verify-sdk-phase1.cjs +293 -0
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
#!/usr/bin/env -S deno run --allow-all
|
|
2
|
+
/**
|
|
3
|
+
* Advanced coverage analysis and reporting
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { parseArgs } from "https://deno.land/std@0.220.0/cli/parse_args.ts";
|
|
7
|
+
import { exists } from "https://deno.land/std@0.220.0/fs/exists.ts";
|
|
8
|
+
import { ensureDir } from "https://deno.land/std@0.220.0/fs/ensure_dir.ts";
|
|
9
|
+
import { walk } from "https://deno.land/std@0.220.0/fs/walk.ts";
|
|
10
|
+
|
|
11
|
+
interface CoverageData {
|
|
12
|
+
url: string;
|
|
13
|
+
ranges: Array<{
|
|
14
|
+
start: { line: number; col: number };
|
|
15
|
+
end: { line: number; col: number };
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface FileCoverage {
|
|
20
|
+
path: string;
|
|
21
|
+
totalLines: number;
|
|
22
|
+
coveredLines: number;
|
|
23
|
+
uncoveredLines: number[];
|
|
24
|
+
coverage: number;
|
|
25
|
+
functions: FunctionCoverage[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface FunctionCoverage {
|
|
29
|
+
name: string;
|
|
30
|
+
line: number;
|
|
31
|
+
covered: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface CoverageReport {
|
|
35
|
+
timestamp: string;
|
|
36
|
+
summary: {
|
|
37
|
+
totalFiles: number;
|
|
38
|
+
totalLines: number;
|
|
39
|
+
coveredLines: number;
|
|
40
|
+
coverage: number;
|
|
41
|
+
thresholds: {
|
|
42
|
+
statements: number;
|
|
43
|
+
branches: number;
|
|
44
|
+
functions: number;
|
|
45
|
+
lines: number;
|
|
46
|
+
};
|
|
47
|
+
passed: boolean;
|
|
48
|
+
};
|
|
49
|
+
files: FileCoverage[];
|
|
50
|
+
uncoveredFiles: string[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class CoverageAnalyzer {
|
|
54
|
+
private sourceDir: string;
|
|
55
|
+
private coverageDir: string;
|
|
56
|
+
private outputDir: string;
|
|
57
|
+
private thresholds: {
|
|
58
|
+
statements: number;
|
|
59
|
+
branches: number;
|
|
60
|
+
functions: number;
|
|
61
|
+
lines: number;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
constructor(options: {
|
|
65
|
+
sourceDir: string;
|
|
66
|
+
coverageDir: string;
|
|
67
|
+
outputDir: string;
|
|
68
|
+
thresholds: {
|
|
69
|
+
statements: number;
|
|
70
|
+
branches: number;
|
|
71
|
+
functions: number;
|
|
72
|
+
lines: number;
|
|
73
|
+
};
|
|
74
|
+
}) {
|
|
75
|
+
this.sourceDir = options.sourceDir;
|
|
76
|
+
this.coverageDir = options.coverageDir;
|
|
77
|
+
this.outputDir = options.outputDir;
|
|
78
|
+
this.thresholds = options.thresholds;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async generateReport(): Promise<CoverageReport> {
|
|
82
|
+
console.log("š Analyzing coverage data...");
|
|
83
|
+
|
|
84
|
+
await ensureDir(this.outputDir);
|
|
85
|
+
|
|
86
|
+
// Load coverage data
|
|
87
|
+
const coverageData = await this.loadCoverageData();
|
|
88
|
+
|
|
89
|
+
// Get all source files
|
|
90
|
+
const sourceFiles = await this.getSourceFiles();
|
|
91
|
+
|
|
92
|
+
// Analyze each file
|
|
93
|
+
const fileAnalysis = await this.analyzeFiles(sourceFiles, coverageData);
|
|
94
|
+
|
|
95
|
+
// Find uncovered files
|
|
96
|
+
const coveredFiles = new Set(coverageData.map(d => this.normalizePath(d.url)));
|
|
97
|
+
const uncoveredFiles = sourceFiles.filter(file => !coveredFiles.has(file));
|
|
98
|
+
|
|
99
|
+
// Calculate summary
|
|
100
|
+
const summary = this.calculateSummary(fileAnalysis, uncoveredFiles.length);
|
|
101
|
+
|
|
102
|
+
const report: CoverageReport = {
|
|
103
|
+
timestamp: new Date().toISOString(),
|
|
104
|
+
summary,
|
|
105
|
+
files: fileAnalysis,
|
|
106
|
+
uncoveredFiles,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Generate various report formats
|
|
110
|
+
await this.generateHTMLReport(report);
|
|
111
|
+
await this.generateJSONReport(report);
|
|
112
|
+
await this.generateTextReport(report);
|
|
113
|
+
await this.generateBadges(report);
|
|
114
|
+
|
|
115
|
+
return report;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private async loadCoverageData(): Promise<CoverageData[]> {
|
|
119
|
+
const coverageFiles: CoverageData[] = [];
|
|
120
|
+
|
|
121
|
+
if (!await exists(this.coverageDir)) {
|
|
122
|
+
throw new Error(`Coverage directory not found: ${this.coverageDir}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for await (const entry of walk(this.coverageDir, {
|
|
126
|
+
exts: [".json"],
|
|
127
|
+
includeDirs: false
|
|
128
|
+
})) {
|
|
129
|
+
const content = await Deno.readTextFile(entry.path);
|
|
130
|
+
const data = JSON.parse(content);
|
|
131
|
+
|
|
132
|
+
if (data.url && data.ranges) {
|
|
133
|
+
coverageFiles.push(data);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return coverageFiles;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private async getSourceFiles(): Promise<string[]> {
|
|
141
|
+
const files: string[] = [];
|
|
142
|
+
|
|
143
|
+
for await (const entry of walk(this.sourceDir, {
|
|
144
|
+
exts: [".ts"],
|
|
145
|
+
includeDirs: false,
|
|
146
|
+
skip: [/\.test\.ts$/, /test\.ts$/, /tests?\//]
|
|
147
|
+
})) {
|
|
148
|
+
// Normalize path
|
|
149
|
+
const relativePath = entry.path.replace(Deno.cwd() + "/", "");
|
|
150
|
+
files.push(relativePath);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return files;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private normalizePath(url: string): string {
|
|
157
|
+
// Convert file:// URLs to relative paths
|
|
158
|
+
if (url.startsWith("file://")) {
|
|
159
|
+
url = url.replace("file://", "");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Remove leading slash and make relative to cwd
|
|
163
|
+
const cwd = Deno.cwd();
|
|
164
|
+
if (url.startsWith(cwd)) {
|
|
165
|
+
url = url.replace(cwd + "/", "");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return url;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private async analyzeFiles(sourceFiles: string[], coverageData: CoverageData[]): Promise<FileCoverage[]> {
|
|
172
|
+
const analysis: FileCoverage[] = [];
|
|
173
|
+
|
|
174
|
+
for (const file of sourceFiles) {
|
|
175
|
+
const coverage = coverageData.find(d => this.normalizePath(d.url) === file);
|
|
176
|
+
const fileAnalysis = await this.analyzeFile(file, coverage);
|
|
177
|
+
analysis.push(fileAnalysis);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return analysis;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private async analyzeFile(filePath: string, coverage?: CoverageData): Promise<FileCoverage> {
|
|
184
|
+
const content = await Deno.readTextFile(filePath);
|
|
185
|
+
const lines = content.split('\n');
|
|
186
|
+
const totalLines = lines.filter(line => line.trim() && !line.trim().startsWith('//')).length;
|
|
187
|
+
|
|
188
|
+
if (!coverage) {
|
|
189
|
+
return {
|
|
190
|
+
path: filePath,
|
|
191
|
+
totalLines,
|
|
192
|
+
coveredLines: 0,
|
|
193
|
+
uncoveredLines: Array.from({ length: totalLines }, (_, i) => i + 1),
|
|
194
|
+
coverage: 0,
|
|
195
|
+
functions: this.extractFunctions(content, false),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Analyze covered lines
|
|
200
|
+
const coveredLines = new Set<number>();
|
|
201
|
+
|
|
202
|
+
for (const range of coverage.ranges) {
|
|
203
|
+
for (let line = range.start.line; line <= range.end.line; line++) {
|
|
204
|
+
coveredLines.add(line);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const uncoveredLines: number[] = [];
|
|
209
|
+
for (let i = 1; i <= lines.length; i++) {
|
|
210
|
+
const line = lines[i - 1].trim();
|
|
211
|
+
if (line && !line.startsWith('//') && !coveredLines.has(i)) {
|
|
212
|
+
uncoveredLines.push(i);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const coveragePercent = totalLines > 0 ? ((totalLines - uncoveredLines.length) / totalLines) * 100 : 100;
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
path: filePath,
|
|
220
|
+
totalLines,
|
|
221
|
+
coveredLines: totalLines - uncoveredLines.length,
|
|
222
|
+
uncoveredLines,
|
|
223
|
+
coverage: coveragePercent,
|
|
224
|
+
functions: this.extractFunctions(content, true, coveredLines),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private extractFunctions(content: string, checkCoverage: boolean, coveredLines?: Set<number>): FunctionCoverage[] {
|
|
229
|
+
const functions: FunctionCoverage[] = [];
|
|
230
|
+
const lines = content.split('\n');
|
|
231
|
+
|
|
232
|
+
// Simple regex patterns for TypeScript functions
|
|
233
|
+
const patterns = [
|
|
234
|
+
/^\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/,
|
|
235
|
+
/^\s*(?:export\s+)?(?:const|let)\s+(\w+)\s*=\s*(?:async\s+)?\(/,
|
|
236
|
+
/^\s*(?:public|private|protected)?\s*(?:async\s+)?(\w+)\s*\(/,
|
|
237
|
+
/^\s*(\w+)\s*:\s*\([^)]*\)\s*=>/,
|
|
238
|
+
];
|
|
239
|
+
|
|
240
|
+
for (let i = 0; i < lines.length; i++) {
|
|
241
|
+
const line = lines[i];
|
|
242
|
+
|
|
243
|
+
for (const pattern of patterns) {
|
|
244
|
+
const match = line.match(pattern);
|
|
245
|
+
if (match) {
|
|
246
|
+
const functionName = match[1];
|
|
247
|
+
const lineNumber = i + 1;
|
|
248
|
+
const covered = checkCoverage ? (coveredLines?.has(lineNumber) ?? false) : false;
|
|
249
|
+
|
|
250
|
+
functions.push({
|
|
251
|
+
name: functionName,
|
|
252
|
+
line: lineNumber,
|
|
253
|
+
covered,
|
|
254
|
+
});
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return functions;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private calculateSummary(files: FileCoverage[], uncoveredFileCount: number): CoverageReport['summary'] {
|
|
264
|
+
const totalFiles = files.length + uncoveredFileCount;
|
|
265
|
+
const totalLines = files.reduce((sum, file) => sum + file.totalLines, 0);
|
|
266
|
+
const coveredLines = files.reduce((sum, file) => sum + file.coveredLines, 0);
|
|
267
|
+
const coverage = totalLines > 0 ? (coveredLines / totalLines) * 100 : 100;
|
|
268
|
+
|
|
269
|
+
const passed = coverage >= this.thresholds.lines;
|
|
270
|
+
|
|
271
|
+
return {
|
|
272
|
+
totalFiles,
|
|
273
|
+
totalLines,
|
|
274
|
+
coveredLines,
|
|
275
|
+
coverage,
|
|
276
|
+
thresholds: this.thresholds,
|
|
277
|
+
passed,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private async generateHTMLReport(report: CoverageReport): Promise<void> {
|
|
282
|
+
const fileRows = report.files
|
|
283
|
+
.sort((a, b) => a.coverage - b.coverage)
|
|
284
|
+
.map(file => {
|
|
285
|
+
const coverageClass = file.coverage >= 80 ? 'high' : file.coverage >= 60 ? 'medium' : 'low';
|
|
286
|
+
const coverageBar = `<div class="coverage-bar"><div class="coverage-fill ${coverageClass}" style="width: ${file.coverage}%"></div></div>`;
|
|
287
|
+
|
|
288
|
+
return `
|
|
289
|
+
<tr class="${coverageClass}">
|
|
290
|
+
<td><a href="#file-${file.path.replace(/[^a-zA-Z0-9]/g, '-')}">${file.path}</a></td>
|
|
291
|
+
<td>${file.coverage.toFixed(2)}%</td>
|
|
292
|
+
<td>${coverageBar}</td>
|
|
293
|
+
<td>${file.coveredLines}/${file.totalLines}</td>
|
|
294
|
+
<td>${file.uncoveredLines.length}</td>
|
|
295
|
+
<td>${file.functions.filter(f => f.covered).length}/${file.functions.length}</td>
|
|
296
|
+
</tr>`;
|
|
297
|
+
}).join('');
|
|
298
|
+
|
|
299
|
+
const uncoveredRows = report.uncoveredFiles.map(file => `
|
|
300
|
+
<tr class="uncovered">
|
|
301
|
+
<td>${file}</td>
|
|
302
|
+
<td>0%</td>
|
|
303
|
+
<td><div class="coverage-bar"><div class="coverage-fill low" style="width: 0%"></div></div></td>
|
|
304
|
+
<td>0/0</td>
|
|
305
|
+
<td>-</td>
|
|
306
|
+
<td>0/0</td>
|
|
307
|
+
</tr>
|
|
308
|
+
`).join('');
|
|
309
|
+
|
|
310
|
+
const fileDetails = report.files.map(file => {
|
|
311
|
+
const uncoveredLinesStr = file.uncoveredLines.length > 0
|
|
312
|
+
? file.uncoveredLines.slice(0, 20).join(', ') + (file.uncoveredLines.length > 20 ? '...' : '')
|
|
313
|
+
: 'All lines covered';
|
|
314
|
+
|
|
315
|
+
const functionRows = file.functions.map(func => `
|
|
316
|
+
<tr class="${func.covered ? 'covered' : 'uncovered'}">
|
|
317
|
+
<td>${func.name}</td>
|
|
318
|
+
<td>${func.line}</td>
|
|
319
|
+
<td>${func.covered ? 'ā
' : 'ā'}</td>
|
|
320
|
+
</tr>
|
|
321
|
+
`).join('');
|
|
322
|
+
|
|
323
|
+
return `
|
|
324
|
+
<div class="file-detail" id="file-${file.path.replace(/[^a-zA-Z0-9]/g, '-')}">
|
|
325
|
+
<h3>š ${file.path}</h3>
|
|
326
|
+
<div class="file-summary">
|
|
327
|
+
<div class="metric">
|
|
328
|
+
<span class="label">Coverage:</span>
|
|
329
|
+
<span class="value ${file.coverage >= 80 ? 'high' : file.coverage >= 60 ? 'medium' : 'low'}">${file.coverage.toFixed(2)}%</span>
|
|
330
|
+
</div>
|
|
331
|
+
<div class="metric">
|
|
332
|
+
<span class="label">Lines:</span>
|
|
333
|
+
<span class="value">${file.coveredLines}/${file.totalLines}</span>
|
|
334
|
+
</div>
|
|
335
|
+
<div class="metric">
|
|
336
|
+
<span class="label">Functions:</span>
|
|
337
|
+
<span class="value">${file.functions.filter(f => f.covered).length}/${file.functions.length}</span>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
|
|
341
|
+
${file.uncoveredLines.length > 0 ? `
|
|
342
|
+
<div class="uncovered-lines">
|
|
343
|
+
<h4>Uncovered Lines:</h4>
|
|
344
|
+
<p>${uncoveredLinesStr}</p>
|
|
345
|
+
</div>
|
|
346
|
+
` : ''}
|
|
347
|
+
|
|
348
|
+
${file.functions.length > 0 ? `
|
|
349
|
+
<div class="functions">
|
|
350
|
+
<h4>Functions:</h4>
|
|
351
|
+
<table>
|
|
352
|
+
<thead>
|
|
353
|
+
<tr>
|
|
354
|
+
<th>Function</th>
|
|
355
|
+
<th>Line</th>
|
|
356
|
+
<th>Covered</th>
|
|
357
|
+
</tr>
|
|
358
|
+
</thead>
|
|
359
|
+
<tbody>
|
|
360
|
+
${functionRows}
|
|
361
|
+
</tbody>
|
|
362
|
+
</table>
|
|
363
|
+
</div>
|
|
364
|
+
` : ''}
|
|
365
|
+
</div>`;
|
|
366
|
+
}).join('');
|
|
367
|
+
|
|
368
|
+
const html = `<!DOCTYPE html>
|
|
369
|
+
<html>
|
|
370
|
+
<head>
|
|
371
|
+
<title>Claude-Flow Coverage Report</title>
|
|
372
|
+
<style>
|
|
373
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 20px; background: #f8f9fa; }
|
|
374
|
+
.header { background: white; padding: 30px; border-radius: 8px; margin-bottom: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
|
375
|
+
.header h1 { margin: 0; color: #2c3e50; }
|
|
376
|
+
.header .timestamp { color: #7f8c8d; margin-top: 5px; }
|
|
377
|
+
|
|
378
|
+
.summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; }
|
|
379
|
+
.summary-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); text-align: center; }
|
|
380
|
+
.summary-card h3 { margin: 0 0 10px 0; color: #2c3e50; font-size: 14px; text-transform: uppercase; }
|
|
381
|
+
.summary-card .value { font-size: 32px; font-weight: bold; margin: 10px 0; }
|
|
382
|
+
.summary-card .value.high { color: #27ae60; }
|
|
383
|
+
.summary-card .value.medium { color: #f39c12; }
|
|
384
|
+
.summary-card .value.low { color: #e74c3c; }
|
|
385
|
+
.summary-card .threshold { font-size: 12px; color: #7f8c8d; }
|
|
386
|
+
|
|
387
|
+
.coverage-status { padding: 15px; border-radius: 8px; margin-bottom: 30px; text-align: center; font-weight: bold; }
|
|
388
|
+
.coverage-status.passed { background: #d4edda; color: #155724; }
|
|
389
|
+
.coverage-status.failed { background: #f8d7da; color: #721c24; }
|
|
390
|
+
|
|
391
|
+
.files-table { background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.1); margin-bottom: 30px; }
|
|
392
|
+
.files-table h2 { margin: 0; padding: 20px; background: #2c3e50; color: white; }
|
|
393
|
+
table { width: 100%; border-collapse: collapse; }
|
|
394
|
+
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ecf0f1; }
|
|
395
|
+
th { background: #f8f9fa; font-weight: 600; }
|
|
396
|
+
|
|
397
|
+
.coverage-bar { width: 100px; height: 20px; background: #ecf0f1; border-radius: 10px; overflow: hidden; }
|
|
398
|
+
.coverage-fill { height: 100%; transition: width 0.3s ease; }
|
|
399
|
+
.coverage-fill.high { background: linear-gradient(90deg, #27ae60, #2ecc71); }
|
|
400
|
+
.coverage-fill.medium { background: linear-gradient(90deg, #f39c12, #e67e22); }
|
|
401
|
+
.coverage-fill.low { background: linear-gradient(90deg, #e74c3c, #c0392b); }
|
|
402
|
+
|
|
403
|
+
.high { background-color: rgba(39, 174, 96, 0.1); }
|
|
404
|
+
.medium { background-color: rgba(243, 156, 18, 0.1); }
|
|
405
|
+
.low { background-color: rgba(231, 76, 60, 0.1); }
|
|
406
|
+
.uncovered { background-color: rgba(231, 76, 60, 0.2); }
|
|
407
|
+
|
|
408
|
+
.file-detail { background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
|
|
409
|
+
.file-detail h3 { margin: 0 0 15px 0; color: #2c3e50; }
|
|
410
|
+
.file-summary { display: flex; gap: 20px; margin-bottom: 20px; }
|
|
411
|
+
.metric { display: flex; flex-direction: column; }
|
|
412
|
+
.metric .label { font-size: 12px; color: #7f8c8d; text-transform: uppercase; }
|
|
413
|
+
.metric .value { font-size: 18px; font-weight: bold; margin-top: 5px; }
|
|
414
|
+
|
|
415
|
+
.uncovered-lines { margin: 15px 0; }
|
|
416
|
+
.uncovered-lines h4 { margin: 0 0 10px 0; color: #e74c3c; }
|
|
417
|
+
.functions { margin: 15px 0; }
|
|
418
|
+
.functions h4 { margin: 0 0 10px 0; color: #2c3e50; }
|
|
419
|
+
.functions table { margin-top: 10px; }
|
|
420
|
+
.covered { background-color: rgba(39, 174, 96, 0.1); }
|
|
421
|
+
|
|
422
|
+
.footer { text-align: center; margin-top: 40px; color: #7f8c8d; }
|
|
423
|
+
</style>
|
|
424
|
+
</head>
|
|
425
|
+
<body>
|
|
426
|
+
<div class="header">
|
|
427
|
+
<h1>š Claude-Flow Coverage Report</h1>
|
|
428
|
+
<div class="timestamp">Generated: ${report.timestamp}</div>
|
|
429
|
+
</div>
|
|
430
|
+
|
|
431
|
+
<div class="coverage-status ${report.summary.passed ? 'passed' : 'failed'}">
|
|
432
|
+
${report.summary.passed ? 'ā
Coverage thresholds passed' : 'ā Coverage thresholds not met'}
|
|
433
|
+
</div>
|
|
434
|
+
|
|
435
|
+
<div class="summary">
|
|
436
|
+
<div class="summary-card">
|
|
437
|
+
<h3>Overall Coverage</h3>
|
|
438
|
+
<div class="value ${report.summary.coverage >= 80 ? 'high' : report.summary.coverage >= 60 ? 'medium' : 'low'}">${report.summary.coverage.toFixed(2)}%</div>
|
|
439
|
+
<div class="threshold">Threshold: ${this.thresholds.lines}%</div>
|
|
440
|
+
</div>
|
|
441
|
+
<div class="summary-card">
|
|
442
|
+
<h3>Total Files</h3>
|
|
443
|
+
<div class="value">${report.summary.totalFiles}</div>
|
|
444
|
+
</div>
|
|
445
|
+
<div class="summary-card">
|
|
446
|
+
<h3>Covered Lines</h3>
|
|
447
|
+
<div class="value">${report.summary.coveredLines}</div>
|
|
448
|
+
<div class="threshold">of ${report.summary.totalLines}</div>
|
|
449
|
+
</div>
|
|
450
|
+
<div class="summary-card">
|
|
451
|
+
<h3>Uncovered Files</h3>
|
|
452
|
+
<div class="value ${report.uncoveredFiles.length === 0 ? 'high' : 'low'}">${report.uncoveredFiles.length}</div>
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
|
|
456
|
+
<div class="files-table">
|
|
457
|
+
<h2>š File Coverage</h2>
|
|
458
|
+
<table>
|
|
459
|
+
<thead>
|
|
460
|
+
<tr>
|
|
461
|
+
<th>File</th>
|
|
462
|
+
<th>Coverage</th>
|
|
463
|
+
<th>Progress</th>
|
|
464
|
+
<th>Lines</th>
|
|
465
|
+
<th>Uncovered</th>
|
|
466
|
+
<th>Functions</th>
|
|
467
|
+
</tr>
|
|
468
|
+
</thead>
|
|
469
|
+
<tbody>
|
|
470
|
+
${fileRows}
|
|
471
|
+
${uncoveredRows}
|
|
472
|
+
</tbody>
|
|
473
|
+
</table>
|
|
474
|
+
</div>
|
|
475
|
+
|
|
476
|
+
<div class="file-details">
|
|
477
|
+
<h2>š File Details</h2>
|
|
478
|
+
${fileDetails}
|
|
479
|
+
</div>
|
|
480
|
+
|
|
481
|
+
<div class="footer">
|
|
482
|
+
<p>Claude-Flow Coverage Report - Advanced AI Agent Orchestration System</p>
|
|
483
|
+
</div>
|
|
484
|
+
</body>
|
|
485
|
+
</html>`;
|
|
486
|
+
|
|
487
|
+
await Deno.writeTextFile(`${this.outputDir}/coverage-detailed.html`, html);
|
|
488
|
+
console.log(" ā
Detailed HTML coverage report generated");
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
private async generateJSONReport(report: CoverageReport): Promise<void> {
|
|
492
|
+
await Deno.writeTextFile(
|
|
493
|
+
`${this.outputDir}/coverage-report.json`,
|
|
494
|
+
JSON.stringify(report, null, 2)
|
|
495
|
+
);
|
|
496
|
+
console.log(" ā
JSON coverage report generated");
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
private async generateTextReport(report: CoverageReport): Promise<void> {
|
|
500
|
+
const lines: string[] = [];
|
|
501
|
+
|
|
502
|
+
lines.push("š CLAUDE-FLOW COVERAGE REPORT");
|
|
503
|
+
lines.push("=".repeat(50));
|
|
504
|
+
lines.push(`Generated: ${report.timestamp}`);
|
|
505
|
+
lines.push("");
|
|
506
|
+
|
|
507
|
+
lines.push("š SUMMARY");
|
|
508
|
+
lines.push("-".repeat(20));
|
|
509
|
+
lines.push(`Overall Coverage: ${report.summary.coverage.toFixed(2)}%`);
|
|
510
|
+
lines.push(`Total Files: ${report.summary.totalFiles}`);
|
|
511
|
+
lines.push(`Covered Lines: ${report.summary.coveredLines}/${report.summary.totalLines}`);
|
|
512
|
+
lines.push(`Uncovered Files: ${report.uncoveredFiles.length}`);
|
|
513
|
+
lines.push("");
|
|
514
|
+
|
|
515
|
+
lines.push("šÆ THRESHOLDS");
|
|
516
|
+
lines.push("-".repeat(20));
|
|
517
|
+
lines.push(`Lines: ${report.summary.coverage.toFixed(2)}% (threshold: ${report.summary.thresholds.lines}%)`);
|
|
518
|
+
lines.push(`Status: ${report.summary.passed ? 'ā
PASSED' : 'ā FAILED'}`);
|
|
519
|
+
lines.push("");
|
|
520
|
+
|
|
521
|
+
if (report.files.length > 0) {
|
|
522
|
+
lines.push("š FILES BY COVERAGE");
|
|
523
|
+
lines.push("-".repeat(20));
|
|
524
|
+
|
|
525
|
+
const sortedFiles = [...report.files].sort((a, b) => a.coverage - b.coverage);
|
|
526
|
+
|
|
527
|
+
for (const file of sortedFiles) {
|
|
528
|
+
const status = file.coverage >= 80 ? 'ā
' : file.coverage >= 60 ? 'ā ļø' : 'ā';
|
|
529
|
+
lines.push(`${status} ${file.path}: ${file.coverage.toFixed(2)}% (${file.coveredLines}/${file.totalLines} lines)`);
|
|
530
|
+
|
|
531
|
+
if (file.uncoveredLines.length > 0 && file.uncoveredLines.length <= 10) {
|
|
532
|
+
lines.push(` Uncovered lines: ${file.uncoveredLines.join(', ')}`);
|
|
533
|
+
} else if (file.uncoveredLines.length > 10) {
|
|
534
|
+
lines.push(` Uncovered lines: ${file.uncoveredLines.slice(0, 10).join(', ')}... (+${file.uncoveredLines.length - 10} more)`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
lines.push("");
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (report.uncoveredFiles.length > 0) {
|
|
541
|
+
lines.push("š« UNCOVERED FILES");
|
|
542
|
+
lines.push("-".repeat(20));
|
|
543
|
+
for (const file of report.uncoveredFiles) {
|
|
544
|
+
lines.push(`ā ${file}`);
|
|
545
|
+
}
|
|
546
|
+
lines.push("");
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
lines.push("š” RECOMMENDATIONS");
|
|
550
|
+
lines.push("-".repeat(20));
|
|
551
|
+
|
|
552
|
+
const lowCoverageFiles = report.files.filter(f => f.coverage < 60);
|
|
553
|
+
if (lowCoverageFiles.length > 0) {
|
|
554
|
+
lines.push("⢠Focus on improving coverage for these files:");
|
|
555
|
+
for (const file of lowCoverageFiles.slice(0, 5)) {
|
|
556
|
+
lines.push(` - ${file.path} (${file.coverage.toFixed(2)}%)`);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
if (report.uncoveredFiles.length > 0) {
|
|
561
|
+
lines.push("⢠Add tests for uncovered files:");
|
|
562
|
+
for (const file of report.uncoveredFiles.slice(0, 5)) {
|
|
563
|
+
lines.push(` - ${file}`);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (report.summary.coverage >= 90) {
|
|
568
|
+
lines.push("⢠Excellent coverage! Consider adding edge case tests.");
|
|
569
|
+
} else if (report.summary.coverage >= 80) {
|
|
570
|
+
lines.push("⢠Good coverage! Focus on critical paths and error handling.");
|
|
571
|
+
} else {
|
|
572
|
+
lines.push("⢠Coverage needs improvement. Add tests for core functionality first.");
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
await Deno.writeTextFile(`${this.outputDir}/coverage-report.txt`, lines.join('\n'));
|
|
576
|
+
console.log(" ā
Text coverage report generated");
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
private async generateBadges(report: CoverageReport): Promise<void> {
|
|
580
|
+
const coverage = report.summary.coverage;
|
|
581
|
+
const color = coverage >= 90 ? 'brightgreen' :
|
|
582
|
+
coverage >= 80 ? 'green' :
|
|
583
|
+
coverage >= 70 ? 'yellow' :
|
|
584
|
+
coverage >= 60 ? 'orange' : 'red';
|
|
585
|
+
|
|
586
|
+
const badgeUrl = `https://img.shields.io/badge/coverage-${coverage.toFixed(1)}%25-${color}`;
|
|
587
|
+
|
|
588
|
+
const badgeMarkdown = ``;
|
|
589
|
+
const badgeHTML = `<img src="${badgeUrl}" alt="Coverage ${coverage.toFixed(1)}%">`;
|
|
590
|
+
|
|
591
|
+
const badges = {
|
|
592
|
+
url: badgeUrl,
|
|
593
|
+
markdown: badgeMarkdown,
|
|
594
|
+
html: badgeHTML,
|
|
595
|
+
coverage: coverage.toFixed(1),
|
|
596
|
+
color,
|
|
597
|
+
status: report.summary.passed ? 'passed' : 'failed',
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
await Deno.writeTextFile(
|
|
601
|
+
`${this.outputDir}/coverage-badges.json`,
|
|
602
|
+
JSON.stringify(badges, null, 2)
|
|
603
|
+
);
|
|
604
|
+
|
|
605
|
+
console.log(" ā
Coverage badges generated");
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
async function main(): Promise<void> {
|
|
610
|
+
const args = parseArgs(Deno.args, {
|
|
611
|
+
string: ["source-dir", "coverage-dir", "output-dir"],
|
|
612
|
+
boolean: ["help"],
|
|
613
|
+
default: {
|
|
614
|
+
"source-dir": "./src",
|
|
615
|
+
"coverage-dir": "./tests/results/coverage",
|
|
616
|
+
"output-dir": "./tests/results",
|
|
617
|
+
},
|
|
618
|
+
alias: {
|
|
619
|
+
h: "help",
|
|
620
|
+
s: "source-dir",
|
|
621
|
+
c: "coverage-dir",
|
|
622
|
+
o: "output-dir",
|
|
623
|
+
},
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
if (args.help) {
|
|
627
|
+
console.log(`
|
|
628
|
+
š Claude-Flow Coverage Analysis Tool
|
|
629
|
+
|
|
630
|
+
USAGE:
|
|
631
|
+
coverage-report.ts [OPTIONS]
|
|
632
|
+
|
|
633
|
+
OPTIONS:
|
|
634
|
+
--source-dir, -s Source code directory (default: ./src)
|
|
635
|
+
--coverage-dir, -c Coverage data directory (default: ./tests/results/coverage)
|
|
636
|
+
--output-dir, -o Output directory for reports (default: ./tests/results)
|
|
637
|
+
--help, -h Show this help
|
|
638
|
+
|
|
639
|
+
EXAMPLES:
|
|
640
|
+
# Generate coverage report with defaults
|
|
641
|
+
./scripts/coverage-report.ts
|
|
642
|
+
|
|
643
|
+
# Custom directories
|
|
644
|
+
./scripts/coverage-report.ts --source-dir ./lib --coverage-dir ./coverage --output-dir ./reports
|
|
645
|
+
`);
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
const thresholds = {
|
|
650
|
+
statements: 80,
|
|
651
|
+
branches: 75,
|
|
652
|
+
functions: 80,
|
|
653
|
+
lines: 80,
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
const analyzer = new CoverageAnalyzer({
|
|
657
|
+
sourceDir: args["source-dir"],
|
|
658
|
+
coverageDir: args["coverage-dir"],
|
|
659
|
+
outputDir: args["output-dir"],
|
|
660
|
+
thresholds,
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
try {
|
|
664
|
+
const report = await analyzer.generateReport();
|
|
665
|
+
|
|
666
|
+
console.log("\nš COVERAGE SUMMARY");
|
|
667
|
+
console.log("=".repeat(40));
|
|
668
|
+
console.log(`Overall Coverage: ${report.summary.coverage.toFixed(2)}%`);
|
|
669
|
+
console.log(`Total Files: ${report.summary.totalFiles}`);
|
|
670
|
+
console.log(`Covered Lines: ${report.summary.coveredLines}/${report.summary.totalLines}`);
|
|
671
|
+
console.log(`Uncovered Files: ${report.uncoveredFiles.length}`);
|
|
672
|
+
|
|
673
|
+
const status = report.summary.passed ? "ā
PASSED" : "ā FAILED";
|
|
674
|
+
console.log(`Status: ${status}`);
|
|
675
|
+
|
|
676
|
+
console.log(`\nš Reports generated in: ${args["output-dir"]}`);
|
|
677
|
+
console.log(` - Detailed HTML: coverage-detailed.html`);
|
|
678
|
+
console.log(` - JSON Data: coverage-report.json`);
|
|
679
|
+
console.log(` - Text Summary: coverage-report.txt`);
|
|
680
|
+
console.log(` - Badges: coverage-badges.json`);
|
|
681
|
+
|
|
682
|
+
Deno.exit(report.summary.passed ? 0 : 1);
|
|
683
|
+
|
|
684
|
+
} catch (error) {
|
|
685
|
+
console.error("ā Coverage analysis failed:", error.message);
|
|
686
|
+
Deno.exit(1);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (import.meta.main) {
|
|
691
|
+
main();
|
|
692
|
+
}
|