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.
Files changed (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. 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
+ };