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,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance Report - Comparison Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Analyzes and compares compliance reports over time.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate comparison report between two compliance reports
|
|
9
|
+
* @param {Object} oldReport - Previous compliance report
|
|
10
|
+
* @param {Object} newReport - Current compliance report
|
|
11
|
+
* @param {Object} options - Comparison options
|
|
12
|
+
* @returns {Object} - Comparison result
|
|
13
|
+
*/
|
|
14
|
+
function generateComparisonReport(oldReport, newReport, options = {}) {
|
|
15
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
16
|
+
const filePath = options.outputDir ?
|
|
17
|
+
`${options.outputDir}/comparison-report-${timestamp}.json` :
|
|
18
|
+
`comparison-report-${timestamp}.json`;
|
|
19
|
+
|
|
20
|
+
const comparison = {
|
|
21
|
+
metadata: {
|
|
22
|
+
generatedAt: new Date().toISOString(),
|
|
23
|
+
oldReportDate: oldReport.generatedAt,
|
|
24
|
+
newReportDate: newReport.generatedAt,
|
|
25
|
+
comparisonPeriod: calculatePeriod(oldReport.generatedAt, newReport.generatedAt)
|
|
26
|
+
},
|
|
27
|
+
summary: {
|
|
28
|
+
oldScore: oldReport.summary.overallComplianceScore,
|
|
29
|
+
newScore: newReport.summary.overallComplianceScore,
|
|
30
|
+
scoreChange: newReport.summary.overallComplianceScore - oldReport.summary.overallComplianceScore,
|
|
31
|
+
oldIssues: oldReport.summary.totalIssues,
|
|
32
|
+
newIssues: newReport.summary.totalIssues,
|
|
33
|
+
issuesChange: newReport.summary.totalIssues - oldReport.summary.totalIssues,
|
|
34
|
+
oldFiles: oldReport.summary.totalFiles,
|
|
35
|
+
newFiles: newReport.summary.totalFiles,
|
|
36
|
+
filesChange: newReport.summary.totalFiles - oldReport.summary.totalFiles
|
|
37
|
+
},
|
|
38
|
+
trends: calculateTrends(oldReport, newReport),
|
|
39
|
+
recommendations: generateComparisonRecommendations(oldReport, newReport)
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// Write comparison to file
|
|
43
|
+
const fs = require('fs');
|
|
44
|
+
const path = require('path');
|
|
45
|
+
fs.writeFileSync(filePath, JSON.stringify(comparison, null, 2), 'utf8');
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
comparison,
|
|
49
|
+
filePath
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Calculate period between reports
|
|
55
|
+
* @param {string} oldDate - Old report date
|
|
56
|
+
* @param {string} newDate - New report date
|
|
57
|
+
* @returns {string} - Period description
|
|
58
|
+
*/
|
|
59
|
+
function calculatePeriod(oldDate, newDate) {
|
|
60
|
+
const old = new Date(oldDate);
|
|
61
|
+
const now = new Date(newDate);
|
|
62
|
+
const days = Math.floor((now - old) / (1000 * 60 * 60 * 24));
|
|
63
|
+
|
|
64
|
+
return `${days} days`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Calculate trends between reports
|
|
69
|
+
* @param {Object} oldReport - Previous compliance report
|
|
70
|
+
* @param {Object} newReport - Current compliance report
|
|
71
|
+
* @returns {Object} - Trend analysis
|
|
72
|
+
*/
|
|
73
|
+
function calculateTrends(oldReport, newReport) {
|
|
74
|
+
return {
|
|
75
|
+
complianceTrend: newReport.summary.overallComplianceScore > oldReport.summary.overallComplianceScore ? 'improving' : 'declining',
|
|
76
|
+
issueTrend: newReport.summary.totalIssues < oldReport.summary.totalIssues ? 'decreasing' : 'increasing',
|
|
77
|
+
fileTrend: newReport.summary.totalFiles > oldReport.summary.totalFiles ? 'growing' : 'stable',
|
|
78
|
+
severityTrend: calculateSeverityTrend(oldReport, newReport),
|
|
79
|
+
categoryTrend: calculateCategoryTrend(oldReport, newReport)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Calculate severity trend between reports
|
|
85
|
+
* @param {Object} oldReport - Previous compliance report
|
|
86
|
+
* @param {Object} newReport - Current compliance report
|
|
87
|
+
* @returns {Object} - Severity trend analysis
|
|
88
|
+
*/
|
|
89
|
+
function calculateSeverityTrend(oldReport, newReport) {
|
|
90
|
+
const oldSeverity = getSeverityDistribution(oldReport);
|
|
91
|
+
const newSeverity = getSeverityDistribution(newReport);
|
|
92
|
+
|
|
93
|
+
const trends = {};
|
|
94
|
+
|
|
95
|
+
Object.keys(oldSeverity).forEach(severity => {
|
|
96
|
+
const oldCount = oldSeverity[severity] || 0;
|
|
97
|
+
const newCount = newSeverity[severity] || 0;
|
|
98
|
+
|
|
99
|
+
if (newCount > oldCount) {
|
|
100
|
+
trends[severity] = 'increasing';
|
|
101
|
+
} else if (newCount < oldCount) {
|
|
102
|
+
trends[severity] = 'decreasing';
|
|
103
|
+
} else {
|
|
104
|
+
trends[severity] = 'stable';
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return trends;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Calculate category trend between reports
|
|
113
|
+
* @param {Object} oldReport - Previous compliance report
|
|
114
|
+
* @param {Object} newReport - Current compliance report
|
|
115
|
+
* @returns {Object} - Category trend analysis
|
|
116
|
+
*/
|
|
117
|
+
function calculateCategoryTrend(oldReport, newReport) {
|
|
118
|
+
const oldCategories = getCategoryDistribution(oldReport);
|
|
119
|
+
const newCategories = getCategoryDistribution(newReport);
|
|
120
|
+
|
|
121
|
+
const trends = {};
|
|
122
|
+
|
|
123
|
+
Object.keys(oldCategories).forEach(category => {
|
|
124
|
+
const oldCount = oldCategories[category] || 0;
|
|
125
|
+
const newCount = newCategories[category] || 0;
|
|
126
|
+
|
|
127
|
+
if (newCount > oldCount) {
|
|
128
|
+
trends[category] = 'increasing';
|
|
129
|
+
} else if (newCount < oldCount) {
|
|
130
|
+
trends[category] = 'decreasing';
|
|
131
|
+
} else {
|
|
132
|
+
trends[category] = 'stable';
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return trends;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get severity distribution from report
|
|
141
|
+
* @param {Object} report - Compliance report
|
|
142
|
+
* @returns {Object} - Severity distribution
|
|
143
|
+
*/
|
|
144
|
+
function getSeverityDistribution(report) {
|
|
145
|
+
const distribution = {
|
|
146
|
+
critical: 0,
|
|
147
|
+
high: 0,
|
|
148
|
+
medium: 0,
|
|
149
|
+
low: 0
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
if (report.files) {
|
|
153
|
+
report.files.forEach(file => {
|
|
154
|
+
if (file.issues) {
|
|
155
|
+
file.issues.forEach(issue => {
|
|
156
|
+
const severity = issue.severity || 'medium';
|
|
157
|
+
if (distribution[severity] !== undefined) {
|
|
158
|
+
distribution[severity]++;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return distribution;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get category distribution from report
|
|
170
|
+
* @param {Object} report - Compliance report
|
|
171
|
+
* @returns {Object} - Category distribution
|
|
172
|
+
*/
|
|
173
|
+
function getCategoryDistribution(report) {
|
|
174
|
+
const distribution = {};
|
|
175
|
+
|
|
176
|
+
if (report.files) {
|
|
177
|
+
report.files.forEach(file => {
|
|
178
|
+
if (file.issues) {
|
|
179
|
+
file.issues.forEach(issue => {
|
|
180
|
+
const category = issue.category || 'general';
|
|
181
|
+
distribution[category] = (distribution[category] || 0) + 1;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return distribution;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Generate comparison recommendations
|
|
192
|
+
* @param {Object} oldReport - Previous compliance report
|
|
193
|
+
* @param {Object} newReport - Current compliance report
|
|
194
|
+
* @returns {Array} - Recommendations
|
|
195
|
+
*/
|
|
196
|
+
function generateComparisonRecommendations(oldReport, newReport) {
|
|
197
|
+
const recommendations = [];
|
|
198
|
+
const scoreChange = newReport.summary.overallComplianceScore - oldReport.summary.overallComplianceScore;
|
|
199
|
+
|
|
200
|
+
// Negative trends
|
|
201
|
+
if (scoreChange < -5) {
|
|
202
|
+
recommendations.push({
|
|
203
|
+
type: 'urgent',
|
|
204
|
+
title: 'Compliance Score Declining',
|
|
205
|
+
description: `Compliance score decreased by ${Math.abs(scoreChange).toFixed(1)}%`,
|
|
206
|
+
action: 'Investigate and address causes of compliance decline'
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (newReport.summary.totalIssues > oldReport.summary.totalIssues) {
|
|
211
|
+
recommendations.push({
|
|
212
|
+
type: 'quality',
|
|
213
|
+
title: 'Increasing Issue Count',
|
|
214
|
+
description: `Total issues increased from ${oldReport.summary.totalIssues} to ${newReport.summary.totalIssues}`,
|
|
215
|
+
action: 'Review code quality and development practices'
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Positive trends
|
|
220
|
+
if (scoreChange > 5) {
|
|
221
|
+
recommendations.push({
|
|
222
|
+
type: 'positive',
|
|
223
|
+
title: 'Compliance Improving',
|
|
224
|
+
description: `Compliance score improved by ${scoreChange.toFixed(1)}%`,
|
|
225
|
+
action: 'Continue current compliance practices'
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (newReport.summary.totalIssues < oldReport.summary.totalIssues) {
|
|
230
|
+
recommendations.push({
|
|
231
|
+
type: 'positive',
|
|
232
|
+
title: 'Issues Decreasing',
|
|
233
|
+
description: `Total issues decreased from ${oldReport.summary.totalIssues} to ${newReport.summary.totalIssues}`,
|
|
234
|
+
action: 'Maintain focus on code quality and compliance'
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Stability recommendations
|
|
239
|
+
if (Math.abs(scoreChange) < 1) {
|
|
240
|
+
recommendations.push({
|
|
241
|
+
type: 'monitoring',
|
|
242
|
+
title: 'Compliance Stable',
|
|
243
|
+
description: 'Compliance score has remained stable',
|
|
244
|
+
action: 'Continue monitoring and consider continuous integration improvements'
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return recommendations;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Generate trend summary
|
|
253
|
+
* @param {Object} trends - Trend analysis
|
|
254
|
+
* @returns {string} - Trend summary
|
|
255
|
+
*/
|
|
256
|
+
function generateTrendSummary(trends) {
|
|
257
|
+
const positive = [];
|
|
258
|
+
const negative = [];
|
|
259
|
+
|
|
260
|
+
Object.entries(trends).forEach(([key, trend]) => {
|
|
261
|
+
if (trend === 'improving' || trend === 'decreasing') {
|
|
262
|
+
positive.push(key);
|
|
263
|
+
} else if (trend === 'declining' || trend === 'increasing') {
|
|
264
|
+
negative.push(key);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
let summary = 'Trends show ';
|
|
269
|
+
|
|
270
|
+
if (positive.length > 0 && negative.length > 0) {
|
|
271
|
+
summary += `mixed results with improvements in ${positive.join(', ')} but concerns in ${negative.join(', ')}`;
|
|
272
|
+
} else if (positive.length > 0) {
|
|
273
|
+
summary += `positive trends in ${positive.join(', ')}`;
|
|
274
|
+
} else if (negative.length > 0) {
|
|
275
|
+
summary += `concerning trends in ${negative.join(', ')}`;
|
|
276
|
+
} else {
|
|
277
|
+
summary += 'stable conditions across all metrics';
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
return summary;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Calculate compliance velocity
|
|
285
|
+
* @param {Array} reports - Array of compliance reports
|
|
286
|
+
* @returns {Object} - Velocity metrics
|
|
287
|
+
*/
|
|
288
|
+
function calculateComplianceVelocity(reports) {
|
|
289
|
+
if (reports.length < 2) {
|
|
290
|
+
return {
|
|
291
|
+
averageScoreChange: 0,
|
|
292
|
+
averageIssueChange: 0,
|
|
293
|
+
velocity: 'insufficient-data'
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
let totalScoreChange = 0;
|
|
298
|
+
let totalIssueChange = 0;
|
|
299
|
+
|
|
300
|
+
for (let i = 1; i < reports.length; i++) {
|
|
301
|
+
const scoreChange = reports[i].summary.overallComplianceScore - reports[i-1].summary.overallComplianceScore;
|
|
302
|
+
const issueChange = reports[i].summary.totalIssues - reports[i-1].summary.totalIssues;
|
|
303
|
+
|
|
304
|
+
totalScoreChange += scoreChange;
|
|
305
|
+
totalIssueChange += issueChange;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const periods = reports.length - 1;
|
|
309
|
+
const averageScoreChange = totalScoreChange / periods;
|
|
310
|
+
const averageIssueChange = totalIssueChange / periods;
|
|
311
|
+
|
|
312
|
+
let velocity = 'stable';
|
|
313
|
+
if (averageScoreChange > 2) velocity = 'improving';
|
|
314
|
+
else if (averageScoreChange < -2) velocity = 'declining';
|
|
315
|
+
|
|
316
|
+
return {
|
|
317
|
+
averageScoreChange,
|
|
318
|
+
averageIssueChange,
|
|
319
|
+
velocity,
|
|
320
|
+
periods
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
module.exports = {
|
|
325
|
+
generateComparisonReport,
|
|
326
|
+
calculatePeriod,
|
|
327
|
+
calculateTrends,
|
|
328
|
+
calculateSeverityTrend,
|
|
329
|
+
calculateCategoryTrend,
|
|
330
|
+
generateComparisonRecommendations,
|
|
331
|
+
generateTrendSummary,
|
|
332
|
+
calculateComplianceVelocity
|
|
333
|
+
};
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compliance Report Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates comprehensive compliance reports in various formats,
|
|
5
|
+
* integrating validation results, metrics, and recommendations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { ComplianceReport, FileComplianceSummary, ComplianceIssue } = require('../models/compliance-report');
|
|
11
|
+
const MetricsCalculator = require('./metrics-calculator');
|
|
12
|
+
const {
|
|
13
|
+
createComplianceReport,
|
|
14
|
+
calculateComplianceMetrics,
|
|
15
|
+
generateComplianceRecommendations,
|
|
16
|
+
validateComplianceReport
|
|
17
|
+
} = require('./compliance-utils');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Report Generator class
|
|
21
|
+
*/
|
|
22
|
+
class ReportGenerator {
|
|
23
|
+
constructor(options = {}) {
|
|
24
|
+
this.options = {
|
|
25
|
+
outputDir: options.outputDir || './reports',
|
|
26
|
+
formats: options.formats || ['json', 'html', 'markdown'],
|
|
27
|
+
includeMetrics: options.includeMetrics !== false,
|
|
28
|
+
includeRecommendations: options.includeRecommendations !== false,
|
|
29
|
+
includeCharts: options.includeCharts !== false,
|
|
30
|
+
...options
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
generateReport(data, format) {
|
|
35
|
+
switch (format.toLowerCase()) {
|
|
36
|
+
case 'json':
|
|
37
|
+
return this.generateJSONReport(data);
|
|
38
|
+
case 'html':
|
|
39
|
+
return this.generateHTMLReport(data);
|
|
40
|
+
case 'markdown':
|
|
41
|
+
return this.generateMarkdownReport(data);
|
|
42
|
+
default:
|
|
43
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
generateJSONReport(data) {
|
|
48
|
+
return JSON.stringify(data, null, 2);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
generateHTMLReport(data) {
|
|
52
|
+
const { report, metrics, recommendations } = data;
|
|
53
|
+
|
|
54
|
+
return `
|
|
55
|
+
<!DOCTYPE html>
|
|
56
|
+
<html>
|
|
57
|
+
<head>
|
|
58
|
+
<title>Compliance Report</title>
|
|
59
|
+
<style>
|
|
60
|
+
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
61
|
+
.header { background: #f5f5f5; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
|
|
62
|
+
.summary { display: flex; gap: 20px; margin-bottom: 20px; }
|
|
63
|
+
.metric { background: #e9ecef; padding: 15px; border-radius: 5px; flex: 1; }
|
|
64
|
+
.metric h3 { margin: 0 0 10px 0; color: #333; }
|
|
65
|
+
.metric .value { font-size: 24px; font-weight: bold; color: #007bff; }
|
|
66
|
+
.issues { background: #fff3cd; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
|
|
67
|
+
.recommendations { background: #d4edda; padding: 15px; border-radius: 5px; }
|
|
68
|
+
.recommendation { margin-bottom: 10px; padding: 10px; background: white; border-radius: 3px; }
|
|
69
|
+
.high { border-left: 4px solid #dc3545; }
|
|
70
|
+
.medium { border-left: 4px solid #ffc107; }
|
|
71
|
+
.low { border-left: 4px solid #28a745; }
|
|
72
|
+
</style>
|
|
73
|
+
</head>
|
|
74
|
+
<body>
|
|
75
|
+
<div class="header">
|
|
76
|
+
<h1>Compliance Report</h1>
|
|
77
|
+
<p>Generated: ${report.metadata.generatedAt}</p>
|
|
78
|
+
<p>Total Files: ${report.metadata.totalFiles}</p>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class="summary">
|
|
82
|
+
<div class="metric">
|
|
83
|
+
<h3>Compliance Rate</h3>
|
|
84
|
+
<div class="value">${metrics.complianceRate}%</div>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="metric">
|
|
87
|
+
<h3>Total Issues</h3>
|
|
88
|
+
<div class="value">${metrics.totalIssues}</div>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="metric">
|
|
91
|
+
<h3>Files Over Limit</h3>
|
|
92
|
+
<div class="value">${metrics.fileMetrics ? metrics.fileMetrics.filesOverLimit : 0}</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
${metrics.totalIssues > 0 ? `
|
|
97
|
+
<div class="issues">
|
|
98
|
+
<h2>Issues Found</h2>
|
|
99
|
+
<p>${metrics.totalIssues} issues need to be addressed</p>
|
|
100
|
+
</div>
|
|
101
|
+
` : ''}
|
|
102
|
+
|
|
103
|
+
<div class="recommendations">
|
|
104
|
+
<h2>Recommendations</h2>
|
|
105
|
+
${recommendations.map(rec => `
|
|
106
|
+
<div class="recommendation ${rec.priority}">
|
|
107
|
+
<strong>${rec.title}</strong>
|
|
108
|
+
<p>${rec.description}</p>
|
|
109
|
+
</div>
|
|
110
|
+
`).join('')}
|
|
111
|
+
</div>
|
|
112
|
+
</body>
|
|
113
|
+
</html>`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
generateMarkdownReport(data) {
|
|
117
|
+
const { report, metrics, recommendations } = data;
|
|
118
|
+
|
|
119
|
+
return `
|
|
120
|
+
# Compliance Report
|
|
121
|
+
|
|
122
|
+
**Generated:** ${report.metadata.generatedAt}
|
|
123
|
+
|
|
124
|
+
## Summary
|
|
125
|
+
|
|
126
|
+
- **Total Files:** ${report.metadata.totalFiles}
|
|
127
|
+
- **Compliance Rate:** ${metrics.complianceRate}%
|
|
128
|
+
- **Total Issues:** ${metrics.totalIssues}
|
|
129
|
+
- **Files Over Limit:** ${metrics.fileMetrics ? metrics.fileMetrics.filesOverLimit : 0}
|
|
130
|
+
|
|
131
|
+
${metrics.totalIssues > 0 ? `
|
|
132
|
+
## Issues
|
|
133
|
+
|
|
134
|
+
${metrics.totalIssues} issues need to be addressed.
|
|
135
|
+
|
|
136
|
+
` : ''}
|
|
137
|
+
|
|
138
|
+
## Recommendations
|
|
139
|
+
|
|
140
|
+
${recommendations.map(rec => `
|
|
141
|
+
### ${rec.title} (${rec.priority})
|
|
142
|
+
|
|
143
|
+
${rec.description}
|
|
144
|
+
|
|
145
|
+
`).join('')}
|
|
146
|
+
`.trim();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Compliance Reporter class
|
|
152
|
+
*/
|
|
153
|
+
class ComplianceReporter {
|
|
154
|
+
constructor(options = {}) {
|
|
155
|
+
this.options = {
|
|
156
|
+
outputDir: options.outputDir || './reports',
|
|
157
|
+
formats: options.formats || ['json', 'html', 'markdown'],
|
|
158
|
+
includeMetrics: options.includeMetrics !== false,
|
|
159
|
+
includeRecommendations: options.includeRecommendations !== false,
|
|
160
|
+
includeCharts: options.includeCharts !== false,
|
|
161
|
+
...options
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
this.metricsCalculator = new MetricsCalculator();
|
|
165
|
+
this.reportGenerator = new ReportGenerator(this.options);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async generateReport(validationResults, options = {}) {
|
|
169
|
+
const reportOptions = { ...this.options, ...options };
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const complianceReport = createComplianceReport(validationResults, reportOptions);
|
|
173
|
+
|
|
174
|
+
let metrics = null;
|
|
175
|
+
if (reportOptions.includeMetrics) {
|
|
176
|
+
metrics = calculateComplianceMetrics(complianceReport);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let recommendations = null;
|
|
180
|
+
if (reportOptions.includeRecommendations) {
|
|
181
|
+
recommendations = generateComplianceRecommendations(complianceReport);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const reportData = {
|
|
185
|
+
report: complianceReport,
|
|
186
|
+
metrics,
|
|
187
|
+
recommendations
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const generatedReports = await this.generateReportsInFormats(reportData, reportOptions);
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
success: true,
|
|
194
|
+
report: complianceReport,
|
|
195
|
+
metrics,
|
|
196
|
+
recommendations,
|
|
197
|
+
generatedReports,
|
|
198
|
+
summary: {
|
|
199
|
+
totalFiles: validationResults.length,
|
|
200
|
+
complianceRate: metrics ? metrics.complianceRate : 0,
|
|
201
|
+
totalIssues: metrics ? metrics.totalIssues : 0,
|
|
202
|
+
formats: Object.keys(generatedReports)
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
} catch (error) {
|
|
207
|
+
return {
|
|
208
|
+
success: false,
|
|
209
|
+
error: error.message,
|
|
210
|
+
report: null,
|
|
211
|
+
metrics: null,
|
|
212
|
+
recommendations: null
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async generateReportsInFormats(reportData, options) {
|
|
218
|
+
const reports = {};
|
|
219
|
+
const formats = options.formats || ['json'];
|
|
220
|
+
|
|
221
|
+
await fs.promises.mkdir(this.options.outputDir, { recursive: true });
|
|
222
|
+
|
|
223
|
+
for (const format of formats) {
|
|
224
|
+
try {
|
|
225
|
+
const content = this.reportGenerator.generateReport(reportData, format);
|
|
226
|
+
const filename = `compliance-report.${format}`;
|
|
227
|
+
const filepath = path.join(this.options.outputDir, filename);
|
|
228
|
+
|
|
229
|
+
await fs.promises.writeFile(filepath, content, 'utf8');
|
|
230
|
+
reports[format] = {
|
|
231
|
+
success: true,
|
|
232
|
+
filepath,
|
|
233
|
+
size: content.length
|
|
234
|
+
};
|
|
235
|
+
} catch (error) {
|
|
236
|
+
reports[format] = {
|
|
237
|
+
success: false,
|
|
238
|
+
error: error.message
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return reports;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getReporterInfo() {
|
|
247
|
+
return {
|
|
248
|
+
supportedFormats: ['json', 'html', 'markdown'],
|
|
249
|
+
defaultOptions: this.options,
|
|
250
|
+
features: [
|
|
251
|
+
'multi-format output',
|
|
252
|
+
'metrics calculation',
|
|
253
|
+
'recommendations generation',
|
|
254
|
+
'compliance validation'
|
|
255
|
+
],
|
|
256
|
+
version: '1.0.0'
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static createDefault(config = {}) {
|
|
261
|
+
return new ComplianceReporter({
|
|
262
|
+
outputDir: './reports',
|
|
263
|
+
formats: ['json', 'html'],
|
|
264
|
+
includeMetrics: true,
|
|
265
|
+
includeRecommendations: true,
|
|
266
|
+
...config
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
static createForCI(config = {}) {
|
|
271
|
+
return new ComplianceReporter({
|
|
272
|
+
outputDir: './compliance-reports',
|
|
273
|
+
formats: ['json', 'markdown'],
|
|
274
|
+
includeMetrics: true,
|
|
275
|
+
includeRecommendations: true,
|
|
276
|
+
includeCharts: false,
|
|
277
|
+
...config
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
module.exports = ComplianceReporter;
|