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
|
@@ -3,18 +3,21 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates comprehensive compliance reports in various formats,
|
|
5
5
|
* integrating validation results, metrics, and recommendations.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
6
|
const fs = require('fs');
|
|
9
7
|
const path = require('path');
|
|
10
8
|
const { ComplianceReport, FileComplianceSummary, ComplianceIssue } = require('../models/compliance-report');
|
|
11
9
|
const MetricsCalculator = require('./metrics-calculator');
|
|
12
|
-
const
|
|
10
|
+
const {
|
|
11
|
+
createComplianceReport,
|
|
12
|
+
calculateComplianceMetrics,
|
|
13
|
+
generateComplianceRecommendations,
|
|
14
|
+
validateComplianceReport
|
|
15
|
+
} = require('./compliance-utils');
|
|
13
16
|
|
|
14
17
|
/**
|
|
15
|
-
* Report
|
|
18
|
+
* Report Generator class
|
|
16
19
|
*/
|
|
17
|
-
class
|
|
20
|
+
class ReportGenerator {
|
|
18
21
|
constructor(options = {}) {
|
|
19
22
|
this.options = {
|
|
20
23
|
outputDir: options.outputDir || './reports',
|
|
@@ -24,688 +27,372 @@ class ComplianceReporter {
|
|
|
24
27
|
includeCharts: options.includeCharts !== false,
|
|
25
28
|
...options
|
|
26
29
|
};
|
|
27
|
-
|
|
28
|
-
this.metricsCalculator = new MetricsCalculator();
|
|
29
|
-
this.reportGenerator = ReportGenerator || this.createFallbackReportGenerator();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Generate comprehensive compliance report
|
|
34
|
-
*/
|
|
35
|
-
async generateReport(validationResults, options = {}) {
|
|
36
|
-
const reportOptions = { ...this.options, ...options };
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
// Create compliance report
|
|
40
|
-
const complianceReport = this.createComplianceReport(validationResults, reportOptions);
|
|
41
|
-
|
|
42
|
-
// Calculate metrics if enabled
|
|
43
|
-
if (reportOptions.includeMetrics) {
|
|
44
|
-
complianceReport.metrics = this.metricsCalculator.calculateMetrics(complianceReport);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Generate reports in requested formats
|
|
48
|
-
const generatedReports = await this.generateReportsInFormats(complianceReport, reportOptions);
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
report: complianceReport,
|
|
52
|
-
files: generatedReports,
|
|
53
|
-
summary: this.generateReportSummary(complianceReport, generatedReports)
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
} catch (error) {
|
|
57
|
-
throw new Error(`Failed to generate compliance report: ${error.message}`);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Create compliance report from validation results
|
|
63
|
-
*/
|
|
64
|
-
createComplianceReport(validationResults, options) {
|
|
65
|
-
const report = new ComplianceReport({
|
|
66
|
-
title: options.title || 'Codebase Compliance Report',
|
|
67
|
-
description: options.description || 'Comprehensive analysis of codebase compliance with constitutional requirements',
|
|
68
|
-
scope: options.scope || 'full',
|
|
69
|
-
scopePath: options.scopePath || process.cwd(),
|
|
70
|
-
generatedAt: new Date().toISOString()
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
// Process validation results
|
|
74
|
-
for (const validationResult of validationResults) {
|
|
75
|
-
const fileSummary = this.createFileSummary(validationResult);
|
|
76
|
-
report.addFileSummary(fileSummary);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return report;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Create file summary from validation result
|
|
84
|
-
*/
|
|
85
|
-
createFileSummary(validationResult) {
|
|
86
|
-
const fileSummary = new FileComplianceSummary({
|
|
87
|
-
filePath: validationResult.filePath,
|
|
88
|
-
lineCount: validationResult.lineCount || 0,
|
|
89
|
-
fileSize: validationResult.fileSize || 0
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
// Add issues from validation result
|
|
93
|
-
if (validationResult.issues) {
|
|
94
|
-
for (const issue of validationResult.issues) {
|
|
95
|
-
fileSummary.addIssue(new ComplianceIssue({
|
|
96
|
-
filePath: validationResult.filePath,
|
|
97
|
-
...issue
|
|
98
|
-
}));
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Add line limit violations
|
|
103
|
-
if (validationResult.lineLimitViolation) {
|
|
104
|
-
fileSummary.addIssue(new ComplianceIssue({
|
|
105
|
-
filePath: validationResult.filePath,
|
|
106
|
-
category: 'file_size',
|
|
107
|
-
severity: validationResult.lineLimitViolation.severity || 'error',
|
|
108
|
-
rule: 'file_size_limit',
|
|
109
|
-
message: validationResult.lineLimitViolation.message,
|
|
110
|
-
description: `File exceeds 555-line limit with ${validationResult.lineCount} lines`,
|
|
111
|
-
suggestion: 'Refactor file into smaller modules',
|
|
112
|
-
lineNumber: null
|
|
113
|
-
}));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return fileSummary;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Generate reports in multiple formats
|
|
121
|
-
*/
|
|
122
|
-
async generateReportsInFormats(complianceReport, options) {
|
|
123
|
-
const generatedFiles = [];
|
|
124
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
125
|
-
const baseName = `compliance-report-${timestamp}`;
|
|
126
|
-
|
|
127
|
-
// Ensure output directory exists
|
|
128
|
-
if (!fs.existsSync(options.outputDir)) {
|
|
129
|
-
fs.mkdirSync(options.outputDir, { recursive: true });
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
for (const format of options.formats) {
|
|
133
|
-
try {
|
|
134
|
-
const fileName = `${baseName}.${format}`;
|
|
135
|
-
const filePath = path.join(options.outputDir, fileName);
|
|
136
|
-
|
|
137
|
-
await this.generateReportInFormat(complianceReport, format, filePath, options);
|
|
138
|
-
|
|
139
|
-
generatedFiles.push({
|
|
140
|
-
format,
|
|
141
|
-
fileName,
|
|
142
|
-
filePath,
|
|
143
|
-
size: fs.statSync(filePath).size
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
} catch (error) {
|
|
147
|
-
console.warn(`Failed to generate ${format} report: ${error.message}`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return generatedFiles;
|
|
152
30
|
}
|
|
153
31
|
|
|
154
|
-
|
|
155
|
-
* Generate report in specific format
|
|
156
|
-
*/
|
|
157
|
-
async generateReportInFormat(complianceReport, format, filePath, options) {
|
|
32
|
+
generateReport(data, format) {
|
|
158
33
|
switch (format.toLowerCase()) {
|
|
159
34
|
case 'json':
|
|
160
|
-
|
|
161
|
-
break;
|
|
35
|
+
return this.generateJSONReport(data);
|
|
162
36
|
case 'html':
|
|
163
|
-
|
|
164
|
-
break;
|
|
37
|
+
return this.generateHTMLReport(data);
|
|
165
38
|
case 'markdown':
|
|
166
|
-
|
|
167
|
-
break;
|
|
168
|
-
case 'csv':
|
|
169
|
-
await this.generateCsvReport(complianceReport, filePath, options);
|
|
170
|
-
break;
|
|
171
|
-
case 'pdf':
|
|
172
|
-
await this.generatePdfReport(complianceReport, filePath, options);
|
|
173
|
-
break;
|
|
39
|
+
return this.generateMarkdownReport(data);
|
|
174
40
|
default:
|
|
175
|
-
throw new Error(`Unsupported
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Generate JSON report
|
|
181
|
-
*/
|
|
182
|
-
async generateJsonReport(complianceReport, filePath, options) {
|
|
183
|
-
const reportData = {
|
|
184
|
-
metadata: {
|
|
185
|
-
generatedAt: complianceReport.generatedAt,
|
|
186
|
-
generator: 'ComplianceReporter',
|
|
187
|
-
version: '1.0.0',
|
|
188
|
-
options: options
|
|
189
|
-
},
|
|
190
|
-
report: complianceReport.toJSON()
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
fs.writeFileSync(filePath, JSON.stringify(reportData, null, 2), 'utf8');
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Generate HTML report
|
|
198
|
-
*/
|
|
199
|
-
async generateHtmlReport(complianceReport, filePath, options) {
|
|
200
|
-
const html = this.generateHtmlContent(complianceReport, options);
|
|
201
|
-
fs.writeFileSync(filePath, html, 'utf8');
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Generate Markdown report
|
|
206
|
-
*/
|
|
207
|
-
async generateMarkdownReport(complianceReport, filePath, options) {
|
|
208
|
-
const markdown = complianceReport.generateDetailedReport();
|
|
209
|
-
fs.writeFileSync(filePath, markdown, 'utf8');
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Generate CSV report
|
|
214
|
-
*/
|
|
215
|
-
async generateCsvReport(complianceReport, filePath, options) {
|
|
216
|
-
let csv = 'File Path,Line Count,Status,Compliance Score,Total Issues,Critical Issues,Violation Issues,Warning Issues\n';
|
|
217
|
-
|
|
218
|
-
for (const fileSummary of complianceReport.fileSummaries) {
|
|
219
|
-
csv += `"${fileSummary.filePath}",${fileSummary.lineCount},${fileSummary.status},${fileSummary.complianceScore},${fileSummary.totalIssues},${fileSummary.criticalIssues},${fileSummary.violationIssues},${fileSummary.warningIssues}\n`;
|
|
41
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
220
42
|
}
|
|
221
|
-
|
|
222
|
-
fs.writeFileSync(filePath, csv, 'utf8');
|
|
223
43
|
}
|
|
224
44
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
*/
|
|
228
|
-
async generatePdfReport(complianceReport, filePath, options) {
|
|
229
|
-
// This would typically use a PDF generation library
|
|
230
|
-
// For now, generate a text file as placeholder
|
|
231
|
-
const text = complianceReport.generateDetailedReport();
|
|
232
|
-
fs.writeFileSync(filePath.replace('.pdf', '.txt'), text, 'utf8');
|
|
45
|
+
generateJSONReport(data) {
|
|
46
|
+
return JSON.stringify(data, null, 2);
|
|
233
47
|
}
|
|
234
48
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
*/
|
|
238
|
-
generateHtmlContent(complianceReport, options) {
|
|
239
|
-
const summary = complianceReport.summary;
|
|
240
|
-
const metrics = complianceReport.metrics;
|
|
49
|
+
generateHTMLReport(data) {
|
|
50
|
+
const { report, metrics, recommendations } = data;
|
|
241
51
|
|
|
242
|
-
|
|
52
|
+
return `
|
|
243
53
|
<!DOCTYPE html>
|
|
244
|
-
<html
|
|
54
|
+
<html>
|
|
245
55
|
<head>
|
|
246
|
-
<
|
|
247
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
248
|
-
<title>${complianceReport.title}</title>
|
|
56
|
+
<title>Compliance Report</title>
|
|
249
57
|
<style>
|
|
250
|
-
body { font-family: Arial, sans-serif; margin: 20px;
|
|
251
|
-
.header { background: #
|
|
252
|
-
.summary { display:
|
|
253
|
-
.metric { background: #
|
|
58
|
+
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
59
|
+
.header { background: #f5f5f5; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
|
|
60
|
+
.summary { display: flex; gap: 20px; margin-bottom: 20px; }
|
|
61
|
+
.metric { background: #e9ecef; padding: 15px; border-radius: 5px; flex: 1; }
|
|
254
62
|
.metric h3 { margin: 0 0 10px 0; color: #333; }
|
|
255
|
-
.metric .value { font-size:
|
|
256
|
-
.
|
|
257
|
-
.
|
|
258
|
-
.
|
|
259
|
-
.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
th { background: #f4f4f4; }
|
|
263
|
-
.status-icon { margin-right: 5px; }
|
|
264
|
-
.recommendations { background: #e7f3ff; padding: 15px; border-radius: 5px; margin-top: 20px; }
|
|
265
|
-
.chart { margin: 20px 0; text-align: center; }
|
|
63
|
+
.metric .value { font-size: 24px; font-weight: bold; color: #007bff; }
|
|
64
|
+
.issues { background: #fff3cd; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
|
|
65
|
+
.recommendations { background: #d4edda; padding: 15px; border-radius: 5px; }
|
|
66
|
+
.recommendation { margin-bottom: 10px; padding: 10px; background: white; border-radius: 3px; }
|
|
67
|
+
.high { border-left: 4px solid #dc3545; }
|
|
68
|
+
.medium { border-left: 4px solid #ffc107; }
|
|
69
|
+
.low { border-left: 4px solid #28a745; }
|
|
266
70
|
</style>
|
|
267
71
|
</head>
|
|
268
72
|
<body>
|
|
269
73
|
<div class="header">
|
|
270
|
-
<h1
|
|
271
|
-
<p
|
|
272
|
-
<p
|
|
273
|
-
<p><strong>Overall Compliance Score:</strong> <span class="value ${this.getScoreClass(summary.overallComplianceScore)}">${summary.overallComplianceScore.toFixed(1)}%</span></p>
|
|
74
|
+
<h1>Compliance Report</h1>
|
|
75
|
+
<p>Generated: ${report.metadata.generatedAt}</p>
|
|
76
|
+
<p>Total Files: ${report.metadata.totalFiles}</p>
|
|
274
77
|
</div>
|
|
275
|
-
|
|
78
|
+
|
|
276
79
|
<div class="summary">
|
|
277
80
|
<div class="metric">
|
|
278
|
-
<h3>
|
|
279
|
-
<div class="value">${
|
|
280
|
-
</div>
|
|
281
|
-
<div class="metric">
|
|
282
|
-
<h3>Compliant Files</h3>
|
|
283
|
-
<div class="value compliant">${summary.compliantFiles}</div>
|
|
284
|
-
</div>
|
|
285
|
-
<div class="metric">
|
|
286
|
-
<h3>Warning Files</h3>
|
|
287
|
-
<div class="value warning">${summary.warningFiles}</div>
|
|
288
|
-
</div>
|
|
289
|
-
<div class="metric">
|
|
290
|
-
<h3>Violation Files</h3>
|
|
291
|
-
<div class="value violation">${summary.violationFiles}</div>
|
|
81
|
+
<h3>Compliance Rate</h3>
|
|
82
|
+
<div class="value">${metrics.complianceRate}%</div>
|
|
292
83
|
</div>
|
|
293
84
|
<div class="metric">
|
|
294
|
-
<h3>
|
|
295
|
-
<div class="value
|
|
85
|
+
<h3>Total Issues</h3>
|
|
86
|
+
<div class="value">${metrics.totalIssues}</div>
|
|
296
87
|
</div>
|
|
297
88
|
<div class="metric">
|
|
298
|
-
<h3>
|
|
299
|
-
<div class="value">${
|
|
89
|
+
<h3>Files Over Limit</h3>
|
|
90
|
+
<div class="value">${metrics.fileMetrics ? metrics.fileMetrics.filesOverLimit : 0}</div>
|
|
300
91
|
</div>
|
|
301
92
|
</div>
|
|
302
|
-
|
|
93
|
+
|
|
94
|
+
${metrics.totalIssues > 0 ? `
|
|
95
|
+
<div class="issues">
|
|
96
|
+
<h2>Issues Found</h2>
|
|
97
|
+
<p>${metrics.totalIssues} issues need to be addressed</p>
|
|
98
|
+
</div>
|
|
99
|
+
` : ''}
|
|
100
|
+
|
|
101
|
+
<div class="recommendations">
|
|
102
|
+
<h2>Recommendations</h2>
|
|
103
|
+
${recommendations.map(rec => `
|
|
104
|
+
<div class="recommendation ${rec.priority}">
|
|
105
|
+
<strong>${rec.title}</strong>
|
|
106
|
+
<p>${rec.description}</p>
|
|
107
|
+
</div>
|
|
108
|
+
`).join('')}
|
|
109
|
+
</div>
|
|
110
|
+
</body>
|
|
111
|
+
</html>`;
|
|
112
|
+
}
|
|
303
113
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
114
|
+
generateMarkdownReport(data) {
|
|
115
|
+
const { report, metrics, recommendations } = data;
|
|
116
|
+
|
|
117
|
+
return `
|
|
118
|
+
# Compliance Report
|
|
308
119
|
|
|
309
|
-
|
|
310
|
-
html += `
|
|
311
|
-
<h2>File Details</h2>
|
|
312
|
-
<table>
|
|
313
|
-
<thead>
|
|
314
|
-
<tr>
|
|
315
|
-
<th>File</th>
|
|
316
|
-
<th>Lines</th>
|
|
317
|
-
<th>Status</th>
|
|
318
|
-
<th>Score</th>
|
|
319
|
-
<th>Issues</th>
|
|
320
|
-
<th>Details</th>
|
|
321
|
-
</tr>
|
|
322
|
-
</thead>
|
|
323
|
-
<tbody>
|
|
324
|
-
`;
|
|
120
|
+
**Generated:** ${report.metadata.generatedAt}
|
|
325
121
|
|
|
326
|
-
|
|
327
|
-
const statusIcon = this.getStatusIcon(fileSummary.status);
|
|
328
|
-
const statusClass = this.getScoreClass(fileSummary.complianceScore);
|
|
329
|
-
|
|
330
|
-
html += `
|
|
331
|
-
<tr>
|
|
332
|
-
<td><code>${fileSummary.filePath}</code></td>
|
|
333
|
-
<td>${fileSummary.lineCount}</td>
|
|
334
|
-
<td><span class="status-icon">${statusIcon}</span>${fileSummary.status}</td>
|
|
335
|
-
<td><span class="${statusClass}">${fileSummary.complianceScore.toFixed(1)}%</span></td>
|
|
336
|
-
<td>${fileSummary.totalIssues}</td>
|
|
337
|
-
<td>
|
|
338
|
-
${fileSummary.criticalIssues > 0 ? `${fileSummary.criticalIssues} critical` : ''}
|
|
339
|
-
${fileSummary.violationIssues > 0 ? `${fileSummary.violationIssues} violations` : ''}
|
|
340
|
-
${fileSummary.warningIssues > 0 ? `${fileSummary.warningIssues} warnings` : ''}
|
|
341
|
-
</td>
|
|
342
|
-
</tr>
|
|
343
|
-
`;
|
|
344
|
-
}
|
|
122
|
+
## Summary
|
|
345
123
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
124
|
+
- **Total Files:** ${report.metadata.totalFiles}
|
|
125
|
+
- **Compliance Rate:** ${metrics.complianceRate}%
|
|
126
|
+
- **Total Issues:** ${metrics.totalIssues}
|
|
127
|
+
- **Files Over Limit:** ${metrics.fileMetrics ? metrics.fileMetrics.filesOverLimit : 0}
|
|
350
128
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
html += this.generateRecommendationsSection(complianceReport.recommendations);
|
|
354
|
-
}
|
|
129
|
+
${metrics.totalIssues > 0 ? `
|
|
130
|
+
## Issues
|
|
355
131
|
|
|
356
|
-
|
|
357
|
-
</body>
|
|
358
|
-
</html>`;
|
|
132
|
+
${metrics.totalIssues} issues need to be addressed.
|
|
359
133
|
|
|
360
|
-
|
|
361
|
-
}
|
|
134
|
+
` : ''}
|
|
362
135
|
|
|
363
|
-
|
|
364
|
-
* Generate metrics section for HTML report
|
|
365
|
-
*/
|
|
366
|
-
generateMetricsSection(metrics) {
|
|
367
|
-
let html = `
|
|
368
|
-
<h2>Metrics Analysis</h2>
|
|
369
|
-
<div class="summary">
|
|
370
|
-
`;
|
|
136
|
+
## Recommendations
|
|
371
137
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
html += `
|
|
375
|
-
<div class="metric">
|
|
376
|
-
<h3>Compliance Rate</h3>
|
|
377
|
-
<div class="value ${this.getScoreClass(metrics.overview.complianceRate)}">${metrics.overview.complianceRate.toFixed(1)}%</div>
|
|
378
|
-
</div>
|
|
379
|
-
<div class="metric">
|
|
380
|
-
<h3>Health Status</h3>
|
|
381
|
-
<div class="value">${metrics.overview.healthStatus}</div>
|
|
382
|
-
</div>
|
|
383
|
-
<div class="metric">
|
|
384
|
-
<h3>Avg Issues/File</h3>
|
|
385
|
-
<div class="value">${metrics.overview.averageIssuesPerFile.toFixed(1)}</div>
|
|
386
|
-
</div>
|
|
387
|
-
`;
|
|
388
|
-
}
|
|
138
|
+
${recommendations.map(rec => `
|
|
139
|
+
### ${rec.title} (${rec.priority})
|
|
389
140
|
|
|
390
|
-
|
|
391
|
-
</div>
|
|
392
|
-
`;
|
|
141
|
+
${rec.description}
|
|
393
142
|
|
|
394
|
-
|
|
143
|
+
`).join('')}
|
|
144
|
+
`.trim();
|
|
395
145
|
}
|
|
146
|
+
}
|
|
396
147
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Compliance Reporter class
|
|
150
|
+
*/
|
|
151
|
+
class ComplianceReporter {
|
|
152
|
+
constructor(options = {}) {
|
|
153
|
+
this.options = {
|
|
154
|
+
outputDir: options.outputDir || './reports',
|
|
155
|
+
formats: options.formats || ['json', 'html', 'markdown'],
|
|
156
|
+
includeMetrics: options.includeMetrics !== false,
|
|
157
|
+
includeRecommendations: options.includeRecommendations !== false,
|
|
158
|
+
includeCharts: options.includeCharts !== false,
|
|
159
|
+
...options
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
this.metricsCalculator = new MetricsCalculator();
|
|
163
|
+
this.reportGenerator = new ReportGenerator(this.options);
|
|
164
|
+
}
|
|
405
165
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
166
|
+
async generateReport(validationResults, options = {}) {
|
|
167
|
+
const reportOptions = { ...this.options, ...options };
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
const complianceReport = createComplianceReport(validationResults, reportOptions);
|
|
410
171
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
172
|
+
let metrics = null;
|
|
173
|
+
if (reportOptions.includeMetrics) {
|
|
174
|
+
metrics = calculateComplianceMetrics(complianceReport);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
let recommendations = null;
|
|
178
|
+
if (reportOptions.includeRecommendations) {
|
|
179
|
+
recommendations = generateComplianceRecommendations(complianceReport);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const reportData = {
|
|
183
|
+
report: complianceReport,
|
|
184
|
+
metrics,
|
|
185
|
+
recommendations
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
const generatedReports = await this.generateReportsInFormats(reportData, reportOptions);
|
|
189
|
+
|
|
190
|
+
return {
|
|
191
|
+
success: true,
|
|
192
|
+
report: complianceReport,
|
|
193
|
+
metrics,
|
|
194
|
+
recommendations,
|
|
195
|
+
generatedReports,
|
|
196
|
+
summary: {
|
|
197
|
+
totalFiles: validationResults.length,
|
|
198
|
+
complianceRate: metrics ? metrics.complianceRate : 0,
|
|
199
|
+
totalIssues: metrics ? metrics.totalIssues : 0,
|
|
200
|
+
formats: Object.keys(generatedReports)
|
|
201
|
+
}
|
|
202
|
+
};
|
|
426
203
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
};
|
|
437
|
-
return icons[status] || '❓';
|
|
204
|
+
} catch (error) {
|
|
205
|
+
return {
|
|
206
|
+
success: false,
|
|
207
|
+
error: error.message,
|
|
208
|
+
report: null,
|
|
209
|
+
metrics: null,
|
|
210
|
+
recommendations: null
|
|
211
|
+
};
|
|
212
|
+
}
|
|
438
213
|
}
|
|
439
214
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
215
|
+
async generateReportsInFormats(reportData, options) {
|
|
216
|
+
const reports = {};
|
|
217
|
+
const formats = options.formats || ['json'];
|
|
218
|
+
|
|
219
|
+
await fs.promises.mkdir(this.options.outputDir, { recursive: true });
|
|
220
|
+
|
|
221
|
+
for (const format of formats) {
|
|
222
|
+
try {
|
|
223
|
+
const content = this.reportGenerator.generateReport(reportData, format);
|
|
224
|
+
const filename = `compliance-report.${format}`;
|
|
225
|
+
const filepath = path.join(this.options.outputDir, filename);
|
|
226
|
+
|
|
227
|
+
await fs.promises.writeFile(filepath, content, 'utf8');
|
|
228
|
+
reports[format] = {
|
|
229
|
+
success: true,
|
|
230
|
+
filepath,
|
|
231
|
+
size: content.length
|
|
232
|
+
};
|
|
233
|
+
} catch (error) {
|
|
234
|
+
reports[format] = {
|
|
235
|
+
success: false,
|
|
236
|
+
error: error.message
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return reports;
|
|
448
242
|
}
|
|
449
243
|
|
|
450
|
-
|
|
451
|
-
* Generate report summary
|
|
452
|
-
*/
|
|
453
|
-
generateReportSummary(complianceReport, generatedFiles) {
|
|
244
|
+
getReporterInfo() {
|
|
454
245
|
return {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
totalFiles: complianceReport.summary.totalFiles,
|
|
458
|
-
overallComplianceScore: complianceReport.summary.overallComplianceScore,
|
|
459
|
-
totalIssues: complianceReport.summary.totalIssues,
|
|
460
|
-
generatedFiles: generatedFiles.map(f => ({
|
|
461
|
-
format: f.format,
|
|
462
|
-
fileName: f.fileName,
|
|
463
|
-
size: f.size
|
|
464
|
-
})),
|
|
465
|
-
healthStatus: this.metricsCalculator.getHealthStatus(complianceReport.summary.overallComplianceScore)
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Generate executive summary
|
|
246
|
+
* @param {Object} options - Generation options
|
|
247
|
+
* @returns {Object} - Generation result
|
|
471
248
|
*/
|
|
472
|
-
|
|
473
|
-
const
|
|
474
|
-
const
|
|
249
|
+
async generateMarkdownReport(complianceReport, options) {
|
|
250
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
251
|
+
const filename = `compliance-report-${timestamp}.md`;
|
|
252
|
+
const filePath = path.join(options.outputDir || this.options.outputDir, filename);
|
|
253
|
+
|
|
254
|
+
const markdownContent = this.generateMarkdownContent(complianceReport, options);
|
|
255
|
+
fs.writeFileSync(filePath, markdownContent, 'utf8');
|
|
475
256
|
|
|
476
257
|
return {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
totalIssues: summary.totalIssues
|
|
482
|
-
},
|
|
483
|
-
keyFindings: this.extractKeyFindings(complianceReport),
|
|
484
|
-
priorityActions: this.extractPriorityActions(complianceReport),
|
|
485
|
-
riskAssessment: this.assessOverallRisk(complianceReport),
|
|
486
|
-
recommendations: complianceReport.recommendations.slice(0, 5) // Top 5 recommendations
|
|
258
|
+
format: 'markdown',
|
|
259
|
+
filename,
|
|
260
|
+
filePath,
|
|
261
|
+
size: markdownContent.length
|
|
487
262
|
};
|
|
488
263
|
}
|
|
489
264
|
|
|
490
265
|
/**
|
|
491
|
-
*
|
|
266
|
+
* Generate Markdown content
|
|
267
|
+
* @param {Object} complianceReport - Compliance report data
|
|
268
|
+
* @param {Object} options - Generation options
|
|
269
|
+
* @returns {string} - Markdown content
|
|
492
270
|
*/
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
const summary = complianceReport.summary;
|
|
496
|
-
|
|
497
|
-
if (summary.criticalFiles > 0) {
|
|
498
|
-
findings.push(`${summary.criticalFiles} files have critical compliance violations`);
|
|
499
|
-
}
|
|
271
|
+
generateMarkdownContent(complianceReport, options) {
|
|
272
|
+
let markdown = `# ${complianceReport.title}\n\n`;
|
|
500
273
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
if (summary.overallComplianceScore < 80) {
|
|
506
|
-
findings.push(`Overall compliance score is ${summary.overallComplianceScore.toFixed(1)}%, below target of 90%`);
|
|
507
|
-
}
|
|
274
|
+
markdown += `**Generated:** ${new Date(complianceReport.generatedAt).toLocaleString()}\n`;
|
|
275
|
+
markdown += `**Scope:** ${complianceReport.scope}\n`;
|
|
276
|
+
markdown += `**Path:** ${complianceReport.scopePath}\n\n`;
|
|
508
277
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
findings.push(`Largest file has ${largestFile.lineCount} lines and requires immediate refactoring`);
|
|
278
|
+
if (complianceReport.description) {
|
|
279
|
+
markdown += `## Description\n${complianceReport.description}\n\n`;
|
|
512
280
|
}
|
|
513
281
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
const actions = [];
|
|
522
|
-
|
|
523
|
-
if (complianceReport.summary.criticalFiles > 0) {
|
|
524
|
-
actions.push({
|
|
525
|
-
priority: 1,
|
|
526
|
-
action: 'Address critical violations',
|
|
527
|
-
description: 'Fix all critical compliance issues immediately'
|
|
528
|
-
});
|
|
282
|
+
// Summary section
|
|
283
|
+
if (complianceReport.summary) {
|
|
284
|
+
markdown += `## Executive Summary\n\n`;
|
|
285
|
+
markdown += `- **Overall Compliance:** ${complianceReport.summary.overallComplianceScore.toFixed(1)}%\n`;
|
|
286
|
+
markdown += `- **Status:** ${complianceReport.summary.overallStatus}\n`;
|
|
287
|
+
markdown += `- **Files Analyzed:** ${complianceReport.summary.totalFiles}\n`;
|
|
288
|
+
markdown += `- **Total Issues:** ${complianceReport.summary.totalIssues}\n\n`;
|
|
529
289
|
}
|
|
530
290
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
291
|
+
// Files section
|
|
292
|
+
if (complianceReport.files && complianceReport.files.length > 0) {
|
|
293
|
+
markdown += `## File Details\n\n`;
|
|
294
|
+
markdown += `| File | Lines | Status | Issues | Score |\n`;
|
|
295
|
+
markdown += `|------|-------|--------|--------|-------|\n`;
|
|
296
|
+
|
|
297
|
+
complianceReport.files.forEach(file => {
|
|
298
|
+
const status = file.status || 'unknown';
|
|
299
|
+
const issues = file.issues ? file.issues.length : 0;
|
|
300
|
+
const score = file.complianceScore ? file.complianceScore.toFixed(1) + '%' : 'N/A';
|
|
301
|
+
markdown += `| ${file.filePath} | ${file.lineCount || 0} | ${status} | ${issues} | ${score} |\n`;
|
|
536
302
|
});
|
|
303
|
+
|
|
304
|
+
markdown += '\n';
|
|
537
305
|
}
|
|
538
306
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
307
|
+
// Recommendations section
|
|
308
|
+
if (complianceReport.recommendations && complianceReport.recommendations.length > 0) {
|
|
309
|
+
markdown += `## Recommendations\n\n`;
|
|
310
|
+
|
|
311
|
+
complianceReport.recommendations.forEach((rec, index) => {
|
|
312
|
+
markdown += `### ${index + 1}. ${rec.title} (${rec.priority})\n\n`;
|
|
313
|
+
markdown += `${rec.description}\n\n`;
|
|
314
|
+
markdown += `**Action:** ${rec.action}\n\n`;
|
|
544
315
|
});
|
|
545
316
|
}
|
|
546
317
|
|
|
547
|
-
return
|
|
318
|
+
return markdown;
|
|
548
319
|
}
|
|
549
320
|
|
|
550
321
|
/**
|
|
551
|
-
*
|
|
322
|
+
* Generate report summary
|
|
323
|
+
* @param {Object} complianceReport - Compliance report
|
|
324
|
+
* @param {Array} generatedReports - Generated files
|
|
325
|
+
* @returns {Object} - Summary
|
|
552
326
|
*/
|
|
553
|
-
|
|
554
|
-
const score = complianceReport.summary.overallComplianceScore;
|
|
555
|
-
const criticalFiles = complianceReport.summary.criticalFiles;
|
|
556
|
-
const violationFiles = complianceReport.summary.violationFiles;
|
|
557
|
-
|
|
558
|
-
let riskLevel = 'low';
|
|
559
|
-
let riskFactors = [];
|
|
560
|
-
|
|
561
|
-
if (criticalFiles > 0) {
|
|
562
|
-
riskLevel = 'critical';
|
|
563
|
-
riskFactors.push(`${criticalFiles} critical files`);
|
|
564
|
-
} else if (violationFiles > 0) {
|
|
565
|
-
riskLevel = 'high';
|
|
566
|
-
riskFactors.push(`${violationFiles} files with violations`);
|
|
567
|
-
} else if (score < 80) {
|
|
568
|
-
riskLevel = 'medium';
|
|
569
|
-
riskFactors.push('Low compliance score');
|
|
570
|
-
}
|
|
571
|
-
|
|
327
|
+
generateReportSummary(complianceReport, generatedReports) {
|
|
572
328
|
return {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
329
|
+
title: complianceReport.title,
|
|
330
|
+
generatedAt: complianceReport.generatedAt,
|
|
331
|
+
formats: generatedReports.map(r => r.format),
|
|
332
|
+
files: generatedReports.map(r => r.filename),
|
|
333
|
+
totalSize: generatedReports.reduce((sum, r) => sum + r.size, 0),
|
|
334
|
+
outputDir: this.options.outputDir
|
|
577
335
|
};
|
|
578
336
|
}
|
|
579
337
|
|
|
580
338
|
/**
|
|
581
|
-
*
|
|
339
|
+
* Generate comparison with previous report
|
|
340
|
+
* @param {Object} currentReport - Current compliance report
|
|
341
|
+
* @param {Object} previousReport - Previous compliance report
|
|
342
|
+
* @param {Object} options - Comparison options
|
|
343
|
+
* @returns {Object} - Comparison result
|
|
582
344
|
*/
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
'Maintain current compliance practices',
|
|
602
|
-
'Continue regular monitoring',
|
|
603
|
-
'Focus on prevention'
|
|
604
|
-
]
|
|
605
|
-
};
|
|
606
|
-
|
|
607
|
-
return strategies[riskLevel] || strategies.low;
|
|
345
|
+
async generateComparison(currentReport, previousReport, options = {}) {
|
|
346
|
+
try {
|
|
347
|
+
const comparisonResult = generateComparisonReport(previousReport, currentReport, {
|
|
348
|
+
...this.options,
|
|
349
|
+
...options
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
return {
|
|
353
|
+
success: true,
|
|
354
|
+
comparison: comparisonResult.comparison,
|
|
355
|
+
filePath: comparisonResult.filePath
|
|
356
|
+
};
|
|
357
|
+
} catch (error) {
|
|
358
|
+
return {
|
|
359
|
+
success: false,
|
|
360
|
+
error: error.message
|
|
361
|
+
};
|
|
362
|
+
}
|
|
608
363
|
}
|
|
609
364
|
|
|
610
365
|
/**
|
|
611
366
|
* Create fallback report generator
|
|
367
|
+
* @returns {Object} - Basic report generator
|
|
612
368
|
*/
|
|
613
369
|
createFallbackReportGenerator() {
|
|
614
370
|
return {
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
return JSON.stringify(data, null, 2);
|
|
619
|
-
case 'text':
|
|
620
|
-
return JSON.stringify(data, null, 2);
|
|
621
|
-
default:
|
|
622
|
-
return JSON.stringify(data, null, 2);
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
/**
|
|
629
|
-
* Generate comparison report (comparing two reports)
|
|
630
|
-
*/
|
|
631
|
-
async generateComparisonReport(oldReport, newReport, options = {}) {
|
|
632
|
-
const comparison = {
|
|
633
|
-
metadata: {
|
|
634
|
-
generatedAt: new Date().toISOString(),
|
|
635
|
-
oldReportId: oldReport.id,
|
|
636
|
-
newReportId: newReport.id,
|
|
637
|
-
comparisonPeriod: this.calculatePeriod(oldReport.generatedAt, newReport.generatedAt)
|
|
638
|
-
},
|
|
639
|
-
changes: {
|
|
640
|
-
filesAdded: newReport.summary.totalFiles - oldReport.summary.totalFiles,
|
|
641
|
-
filesRemoved: 0, // Would need more complex logic to calculate
|
|
642
|
-
complianceScoreChange: newReport.summary.overallComplianceScore - oldReport.summary.overallComplianceScore,
|
|
643
|
-
issuesChange: newReport.summary.totalIssues - oldReport.summary.totalFiles
|
|
644
|
-
},
|
|
645
|
-
trends: this.calculateTrends(oldReport, newReport),
|
|
646
|
-
recommendations: this.generateComparisonRecommendations(oldReport, newReport)
|
|
647
|
-
};
|
|
648
|
-
|
|
649
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
650
|
-
const filePath = path.join(options.outputDir || './reports', `comparison-report-${timestamp}.json`);
|
|
651
|
-
|
|
652
|
-
fs.writeFileSync(filePath, JSON.stringify(comparison, null, 2), 'utf8');
|
|
653
|
-
|
|
654
|
-
return {
|
|
655
|
-
comparison,
|
|
656
|
-
filePath
|
|
371
|
+
generateJSON: (data, options) => this.generateJSONReport(data, options),
|
|
372
|
+
generateHTML: (data, options) => this.generateHTMLReport(data, options),
|
|
373
|
+
generateMarkdown: (data, options) => this.generateMarkdownReport(data, options)
|
|
657
374
|
};
|
|
658
375
|
}
|
|
659
376
|
|
|
660
377
|
/**
|
|
661
|
-
*
|
|
662
|
-
|
|
663
|
-
calculatePeriod(oldDate, newDate) {
|
|
664
|
-
const old = new Date(oldDate);
|
|
665
|
-
const now = new Date(newDate);
|
|
666
|
-
const days = Math.floor((now - old) / (1000 * 60 * 60 * 24));
|
|
667
|
-
|
|
668
|
-
return `${days} days`;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Calculate trends between reports
|
|
378
|
+
* Get reporter information
|
|
379
|
+
* @returns {Object} - Reporter info
|
|
673
380
|
*/
|
|
674
|
-
|
|
381
|
+
getInfo() {
|
|
675
382
|
return {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
383
|
+
name: 'Compliance Report Generator',
|
|
384
|
+
version: '1.0.0',
|
|
385
|
+
supportedFormats: ['json', 'html', 'markdown'],
|
|
386
|
+
features: [
|
|
387
|
+
'multi-format output',
|
|
388
|
+
'metrics calculation',
|
|
389
|
+
'recommendation generation',
|
|
390
|
+
'trend analysis',
|
|
391
|
+
'comparison reports',
|
|
392
|
+
'custom styling'
|
|
393
|
+
]
|
|
679
394
|
};
|
|
680
395
|
}
|
|
681
|
-
|
|
682
|
-
/**
|
|
683
|
-
* Generate comparison recommendations
|
|
684
|
-
*/
|
|
685
|
-
generateComparisonRecommendations(oldReport, newReport) {
|
|
686
|
-
const recommendations = [];
|
|
687
|
-
const scoreChange = newReport.summary.overallComplianceScore - oldReport.summary.overallComplianceScore;
|
|
688
|
-
|
|
689
|
-
if (scoreChange < -5) {
|
|
690
|
-
recommendations.push({
|
|
691
|
-
type: 'urgent',
|
|
692
|
-
title: 'Compliance Score Declining',
|
|
693
|
-
description: `Compliance score decreased by ${Math.abs(scoreChange).toFixed(1)}%`,
|
|
694
|
-
action: 'Investigate and address causes of compliance decline'
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
if (scoreChange > 5) {
|
|
699
|
-
recommendations.push({
|
|
700
|
-
type: 'positive',
|
|
701
|
-
title: 'Compliance Improving',
|
|
702
|
-
description: `Compliance score improved by ${scoreChange.toFixed(1)}%`,
|
|
703
|
-
action: 'Continue current compliance practices'
|
|
704
|
-
});
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
return recommendations;
|
|
708
|
-
}
|
|
709
396
|
}
|
|
710
397
|
|
|
711
398
|
module.exports = ComplianceReporter;
|