vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642
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/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Continuous Scan Notification System
|
|
3
|
+
*
|
|
4
|
+
* Specialized notification system for continuous compliance scanning,
|
|
5
|
+
* providing intelligent alerts for new file size violations detected during scans.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { AlertSystem, Alert, ALERT_SEVERITY, ALERT_CATEGORIES } = require('./alert-system');
|
|
9
|
+
const EventEmitter = require('events');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Continuous Scan Notification Categories
|
|
13
|
+
*/
|
|
14
|
+
const SCAN_NOTIFICATION_TYPES = {
|
|
15
|
+
NEW_VIOLATIONS_DETECTED: 'new_violations_detected',
|
|
16
|
+
VIOLATIONS_RESOLVED: 'violations_resolved',
|
|
17
|
+
SCAN_COMPLETED: 'scan_completed',
|
|
18
|
+
SCAN_ERROR: 'scan_error',
|
|
19
|
+
THRESHOLD_EXCEEDED: 'threshold_exceeded',
|
|
20
|
+
PROGRESS_UPDATE: 'progress_update'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Continuous Scan Notification System
|
|
25
|
+
*/
|
|
26
|
+
class ContinuousScanNotificationSystem extends EventEmitter {
|
|
27
|
+
constructor(options = {}) {
|
|
28
|
+
super();
|
|
29
|
+
|
|
30
|
+
this.options = {
|
|
31
|
+
// Notification thresholds
|
|
32
|
+
newViolationsThreshold: options.newViolationsThreshold || 1,
|
|
33
|
+
resolvedViolationsThreshold: options.resolvedViolationsThreshold || 5,
|
|
34
|
+
|
|
35
|
+
// Batch notifications
|
|
36
|
+
enableBatchNotifications: options.enableBatchNotifications !== false,
|
|
37
|
+
batchIntervalMs: options.batchIntervalMs || 30000, // 30 seconds
|
|
38
|
+
maxBatchSize: options.maxBatchSize || 10,
|
|
39
|
+
|
|
40
|
+
// Smart notifications
|
|
41
|
+
enableSmartNotifications: options.enableSmartNotifications !== false,
|
|
42
|
+
minSignificantChange: options.minSignificantChange || 3, // minimum change to trigger notification
|
|
43
|
+
|
|
44
|
+
// Notification channels
|
|
45
|
+
channels: options.channels || ['console', 'file'],
|
|
46
|
+
logFile: options.logFile || './logs/continuous-scan-notifications.log',
|
|
47
|
+
|
|
48
|
+
// Alert integration
|
|
49
|
+
enableAlertIntegration: options.enableAlertIntegration !== false,
|
|
50
|
+
alertSystem: options.alertSystem || null,
|
|
51
|
+
|
|
52
|
+
...options
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
this.notificationHistory = [];
|
|
56
|
+
this.batchQueue = [];
|
|
57
|
+
this.batchTimer = null;
|
|
58
|
+
this.lastScanState = null;
|
|
59
|
+
this.notificationStats = {
|
|
60
|
+
totalNotifications: 0,
|
|
61
|
+
notificationsByType: {},
|
|
62
|
+
suppressedNotifications: 0,
|
|
63
|
+
batchedNotifications: 0
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Initialize alert system if provided
|
|
67
|
+
if (this.options.enableAlertIntegration && this.options.alertSystem) {
|
|
68
|
+
this.alertSystem = this.options.alertSystem;
|
|
69
|
+
} else if (this.options.enableAlertIntegration) {
|
|
70
|
+
this.alertSystem = new AlertSystem({
|
|
71
|
+
channels: this.options.channels,
|
|
72
|
+
enableNotifications: true
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Setup batch processing
|
|
77
|
+
if (this.options.enableBatchNotifications) {
|
|
78
|
+
this.setupBatchProcessing();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Process continuous scan results and generate notifications
|
|
84
|
+
*/
|
|
85
|
+
processScanResults(scanResults, scanStatus) {
|
|
86
|
+
const notifications = [];
|
|
87
|
+
|
|
88
|
+
// Compare with previous scan state
|
|
89
|
+
const changes = this.detectChanges(scanResults, scanStatus);
|
|
90
|
+
|
|
91
|
+
// Generate notifications based on changes
|
|
92
|
+
if (changes.newViolations.length > 0) {
|
|
93
|
+
notifications.push(...this.createNewViolationNotifications(changes.newViolations));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (changes.resolvedViolations.length > 0) {
|
|
97
|
+
notifications.push(...this.createResolvedViolationNotifications(changes.resolvedViolations));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (changes.thresholdExceeded) {
|
|
101
|
+
notifications.push(this.createThresholdExceededNotification(changes.thresholdExceeded));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (changes.scanError) {
|
|
105
|
+
notifications.push(this.createScanErrorNotification(changes.scanError));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (changes.progressUpdate) {
|
|
109
|
+
notifications.push(this.createProgressNotification(changes.progressUpdate));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Process notifications
|
|
113
|
+
for (const notification of notifications) {
|
|
114
|
+
this.processNotification(notification);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Update scan state
|
|
118
|
+
this.lastScanState = {
|
|
119
|
+
timestamp: new Date().toISOString(),
|
|
120
|
+
scanResults,
|
|
121
|
+
scanStatus,
|
|
122
|
+
changes
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
return notifications;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Detect changes between current and previous scan results
|
|
130
|
+
*/
|
|
131
|
+
detectChanges(scanResults, scanStatus) {
|
|
132
|
+
const changes = {
|
|
133
|
+
newViolations: [],
|
|
134
|
+
resolvedViolations: [],
|
|
135
|
+
thresholdExceeded: null,
|
|
136
|
+
scanError: scanStatus.error || null,
|
|
137
|
+
progressUpdate: null
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
if (!this.lastScanState) {
|
|
141
|
+
// First scan - all violations are "new"
|
|
142
|
+
changes.newViolations = scanResults.violations || [];
|
|
143
|
+
changes.progressUpdate = {
|
|
144
|
+
type: 'initial_scan',
|
|
145
|
+
totalFiles: scanResults.summary?.totalFiles || 0,
|
|
146
|
+
violationCount: scanResults.summary?.nonCompliantFiles || 0
|
|
147
|
+
};
|
|
148
|
+
return changes;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const previousViolations = this.lastScanState.scanResults.violations || [];
|
|
152
|
+
const currentViolations = scanResults.violations || [];
|
|
153
|
+
|
|
154
|
+
// Find new violations
|
|
155
|
+
const previousFilePaths = new Set(previousViolations.map(v => v.filePath));
|
|
156
|
+
changes.newViolations = currentViolations.filter(v => !previousFilePaths.has(v.filePath));
|
|
157
|
+
|
|
158
|
+
// Find resolved violations
|
|
159
|
+
const currentFilePaths = new Set(currentViolations.map(v => v.filePath));
|
|
160
|
+
changes.resolvedViolations = previousViolations.filter(v => !currentFilePaths.has(v.filePath));
|
|
161
|
+
|
|
162
|
+
// Check for threshold exceeded
|
|
163
|
+
const violationCount = scanResults.summary?.nonCompliantFiles || 0;
|
|
164
|
+
if (violationCount >= this.options.newViolationsThreshold) {
|
|
165
|
+
changes.thresholdExceeded = {
|
|
166
|
+
currentCount: violationCount,
|
|
167
|
+
threshold: this.options.newViolationsThreshold,
|
|
168
|
+
previousCount: this.lastScanState.scanResults.summary?.nonCompliantFiles || 0
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Progress update
|
|
173
|
+
const previousCount = this.lastScanState.scanResults.summary?.nonCompliantFiles || 0;
|
|
174
|
+
if (violationCount !== previousCount) {
|
|
175
|
+
changes.progressUpdate = {
|
|
176
|
+
type: 'count_change',
|
|
177
|
+
previousCount,
|
|
178
|
+
currentCount: violationCount,
|
|
179
|
+
change: violationCount - previousCount
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return changes;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Create notifications for new violations
|
|
188
|
+
*/
|
|
189
|
+
createNewViolationNotifications(newViolations) {
|
|
190
|
+
const notifications = [];
|
|
191
|
+
|
|
192
|
+
if (newViolations.length === 0) return notifications;
|
|
193
|
+
|
|
194
|
+
// Smart notification: only notify if significant change
|
|
195
|
+
if (this.options.enableSmartNotifications &&
|
|
196
|
+
newViolations.length < this.options.minSignificantChange) {
|
|
197
|
+
this.notificationStats.suppressedNotifications++;
|
|
198
|
+
return notifications;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (this.options.enableBatchNotifications && newViolations.length > this.options.maxBatchSize) {
|
|
202
|
+
// Create batch notification
|
|
203
|
+
notifications.push({
|
|
204
|
+
type: SCAN_NOTIFICATION_TYPES.NEW_VIOLATIONS_DETECTED,
|
|
205
|
+
severity: newViolations.length > 10 ? ALERT_SEVERITY.ERROR : ALERT_SEVERITY.WARNING,
|
|
206
|
+
title: `${newViolations.length} New File Size Violations Detected`,
|
|
207
|
+
message: `Continuous scan detected ${newViolations.length} files exceeding the 555-line limit`,
|
|
208
|
+
data: {
|
|
209
|
+
violationCount: newViolations.length,
|
|
210
|
+
violations: newViolations.slice(0, 5), // Include first 5 for details
|
|
211
|
+
totalViolations: newViolations.length,
|
|
212
|
+
timestamp: new Date().toISOString()
|
|
213
|
+
},
|
|
214
|
+
actions: [
|
|
215
|
+
'Review violation details in compliance dashboard',
|
|
216
|
+
'Run refactoring tools on largest violations',
|
|
217
|
+
'Update task list with new violations'
|
|
218
|
+
]
|
|
219
|
+
});
|
|
220
|
+
} else {
|
|
221
|
+
// Create individual notifications
|
|
222
|
+
for (const violation of newViolations) {
|
|
223
|
+
notifications.push({
|
|
224
|
+
type: SCAN_NOTIFICATION_TYPES.NEW_VIOLATIONS_DETECTED,
|
|
225
|
+
severity: this.getViolationSeverity(violation),
|
|
226
|
+
title: `New File Size Violation: ${violation.filePath}`,
|
|
227
|
+
message: `${violation.filePath} has ${violation.lineCount} lines (${this.getExcessLines(violation)} over limit)`,
|
|
228
|
+
data: {
|
|
229
|
+
violation,
|
|
230
|
+
timestamp: new Date().toISOString()
|
|
231
|
+
},
|
|
232
|
+
actions: [
|
|
233
|
+
'Refactor this file',
|
|
234
|
+
'Add to refactoring task list',
|
|
235
|
+
'View detailed analysis'
|
|
236
|
+
]
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return notifications;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Create notifications for resolved violations
|
|
246
|
+
*/
|
|
247
|
+
createResolvedViolationNotifications(resolvedViolations) {
|
|
248
|
+
const notifications = [];
|
|
249
|
+
|
|
250
|
+
if (resolvedViolations.length === 0) return notifications;
|
|
251
|
+
|
|
252
|
+
// Only notify if significant number resolved
|
|
253
|
+
if (resolvedViolations.length >= this.options.resolvedViolationsThreshold) {
|
|
254
|
+
notifications.push({
|
|
255
|
+
type: SCAN_NOTIFICATION_TYPES.VIOLATIONS_RESOLVED,
|
|
256
|
+
severity: ALERT_SEVERITY.INFO,
|
|
257
|
+
title: `${resolvedViolations.length} File Size Violations Resolved`,
|
|
258
|
+
message: `Great progress! ${resolvedViolations.length} files are now compliant with the 555-line limit`,
|
|
259
|
+
data: {
|
|
260
|
+
resolvedCount: resolvedViolations.length,
|
|
261
|
+
resolvedFiles: resolvedViolations.map(v => v.filePath),
|
|
262
|
+
timestamp: new Date().toISOString()
|
|
263
|
+
},
|
|
264
|
+
actions: [
|
|
265
|
+
'Review compliance progress',
|
|
266
|
+
'Update project status',
|
|
267
|
+
'Continue with remaining violations'
|
|
268
|
+
]
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return notifications;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Create threshold exceeded notification
|
|
277
|
+
*/
|
|
278
|
+
createThresholdExceededNotification(thresholdData) {
|
|
279
|
+
return {
|
|
280
|
+
type: SCAN_NOTIFICATION_TYPES.THRESHOLD_EXCEEDED,
|
|
281
|
+
severity: thresholdData.currentCount > thresholdData.threshold * 2 ? ALERT_SEVERITY.CRITICAL : ALERT_SEVERITY.ERROR,
|
|
282
|
+
title: `File Size Violation Threshold Exceeded`,
|
|
283
|
+
message: `${thresholdData.currentCount} files exceed the 555-line limit (threshold: ${thresholdData.threshold})`,
|
|
284
|
+
data: {
|
|
285
|
+
...thresholdData,
|
|
286
|
+
timestamp: new Date().toISOString()
|
|
287
|
+
},
|
|
288
|
+
actions: [
|
|
289
|
+
'Immediate refactoring required',
|
|
290
|
+
'Escalate to team lead',
|
|
291
|
+
'Schedule refactoring sprint'
|
|
292
|
+
]
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Create scan error notification
|
|
298
|
+
*/
|
|
299
|
+
createScanErrorNotification(error) {
|
|
300
|
+
return {
|
|
301
|
+
type: SCAN_NOTIFICATION_TYPES.SCAN_ERROR,
|
|
302
|
+
severity: ALERT_SEVERITY.ERROR,
|
|
303
|
+
title: 'Continuous Scan Error',
|
|
304
|
+
message: `Error during continuous scan: ${error.message || error}`,
|
|
305
|
+
data: {
|
|
306
|
+
error,
|
|
307
|
+
timestamp: new Date().toISOString()
|
|
308
|
+
},
|
|
309
|
+
actions: [
|
|
310
|
+
'Check scan configuration',
|
|
311
|
+
'Review error logs',
|
|
312
|
+
'Restart continuous scanner'
|
|
313
|
+
]
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Create progress notification
|
|
319
|
+
*/
|
|
320
|
+
createProgressNotification(progressData) {
|
|
321
|
+
const severity = progressData.type === 'initial_scan' ? ALERT_SEVERITY.INFO : ALERT_SEVERITY.INFO;
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
type: SCAN_NOTIFICATION_TYPES.PROGRESS_UPDATE,
|
|
325
|
+
severity,
|
|
326
|
+
title: progressData.type === 'initial_scan' ? 'Initial Scan Completed' : 'Compliance Progress Update',
|
|
327
|
+
message: this.formatProgressMessage(progressData),
|
|
328
|
+
data: {
|
|
329
|
+
...progressData,
|
|
330
|
+
timestamp: new Date().toISOString()
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Process a notification
|
|
337
|
+
*/
|
|
338
|
+
processNotification(notification) {
|
|
339
|
+
// Add to history
|
|
340
|
+
this.notificationHistory.push(notification);
|
|
341
|
+
this.notificationStats.totalNotifications++;
|
|
342
|
+
this.notificationStats.notificationsByType[notification.type] =
|
|
343
|
+
(this.notificationStats.notificationsByType[notification.type] || 0) + 1;
|
|
344
|
+
|
|
345
|
+
// Handle batching
|
|
346
|
+
if (this.options.enableBatchNotifications) {
|
|
347
|
+
this.addToBatch(notification);
|
|
348
|
+
} else {
|
|
349
|
+
this.sendNotification(notification);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Emit event
|
|
353
|
+
this.emit('notification', notification);
|
|
354
|
+
this.emit(`notification:${notification.type}`, notification);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Add notification to batch
|
|
359
|
+
*/
|
|
360
|
+
addToBatch(notification) {
|
|
361
|
+
this.batchQueue.push(notification);
|
|
362
|
+
this.notificationStats.batchedNotifications++;
|
|
363
|
+
|
|
364
|
+
// Send immediately if high severity or batch is full
|
|
365
|
+
if (notification.severity === ALERT_SEVERITY.CRITICAL ||
|
|
366
|
+
this.batchQueue.length >= this.options.maxBatchSize) {
|
|
367
|
+
this.sendBatch();
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Setup batch processing
|
|
373
|
+
*/
|
|
374
|
+
setupBatchProcessing() {
|
|
375
|
+
this.batchTimer = setInterval(() => {
|
|
376
|
+
if (this.batchQueue.length > 0) {
|
|
377
|
+
this.sendBatch();
|
|
378
|
+
}
|
|
379
|
+
}, this.options.batchIntervalMs);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Send batch notifications
|
|
384
|
+
*/
|
|
385
|
+
sendBatch() {
|
|
386
|
+
if (this.batchQueue.length === 0) return;
|
|
387
|
+
|
|
388
|
+
const batch = [...this.batchQueue];
|
|
389
|
+
this.batchQueue = [];
|
|
390
|
+
|
|
391
|
+
// Create batch summary notification
|
|
392
|
+
const batchNotification = {
|
|
393
|
+
type: 'batch_summary',
|
|
394
|
+
severity: this.getBatchSeverity(batch),
|
|
395
|
+
title: `Scan Notification Summary (${batch.length} items)`,
|
|
396
|
+
message: this.formatBatchSummary(batch),
|
|
397
|
+
data: {
|
|
398
|
+
batchSize: batch.length,
|
|
399
|
+
notifications: batch,
|
|
400
|
+
timestamp: new Date().toISOString()
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
this.sendNotification(batchNotification);
|
|
405
|
+
|
|
406
|
+
// Also send individual notifications to alert system
|
|
407
|
+
if (this.alertSystem) {
|
|
408
|
+
for (const notification of batch) {
|
|
409
|
+
this.sendToAlertSystem(notification);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Send notification
|
|
416
|
+
*/
|
|
417
|
+
sendNotification(notification) {
|
|
418
|
+
for (const channel of this.options.channels) {
|
|
419
|
+
try {
|
|
420
|
+
switch (channel) {
|
|
421
|
+
case 'console':
|
|
422
|
+
this.sendConsoleNotification(notification);
|
|
423
|
+
break;
|
|
424
|
+
case 'file':
|
|
425
|
+
this.sendFileNotification(notification);
|
|
426
|
+
break;
|
|
427
|
+
case 'alert':
|
|
428
|
+
if (this.alertSystem) {
|
|
429
|
+
this.sendToAlertSystem(notification);
|
|
430
|
+
}
|
|
431
|
+
break;
|
|
432
|
+
default:
|
|
433
|
+
console.warn(`Unknown notification channel: ${channel}`);
|
|
434
|
+
}
|
|
435
|
+
} catch (error) {
|
|
436
|
+
console.error(`Failed to send ${channel} notification:`, error);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Send console notification
|
|
443
|
+
*/
|
|
444
|
+
sendConsoleNotification(notification) {
|
|
445
|
+
const colors = {
|
|
446
|
+
info: '\x1b[36m',
|
|
447
|
+
warning: '\x1b[33m',
|
|
448
|
+
error: '\x1b[31m',
|
|
449
|
+
critical: '\x1b[35m',
|
|
450
|
+
reset: '\x1b[0m',
|
|
451
|
+
bold: '\x1b[1m'
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const color = colors[notification.severity] || colors.info;
|
|
455
|
+
const icon = this.getNotificationIcon(notification.type);
|
|
456
|
+
|
|
457
|
+
console.log(`${color}${colors.bold}[SCAN NOTIFY] ${icon} ${notification.title}${colors.reset}`);
|
|
458
|
+
console.log(`${color} ${notification.message}${colors.reset}`);
|
|
459
|
+
console.log(` Time: ${new Date(notification.data.timestamp).toLocaleString()}`);
|
|
460
|
+
|
|
461
|
+
if (notification.data.violationCount) {
|
|
462
|
+
console.log(` Violations: ${notification.data.violationCount}`);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (notification.actions && notification.actions.length > 0) {
|
|
466
|
+
console.log(` Actions: ${notification.actions.slice(0, 2).join(', ')}`);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
console.log('');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Send file notification
|
|
474
|
+
*/
|
|
475
|
+
sendFileNotification(notification) {
|
|
476
|
+
const fs = require('fs');
|
|
477
|
+
const path = require('path');
|
|
478
|
+
|
|
479
|
+
// Ensure log directory exists
|
|
480
|
+
const logDir = path.dirname(this.options.logFile);
|
|
481
|
+
if (!fs.existsSync(logDir)) {
|
|
482
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const logEntry = {
|
|
486
|
+
timestamp: notification.data.timestamp,
|
|
487
|
+
type: notification.type,
|
|
488
|
+
severity: notification.severity,
|
|
489
|
+
title: notification.title,
|
|
490
|
+
message: notification.message,
|
|
491
|
+
data: notification.data
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
const logLine = JSON.stringify(logEntry) + '\n';
|
|
495
|
+
fs.appendFileSync(this.options.logFile, logLine, 'utf8');
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Send to alert system
|
|
500
|
+
*/
|
|
501
|
+
sendToAlertSystem(notification) {
|
|
502
|
+
if (!this.alertSystem) return;
|
|
503
|
+
|
|
504
|
+
const alert = new Alert({
|
|
505
|
+
category: ALERT_CATEGORIES.FILE_SIZE,
|
|
506
|
+
severity: notification.severity,
|
|
507
|
+
title: notification.title,
|
|
508
|
+
message: notification.message,
|
|
509
|
+
description: notification.data.violations ?
|
|
510
|
+
`Details: ${notification.data.violations.length} violations detected` :
|
|
511
|
+
notification.message,
|
|
512
|
+
filePath: notification.data.violation?.filePath || 'Multiple files',
|
|
513
|
+
metadata: {
|
|
514
|
+
timestamp: notification.data.timestamp,
|
|
515
|
+
source: 'continuous-scan-notifier',
|
|
516
|
+
notificationType: notification.type
|
|
517
|
+
},
|
|
518
|
+
context: {
|
|
519
|
+
...notification.data,
|
|
520
|
+
notificationActions: notification.actions
|
|
521
|
+
},
|
|
522
|
+
actions: notification.actions || []
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
this.alertSystem.processAlert(alert);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Get violation severity based on line count
|
|
530
|
+
*/
|
|
531
|
+
getViolationSeverity(violation) {
|
|
532
|
+
const lineCount = violation.lineCount || 0;
|
|
533
|
+
|
|
534
|
+
if (lineCount > 1000) return ALERT_SEVERITY.CRITICAL;
|
|
535
|
+
if (lineCount > 800) return ALERT_SEVERITY.ERROR;
|
|
536
|
+
if (lineCount > 555) return ALERT_SEVERITY.WARNING;
|
|
537
|
+
return ALERT_SEVERITY.INFO;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Get excess lines for violation
|
|
542
|
+
*/
|
|
543
|
+
getExcessLines(violation) {
|
|
544
|
+
const lineCount = violation.lineCount || 0;
|
|
545
|
+
const excessLines = lineCount - 555;
|
|
546
|
+
return excessLines > 0 ? `${excessLines} lines` : '0 lines';
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Get notification icon
|
|
551
|
+
*/
|
|
552
|
+
getNotificationIcon(type) {
|
|
553
|
+
const icons = {
|
|
554
|
+
[SCAN_NOTIFICATION_TYPES.NEW_VIOLATIONS_DETECTED]: '🚨',
|
|
555
|
+
[SCAN_NOTIFICATION_TYPES.VIOLATIONS_RESOLVED]: '✅',
|
|
556
|
+
[SCAN_NOTIFICATION_TYPES.SCAN_COMPLETED]: '🔍',
|
|
557
|
+
[SCAN_NOTIFICATION_TYPES.SCAN_ERROR]: '❌',
|
|
558
|
+
[SCAN_NOTIFICATION_TYPES.THRESHOLD_EXCEEDED]: '⚠️',
|
|
559
|
+
[SCAN_NOTIFICATION_TYPES.PROGRESS_UPDATE]: '📊',
|
|
560
|
+
'batch_summary': '📋'
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
return icons[type] || '📢';
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Get batch severity
|
|
568
|
+
*/
|
|
569
|
+
getBatchSeverity(batch) {
|
|
570
|
+
if (batch.some(n => n.severity === ALERT_SEVERITY.CRITICAL)) return ALERT_SEVERITY.CRITICAL;
|
|
571
|
+
if (batch.some(n => n.severity === ALERT_SEVERITY.ERROR)) return ALERT_SEVERITY.ERROR;
|
|
572
|
+
if (batch.some(n => n.severity === ALERT_SEVERITY.WARNING)) return ALERT_SEVERITY.WARNING;
|
|
573
|
+
return ALERT_SEVERITY.INFO;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Format batch summary
|
|
578
|
+
*/
|
|
579
|
+
formatBatchSummary(batch) {
|
|
580
|
+
const typeCounts = {};
|
|
581
|
+
for (const notification of batch) {
|
|
582
|
+
typeCounts[notification.type] = (typeCounts[notification.type] || 0) + 1;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
let summary = `Batch contains ${batch.length} notifications: `;
|
|
586
|
+
const items = [];
|
|
587
|
+
|
|
588
|
+
for (const [type, count] of Object.entries(typeCounts)) {
|
|
589
|
+
items.push(`${count} ${type}`);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
summary += items.join(', ');
|
|
593
|
+
return summary;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Format progress message
|
|
598
|
+
*/
|
|
599
|
+
formatProgressMessage(progressData) {
|
|
600
|
+
switch (progressData.type) {
|
|
601
|
+
case 'initial_scan':
|
|
602
|
+
return `Initial scan completed: ${progressData.totalFiles} files scanned, ${progressData.violationCount} violations found`;
|
|
603
|
+
case 'count_change':
|
|
604
|
+
const direction = progressData.change > 0 ? 'increased' : 'decreased';
|
|
605
|
+
return `File size violations ${direction} by ${Math.abs(progressData.change)} (now ${progressData.currentCount})`;
|
|
606
|
+
default:
|
|
607
|
+
return `Scan progress updated`;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Get notification statistics
|
|
613
|
+
*/
|
|
614
|
+
getStats() {
|
|
615
|
+
return {
|
|
616
|
+
...this.notificationStats,
|
|
617
|
+
queueSize: this.batchQueue.length,
|
|
618
|
+
lastScanState: this.lastScanState ? {
|
|
619
|
+
timestamp: this.lastScanState.timestamp,
|
|
620
|
+
violationCount: this.lastScanState.scanResults.summary?.nonCompliantFiles || 0
|
|
621
|
+
} : null
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Clear notification history
|
|
627
|
+
*/
|
|
628
|
+
clearHistory() {
|
|
629
|
+
this.notificationHistory = [];
|
|
630
|
+
this.batchQueue = [];
|
|
631
|
+
this.notificationStats = {
|
|
632
|
+
totalNotifications: 0,
|
|
633
|
+
notificationsByType: {},
|
|
634
|
+
suppressedNotifications: 0,
|
|
635
|
+
batchedNotifications: 0
|
|
636
|
+
};
|
|
637
|
+
this.emit('historyCleared');
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Shutdown notification system
|
|
642
|
+
*/
|
|
643
|
+
shutdown() {
|
|
644
|
+
if (this.batchTimer) {
|
|
645
|
+
clearInterval(this.batchTimer);
|
|
646
|
+
this.batchTimer = null;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Send any remaining batch notifications
|
|
650
|
+
if (this.batchQueue.length > 0) {
|
|
651
|
+
this.sendBatch();
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
this.emit('shutdown');
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
module.exports = {
|
|
659
|
+
ContinuousScanNotificationSystem,
|
|
660
|
+
SCAN_NOTIFICATION_TYPES
|
|
661
|
+
};
|