vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850
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 +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- package/src/validation/metrics-calculator.js +27 -551
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Helper Functions
|
|
3
|
+
* Shared utility functions for metrics calculations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class MetricsHelpers {
|
|
7
|
+
/**
|
|
8
|
+
* Calculate median value from array
|
|
9
|
+
*/
|
|
10
|
+
calculateMedian(values) {
|
|
11
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
12
|
+
const mid = Math.floor(sorted.length / 2);
|
|
13
|
+
return sorted.length % 2 === 0 ?
|
|
14
|
+
(sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Calculate size distribution
|
|
19
|
+
*/
|
|
20
|
+
calculateSizeDistribution(fileSummaries) {
|
|
21
|
+
const sizes = fileSummaries.map(f => f.lineCount);
|
|
22
|
+
const max = Math.max(...sizes);
|
|
23
|
+
const min = Math.min(...sizes);
|
|
24
|
+
const ranges = 10;
|
|
25
|
+
const rangeSize = Math.ceil((max - min) / ranges);
|
|
26
|
+
|
|
27
|
+
const distribution = [];
|
|
28
|
+
for (let i = 0; i < ranges; i++) {
|
|
29
|
+
const lower = min + (i * rangeSize);
|
|
30
|
+
const upper = lower + rangeSize;
|
|
31
|
+
const count = sizes.filter(s => s >= lower && s < upper).length;
|
|
32
|
+
|
|
33
|
+
distribution.push({
|
|
34
|
+
range: `${lower}-${upper}`,
|
|
35
|
+
count,
|
|
36
|
+
percentage: (count / fileSummaries.length * 100).toFixed(1)
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return distribution;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Calculate overall score from metrics
|
|
45
|
+
*/
|
|
46
|
+
calculateOverallScore(metrics) {
|
|
47
|
+
const weights = {
|
|
48
|
+
compliance: 0.3,
|
|
49
|
+
size: 0.25,
|
|
50
|
+
severity: 0.2,
|
|
51
|
+
quality: 0.15,
|
|
52
|
+
category: 0.1
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const scores = {
|
|
56
|
+
compliance: metrics.overview.complianceRate,
|
|
57
|
+
size: Math.max(0, 100 - metrics.sizeMetrics.sizeRiskScore * 10),
|
|
58
|
+
severity: Math.max(0, 100 - metrics.severityMetrics.severityRiskScore),
|
|
59
|
+
quality: metrics.qualityMetrics.codeQualityScore,
|
|
60
|
+
category: 100 - (metrics.categoryMetrics.mostProblematicCategory?.issueCount || 0) * 5
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
let overallScore = 0;
|
|
64
|
+
for (const [metric, weight] of Object.entries(weights)) {
|
|
65
|
+
overallScore += scores[metric] * weight;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return Math.max(0, Math.min(100, overallScore));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Assess risk level from metrics
|
|
73
|
+
*/
|
|
74
|
+
assessRiskLevel(overallScore) {
|
|
75
|
+
if (overallScore >= 90) return 'low';
|
|
76
|
+
if (overallScore >= 70) return 'medium';
|
|
77
|
+
if (overallScore >= 50) return 'high';
|
|
78
|
+
return 'critical';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Assign health grade from metrics
|
|
83
|
+
*/
|
|
84
|
+
assignHealthGrade(overallScore) {
|
|
85
|
+
if (overallScore >= 95) return 'A+';
|
|
86
|
+
if (overallScore >= 90) return 'A';
|
|
87
|
+
if (overallScore >= 85) return 'B+';
|
|
88
|
+
if (overallScore >= 80) return 'B';
|
|
89
|
+
if (overallScore >= 75) return 'C+';
|
|
90
|
+
if (overallScore >= 70) return 'C';
|
|
91
|
+
if (overallScore >= 60) return 'D';
|
|
92
|
+
return 'F';
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Extract key insights from metrics
|
|
97
|
+
*/
|
|
98
|
+
extractKeyInsights(metrics) {
|
|
99
|
+
const insights = [];
|
|
100
|
+
|
|
101
|
+
if (metrics.overview.complianceRate < 80) {
|
|
102
|
+
insights.push('Compliance rate below target - requires immediate attention');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (metrics.sizeMetrics.criticalSizeFiles > 0) {
|
|
106
|
+
insights.push(`${metrics.sizeMetrics.criticalSizeFiles} files require immediate refactoring`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (metrics.severityMetrics.severities.critical.count > 0) {
|
|
110
|
+
insights.push('Critical violations detected - address immediately');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const mostProblematic = metrics.categoryMetrics.mostProblematicCategory;
|
|
114
|
+
if (mostProblematic && mostProblematic.issueCount > 5) {
|
|
115
|
+
insights.push(`${mostProblematic.category} category has highest violation count`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return insights;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Identify priority actions from metrics
|
|
123
|
+
*/
|
|
124
|
+
identifyPriorityActions(metrics) {
|
|
125
|
+
const actions = [];
|
|
126
|
+
|
|
127
|
+
if (metrics.sizeMetrics.criticalSizeFiles > 0) {
|
|
128
|
+
actions.push({
|
|
129
|
+
action: 'Refactor critical files',
|
|
130
|
+
priority: 1,
|
|
131
|
+
description: 'Address files exceeding critical size threshold'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (metrics.severityMetrics.severities.critical.count > 0) {
|
|
136
|
+
actions.push({
|
|
137
|
+
action: 'Fix critical violations',
|
|
138
|
+
priority: 2,
|
|
139
|
+
description: 'Resolve all critical compliance issues'
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (metrics.overview.complianceRate < 80) {
|
|
144
|
+
actions.push({
|
|
145
|
+
action: 'Improve compliance rate',
|
|
146
|
+
priority: 3,
|
|
147
|
+
description: 'Focus on improving overall compliance to >90%'
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return actions;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
module.exports = new MetricsHelpers();
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overview Metrics Calculator
|
|
3
|
+
* Calculates overview and file-specific metrics
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { COMPLIANCE_STATUS } = require('../../models/compliance-report');
|
|
7
|
+
|
|
8
|
+
class OverviewCalculator {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Calculate overview metrics
|
|
15
|
+
*/
|
|
16
|
+
calculateOverviewMetrics(report) {
|
|
17
|
+
const totalFiles = report.summary.totalFiles;
|
|
18
|
+
const compliantFiles = report.summary.compliantFiles;
|
|
19
|
+
const totalIssues = report.summary.totalIssues;
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
totalFiles,
|
|
23
|
+
compliantFiles,
|
|
24
|
+
nonCompliantFiles: totalFiles - compliantFiles,
|
|
25
|
+
totalIssues,
|
|
26
|
+
overallComplianceScore: report.summary.overallComplianceScore,
|
|
27
|
+
complianceRate: totalFiles > 0 ? (compliantFiles / totalFiles * 100) : 100,
|
|
28
|
+
averageIssuesPerFile: totalFiles > 0 ? (totalIssues / totalFiles) : 0,
|
|
29
|
+
healthStatus: this.getHealthStatus(report.summary.overallComplianceScore)
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Calculate file-specific metrics
|
|
35
|
+
*/
|
|
36
|
+
calculateFileMetrics(report, helpers) {
|
|
37
|
+
const fileSummaries = report.fileSummaries;
|
|
38
|
+
|
|
39
|
+
// Sort files by various criteria
|
|
40
|
+
const filesBySize = [...fileSummaries].sort((a, b) => b.lineCount - a.lineCount);
|
|
41
|
+
const filesByCompliance = [...fileSummaries].sort((a, b) => a.complianceScore - b.complianceScore);
|
|
42
|
+
const filesByIssues = [...fileSummaries].sort((a, b) => b.totalIssues - a.totalIssues);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
largestFiles: filesBySize.slice(0, 10).map(f => ({
|
|
46
|
+
filePath: f.filePath,
|
|
47
|
+
lineCount: f.lineCount,
|
|
48
|
+
status: f.status,
|
|
49
|
+
complianceScore: f.complianceScore
|
|
50
|
+
})),
|
|
51
|
+
smallestFiles: filesBySize.slice(-10).reverse().map(f => ({
|
|
52
|
+
filePath: f.filePath,
|
|
53
|
+
lineCount: f.lineCount,
|
|
54
|
+
status: f.status,
|
|
55
|
+
complianceScore: f.complianceScore
|
|
56
|
+
})),
|
|
57
|
+
leastCompliantFiles: filesByCompliance.slice(0, 10).map(f => ({
|
|
58
|
+
filePath: f.filePath,
|
|
59
|
+
complianceScore: f.complianceScore,
|
|
60
|
+
status: f.status,
|
|
61
|
+
totalIssues: f.totalIssues
|
|
62
|
+
})),
|
|
63
|
+
mostProblematicFiles: filesByIssues.slice(0, 10).map(f => ({
|
|
64
|
+
filePath: f.filePath,
|
|
65
|
+
totalIssues: f.totalIssues,
|
|
66
|
+
status: f.status,
|
|
67
|
+
complianceScore: f.complianceScore
|
|
68
|
+
})),
|
|
69
|
+
averageFileSize: fileSummaries.length > 0 ?
|
|
70
|
+
fileSummaries.reduce((sum, f) => sum + f.lineCount, 0) / fileSummaries.length : 0,
|
|
71
|
+
medianFileSize: helpers.calculateMedian(fileSummaries.map(f => f.lineCount)),
|
|
72
|
+
fileSizeDistribution: helpers.calculateSizeDistribution(fileSummaries)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getHealthStatus(complianceScore) {
|
|
77
|
+
if (complianceScore >= 95) return 'excellent';
|
|
78
|
+
if (complianceScore >= 85) return 'good';
|
|
79
|
+
if (complianceScore >= 70) return 'fair';
|
|
80
|
+
if (complianceScore >= 50) return 'poor';
|
|
81
|
+
return 'critical';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = OverviewCalculator;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overview Metrics Calculator
|
|
3
|
+
*
|
|
4
|
+
* Calculates high-level overview metrics for compliance reports.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Calculate overview metrics
|
|
9
|
+
*/
|
|
10
|
+
function calculateOverviewMetrics(report, options = {}) {
|
|
11
|
+
const totalFiles = report.summary.totalFiles;
|
|
12
|
+
const compliantFiles = report.summary.compliantFiles;
|
|
13
|
+
const totalIssues = report.summary.totalIssues;
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
totalFiles,
|
|
17
|
+
compliantFiles,
|
|
18
|
+
nonCompliantFiles: totalFiles - compliantFiles,
|
|
19
|
+
totalIssues,
|
|
20
|
+
overallComplianceScore: report.summary.overallComplianceScore,
|
|
21
|
+
complianceRate: totalFiles > 0 ? (compliantFiles / totalFiles * 100) : 100,
|
|
22
|
+
averageIssuesPerFile: totalFiles > 0 ? (totalIssues / totalFiles) : 0,
|
|
23
|
+
healthStatus: getHealthStatus(report.summary.overallComplianceScore)
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get health status based on compliance score
|
|
29
|
+
*/
|
|
30
|
+
function getHealthStatus(complianceScore) {
|
|
31
|
+
if (complianceScore >= 95) return 'excellent';
|
|
32
|
+
if (complianceScore >= 85) return 'good';
|
|
33
|
+
if (complianceScore >= 70) return 'fair';
|
|
34
|
+
if (complianceScore >= 50) return 'poor';
|
|
35
|
+
return 'critical';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
calculateOverviewMetrics,
|
|
40
|
+
getHealthStatus
|
|
41
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quality Metrics Calculator
|
|
3
|
+
* Calculates quality, maintainability, and technical debt metrics
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { COMPLIANCE_STATUS, COMPLIANCE_CATEGORIES } = require('../../models/compliance-report');
|
|
7
|
+
|
|
8
|
+
class QualityCalculator {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Calculate quality metrics
|
|
15
|
+
*/
|
|
16
|
+
calculateQualityMetrics(fileSummaries) {
|
|
17
|
+
return {
|
|
18
|
+
codeQualityScore: this.calculateCodeQualityScore(fileSummaries),
|
|
19
|
+
maintainabilityIndex: this.calculateMaintainabilityIndex(fileSummaries),
|
|
20
|
+
technicalDebt: this.calculateTechnicalDebt(fileSummaries),
|
|
21
|
+
complexityMetrics: this.calculateComplexityMetrics(fileSummaries),
|
|
22
|
+
documentationCoverage: this.calculateDocumentationCoverage(fileSummaries)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Calculate performance metrics
|
|
28
|
+
*/
|
|
29
|
+
calculatePerformanceMetrics(fileSummaries) {
|
|
30
|
+
return {
|
|
31
|
+
averageAnalysisTime: 0,
|
|
32
|
+
totalAnalysisTime: 0,
|
|
33
|
+
filesPerSecond: 0,
|
|
34
|
+
memoryUsage: {
|
|
35
|
+
estimated: this.estimateMemoryUsage(fileSummaries),
|
|
36
|
+
peak: 0
|
|
37
|
+
},
|
|
38
|
+
efficiency: {
|
|
39
|
+
issuesDetectedPerMinute: 0,
|
|
40
|
+
filesProcessedPerMinute: 0
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
calculateCodeQualityScore(fileSummaries) {
|
|
46
|
+
const totalFiles = fileSummaries.length;
|
|
47
|
+
const compliantFiles = fileSummaries.filter(f => f.status === COMPLIANCE_STATUS.COMPLIANT).length;
|
|
48
|
+
const totalIssues = fileSummaries.reduce((sum, f) => sum + f.totalIssues, 0);
|
|
49
|
+
|
|
50
|
+
// Base score from compliance
|
|
51
|
+
let score = (compliantFiles / totalFiles) * 100;
|
|
52
|
+
|
|
53
|
+
// Penalize for high issue density
|
|
54
|
+
const avgIssuesPerFile = totalIssues / totalFiles;
|
|
55
|
+
score -= Math.min(avgIssuesPerFile * 5, 30);
|
|
56
|
+
|
|
57
|
+
return Math.max(0, Math.min(100, score));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
calculateMaintainabilityIndex(fileSummaries) {
|
|
61
|
+
// Simplified maintainability index based on file sizes and issues
|
|
62
|
+
let totalIndex = 0;
|
|
63
|
+
|
|
64
|
+
for (const file of fileSummaries) {
|
|
65
|
+
let fileIndex = 100;
|
|
66
|
+
|
|
67
|
+
// Reduce based on file size
|
|
68
|
+
if (file.lineCount > 555) {
|
|
69
|
+
fileIndex -= ((file.lineCount - 555) / 555) * 30;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Reduce based on issues
|
|
73
|
+
fileIndex -= file.totalIssues * 2;
|
|
74
|
+
|
|
75
|
+
totalIndex += Math.max(0, fileIndex);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return fileSummaries.length > 0 ? totalIndex / fileSummaries.length : 100;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
calculateTechnicalDebt(fileSummaries) {
|
|
82
|
+
// Estimate technical debt in hours based on violations
|
|
83
|
+
let totalDebt = 0;
|
|
84
|
+
|
|
85
|
+
for (const file of fileSummaries) {
|
|
86
|
+
// Base debt per file
|
|
87
|
+
let fileDebt = 0;
|
|
88
|
+
|
|
89
|
+
// Size-related debt
|
|
90
|
+
if (file.lineCount > 555) {
|
|
91
|
+
fileDebt += (file.lineCount - 555) * 0.1; // 6 minutes per excess line
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Issue-related debt
|
|
95
|
+
fileDebt += file.criticalIssues * 4; // 4 hours per critical issue
|
|
96
|
+
fileDebt += file.violationIssues * 2; // 2 hours per violation
|
|
97
|
+
fileDebt += file.warningIssues * 0.5; // 30 minutes per warning
|
|
98
|
+
|
|
99
|
+
totalDebt += fileDebt;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
totalHours: totalDebt,
|
|
104
|
+
totalDays: totalDebt / 8,
|
|
105
|
+
estimatedCost: totalDebt * 100,
|
|
106
|
+
priorityFiles: fileSummaries
|
|
107
|
+
.filter(f => f.lineCount > 555 || f.totalIssues > 5)
|
|
108
|
+
.map(f => ({
|
|
109
|
+
filePath: f.filePath,
|
|
110
|
+
estimatedHours: (f.lineCount > 555 ? (f.lineCount - 555) * 0.1 : 0) +
|
|
111
|
+
(f.criticalIssues * 4) +
|
|
112
|
+
(f.violationIssues * 2) +
|
|
113
|
+
(f.warningIssues * 0.5)
|
|
114
|
+
}))
|
|
115
|
+
.sort((a, b) => b.estimatedHours - a.estimatedHours)
|
|
116
|
+
.slice(0, 10)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
calculateComplexityMetrics(fileSummaries) {
|
|
121
|
+
return {
|
|
122
|
+
averageComplexity: fileSummaries.length > 0 ?
|
|
123
|
+
fileSummaries.reduce((sum, f) => sum + (f.lineCount / 100), 0) / fileSummaries.length : 0,
|
|
124
|
+
highComplexityFiles: fileSummaries.filter(f => f.lineCount > 500).length,
|
|
125
|
+
complexityDistribution: this.calculateComplexityDistribution(fileSummaries)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
calculateComplexityDistribution(fileSummaries) {
|
|
130
|
+
const complexity = fileSummaries.map(f => f.lineCount / 100);
|
|
131
|
+
const distribution = {
|
|
132
|
+
low: complexity.filter(c => c < 2).length,
|
|
133
|
+
medium: complexity.filter(c => c >= 2 && c < 5).length,
|
|
134
|
+
high: complexity.filter(c => c >= 5 && c < 10).length,
|
|
135
|
+
veryHigh: complexity.filter(c => c >= 10).length
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return distribution;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
calculateDocumentationCoverage(fileSummaries) {
|
|
142
|
+
const totalFiles = fileSummaries.length;
|
|
143
|
+
const documentedFiles = fileSummaries.filter(f =>
|
|
144
|
+
f.issues.some(issue => issue.category === COMPLIANCE_CATEGORIES.DOCUMENTATION)
|
|
145
|
+
).length;
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
coveragePercentage: totalFiles > 0 ? (documentedFiles / totalFiles * 100) : 100,
|
|
149
|
+
documentedFiles,
|
|
150
|
+
undocumentedFiles: totalFiles - documentedFiles
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
estimateMemoryUsage(fileSummaries) {
|
|
155
|
+
// Rough estimation based on file sizes and issue counts
|
|
156
|
+
const baseMemory = 50 * 1024 * 1024; // 50MB base
|
|
157
|
+
const perFileMemory = 1024; // 1KB per file
|
|
158
|
+
const perIssueMemory = 512; // 512 bytes per issue
|
|
159
|
+
|
|
160
|
+
const totalIssues = fileSummaries.reduce((sum, f) => sum + f.totalIssues, 0);
|
|
161
|
+
|
|
162
|
+
return baseMemory + (fileSummaries.length * perFileMemory) + (totalIssues * perIssueMemory);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
module.exports = QualityCalculator;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size Metrics Calculator
|
|
3
|
+
* Calculates size-specific metrics and risk scores
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class SizeCalculator {
|
|
7
|
+
constructor(options = {}) {
|
|
8
|
+
this.options = {
|
|
9
|
+
maxFileSize: options.maxFileSize || 555,
|
|
10
|
+
warningThreshold: options.warningThreshold || 500,
|
|
11
|
+
criticalThreshold: options.criticalThreshold || 800,
|
|
12
|
+
...options
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Calculate size-specific metrics
|
|
18
|
+
*/
|
|
19
|
+
calculateSizeMetrics(report) {
|
|
20
|
+
const fileSummaries = report.fileSummaries;
|
|
21
|
+
const maxLimit = this.options.maxFileSize;
|
|
22
|
+
const warningThreshold = this.options.warningThreshold;
|
|
23
|
+
const criticalThreshold = this.options.criticalThreshold;
|
|
24
|
+
|
|
25
|
+
const sizeCategories = {
|
|
26
|
+
small: fileSummaries.filter(f => f.lineCount <= warningThreshold * 0.5).length,
|
|
27
|
+
medium: fileSummaries.filter(f => f.lineCount > warningThreshold * 0.5 && f.lineCount <= warningThreshold).length,
|
|
28
|
+
large: fileSummaries.filter(f => f.lineCount > warningThreshold && f.lineCount <= maxLimit).length,
|
|
29
|
+
oversized: fileSummaries.filter(f => f.lineCount > maxLimit && f.lineCount <= criticalThreshold).length,
|
|
30
|
+
critical: fileSummaries.filter(f => f.lineCount > criticalThreshold).length
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const totalLines = fileSummaries.reduce((sum, f) => sum + f.lineCount, 0);
|
|
34
|
+
const excessLines = fileSummaries
|
|
35
|
+
.filter(f => f.lineCount > maxLimit)
|
|
36
|
+
.reduce((sum, f) => sum + (f.lineCount - maxLimit), 0);
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
sizeCategories,
|
|
40
|
+
totalLines,
|
|
41
|
+
excessLines,
|
|
42
|
+
averageExcessPerOversizedFile: sizeCategories.oversized > 0 ?
|
|
43
|
+
excessLines / (sizeCategories.oversized + sizeCategories.critical) : 0,
|
|
44
|
+
sizeComplianceRate: ((sizeCategories.small + sizeCategories.medium + sizeCategories.large) / fileSummaries.length * 100),
|
|
45
|
+
criticalSizeFiles: sizeCategories.critical,
|
|
46
|
+
oversizedFiles: sizeCategories.oversized,
|
|
47
|
+
sizeRiskScore: this.calculateSizeRiskScore(sizeCategories, fileSummaries.length)
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
calculateSizeRiskScore(sizeCategories, totalFiles) {
|
|
52
|
+
const weights = {
|
|
53
|
+
small: 0,
|
|
54
|
+
medium: 0,
|
|
55
|
+
large: 1,
|
|
56
|
+
oversized: 5,
|
|
57
|
+
critical: 10
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
let riskScore = 0;
|
|
61
|
+
for (const [category, count] of Object.entries(sizeCategories)) {
|
|
62
|
+
riskScore += weights[category] * count;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return totalFiles > 0 ? (riskScore / totalFiles) : 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
module.exports = SizeCalculator;
|