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,437 @@
1
+ /**
2
+ * Notification System for Continuous Compliance Monitoring
3
+ *
4
+ * Provides intelligent notification management for new violations detected
5
+ * during continuous scanning, with configurable channels and escalation policies.
6
+ */
7
+
8
+ const EventEmitter = require('events');
9
+ const { AlertSystem } = require('./alert-system');
10
+
11
+ /**
12
+ * Notification channels
13
+ */
14
+ const NOTIFICATION_CHANNELS = {
15
+ CONSOLE: 'console',
16
+ FILE: 'file',
17
+ DESKTOP: 'desktop',
18
+ EMAIL: 'email',
19
+ SLACK: 'slack'
20
+ };
21
+
22
+ /**
23
+ * Notification priorities
24
+ */
25
+ const NOTIFICATION_PRIORITY = {
26
+ LOW: 'low',
27
+ MEDIUM: 'medium',
28
+ HIGH: 'high',
29
+ CRITICAL: 'critical'
30
+ };
31
+
32
+ /**
33
+ * Notification Manager Class
34
+ */
35
+ class NotificationManager extends EventEmitter {
36
+ constructor(options = {}) {
37
+ super();
38
+
39
+ this.options = {
40
+ // Enable/disable notifications
41
+ enabled: options.enabled !== false,
42
+
43
+ // Notification channels to use
44
+ channels: options.channels || [NOTIFICATION_CHANNELS.CONSOLE, NOTIFICATION_CHANNELS.FILE],
45
+
46
+ // Notification thresholds
47
+ violationThreshold: options.violationThreshold || 1,
48
+ criticalViolationThreshold: options.criticalViolationThreshold || 10,
49
+
50
+ // Rate limiting
51
+ enableRateLimit: options.enableRateLimit !== false,
52
+ rateLimitMs: options.rateLimitMs || 300000, // 5 minutes
53
+
54
+ // Desktop notification settings
55
+ enableDesktop: options.enableDesktop !== false,
56
+ desktopTitle: options.desktopTitle || 'Vibe Coding Machine',
57
+
58
+ // File logging
59
+ logFile: options.logFile || './logs/notifications.log',
60
+
61
+ ...options
62
+ };
63
+
64
+ // Initialize alert system for integration
65
+ this.alertSystem = new AlertSystem({
66
+ channels: this.options.channels,
67
+ enableNotifications: this.options.enabled
68
+ });
69
+
70
+ // Rate limiting tracking
71
+ this.lastNotificationTime = new Map();
72
+
73
+ // Statistics
74
+ this.stats = {
75
+ totalNotifications: 0,
76
+ notificationsByChannel: {},
77
+ notificationsByPriority: {},
78
+ violationsDetected: 0,
79
+ lastNotification: null
80
+ };
81
+
82
+ this._initializeStats();
83
+ }
84
+
85
+ /**
86
+ * Initialize statistics tracking
87
+ */
88
+ _initializeStats() {
89
+ for (const channel of Object.values(NOTIFICATION_CHANNELS)) {
90
+ this.stats.notificationsByChannel[channel] = 0;
91
+ }
92
+ for (const priority of Object.values(NOTIFICATION_PRIORITY)) {
93
+ this.stats.notificationsByPriority[priority] = 0;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Handle new violations from continuous scanner
99
+ */
100
+ async handleNewViolations(violations, scanInfo = {}) {
101
+ if (!this.options.enabled || !violations || violations.length === 0) {
102
+ return;
103
+ }
104
+
105
+ this.stats.violationsDetected += violations.length;
106
+
107
+ // Check rate limiting
108
+ if (this.options.enableRateLimit && this._isRateLimited('violations')) {
109
+ console.log('Notification rate limited for violations');
110
+ return;
111
+ }
112
+
113
+ // Determine notification priority
114
+ const priority = this._determinePriority(violations);
115
+
116
+ // Create notification
117
+ const notification = this._createViolationNotification(violations, scanInfo, priority);
118
+
119
+ // Send notification through all configured channels
120
+ await this._sendNotification(notification);
121
+
122
+ // Update statistics
123
+ this._updateStats(notification);
124
+
125
+ // Emit event for external handlers
126
+ this.emit('violationNotification', notification);
127
+ }
128
+
129
+ /**
130
+ * Handle scanner status changes
131
+ */
132
+ async handleScannerStatus(status, statusInfo = {}) {
133
+ if (!this.options.enabled) {
134
+ return;
135
+ }
136
+
137
+ const notification = this._createStatusNotification(status, statusInfo);
138
+
139
+ if (notification) {
140
+ await this._sendNotification(notification);
141
+ this._updateStats(notification);
142
+ this.emit('statusNotification', notification);
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Determine notification priority based on violations
148
+ */
149
+ _determinePriority(violations) {
150
+ if (violations.length >= this.options.criticalViolationThreshold) {
151
+ return NOTIFICATION_PRIORITY.CRITICAL;
152
+ } else if (violations.length >= 5) {
153
+ return NOTIFICATION_PRIORITY.HIGH;
154
+ } else if (violations.length >= this.options.violationThreshold) {
155
+ return NOTIFICATION_PRIORITY.MEDIUM;
156
+ }
157
+ return NOTIFICATION_PRIORITY.LOW;
158
+ }
159
+
160
+ /**
161
+ * Create violation notification
162
+ */
163
+ _createViolationNotification(violations, scanInfo, priority) {
164
+ const violationCount = violations.length;
165
+ const totalExcessLines = violations.reduce((sum, v) => sum + (v.lineCount - 555), 0);
166
+
167
+ return {
168
+ id: `violation-${Date.now()}`,
169
+ type: 'violation',
170
+ priority,
171
+ title: `${violationCount} File Size Violations Detected`,
172
+ message: `${violationCount} files exceed the 555-line limit (${totalExcessLines} excess lines total)`,
173
+ description: this._generateViolationDescription(violations),
174
+ metadata: {
175
+ timestamp: new Date().toISOString(),
176
+ source: 'continuous-scanner',
177
+ scanInfo,
178
+ violationCount,
179
+ totalExcessLines,
180
+ violations: violations.map(v => ({
181
+ filePath: v.filePath,
182
+ lineCount: v.lineCount,
183
+ excessLines: v.lineCount - 555,
184
+ severity: v.lineCount > 1000 ? 'critical' : 'warning'
185
+ }))
186
+ }
187
+ };
188
+ }
189
+
190
+ /**
191
+ * Generate detailed violation description
192
+ */
193
+ _generateViolationDescription(violations) {
194
+ const topViolations = violations
195
+ .sort((a, b) => b.lineCount - a.lineCount)
196
+ .slice(0, 5);
197
+
198
+ let description = `Top violations:\n`;
199
+ topViolations.forEach((v, index) => {
200
+ description += `${index + 1}. ${v.filePath} (${v.lineCount} lines, ${v.lineCount - 555} over)\n`;
201
+ });
202
+
203
+ if (violations.length > 5) {
204
+ description += `... and ${violations.length - 5} more files`;
205
+ }
206
+
207
+ return description;
208
+ }
209
+
210
+ /**
211
+ * Create status notification
212
+ */
213
+ _createStatusNotification(status, statusInfo) {
214
+ if (status === 'error') {
215
+ return {
216
+ id: `status-error-${Date.now()}`,
217
+ type: 'status',
218
+ priority: NOTIFICATION_PRIORITY.HIGH,
219
+ title: 'Continuous Scanner Error',
220
+ message: 'Continuous scanner encountered an error',
221
+ description: statusInfo.error || 'Unknown error occurred',
222
+ metadata: {
223
+ timestamp: new Date().toISOString(),
224
+ source: 'continuous-scanner',
225
+ status,
226
+ statusInfo
227
+ }
228
+ };
229
+ }
230
+
231
+ return null;
232
+ }
233
+
234
+ /**
235
+ * Send notification through configured channels
236
+ */
237
+ async _sendNotification(notification) {
238
+ const results = [];
239
+
240
+ for (const channel of this.options.channels) {
241
+ try {
242
+ const result = await this._sendToChannel(channel, notification);
243
+ results.push({ channel, success: true, result });
244
+ } catch (error) {
245
+ console.error(`Failed to send ${channel} notification:`, error);
246
+ results.push({ channel, success: false, error });
247
+ }
248
+ }
249
+
250
+ return results;
251
+ }
252
+
253
+ /**
254
+ * Send notification to specific channel
255
+ */
256
+ async _sendToChannel(channel, notification) {
257
+ switch (channel) {
258
+ case NOTIFICATION_CHANNELS.CONSOLE:
259
+ return this._sendConsoleNotification(notification);
260
+ case NOTIFICATION_CHANNELS.FILE:
261
+ return this._sendFileNotification(notification);
262
+ case NOTIFICATION_CHANNELS.DESKTOP:
263
+ return this._sendDesktopNotification(notification);
264
+ case NOTIFICATION_CHANNELS.EMAIL:
265
+ return this._sendEmailNotification(notification);
266
+ case NOTIFICATION_CHANNELS.SLACK:
267
+ return this._sendSlackNotification(notification);
268
+ default:
269
+ throw new Error(`Unknown notification channel: ${channel}`);
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Send console notification
275
+ */
276
+ _sendConsoleNotification(notification) {
277
+ const colors = {
278
+ low: '\x1b[36m', // Cyan
279
+ medium: '\x1b[33m', // Yellow
280
+ high: '\x1b[31m', // Red
281
+ critical: '\x1b[35m' // Magenta
282
+ };
283
+
284
+ const reset = '\x1b[0m';
285
+ const color = colors[notification.priority] || '';
286
+
287
+ console.log(`${color}🔔 ${notification.title}${reset}`);
288
+ console.log(`${notification.message}`);
289
+ if (notification.description) {
290
+ console.log(`${notification.description}`);
291
+ }
292
+ console.log('');
293
+ }
294
+
295
+ /**
296
+ * Send file notification
297
+ */
298
+ _sendFileNotification(notification) {
299
+ const fs = require('fs');
300
+ const path = require('path');
301
+
302
+ // Ensure log directory exists
303
+ const logDir = path.dirname(this.options.logFile);
304
+ if (!fs.existsSync(logDir)) {
305
+ fs.mkdirSync(logDir, { recursive: true });
306
+ }
307
+
308
+ const logEntry = {
309
+ timestamp: notification.metadata.timestamp,
310
+ id: notification.id,
311
+ type: notification.type,
312
+ priority: notification.priority,
313
+ title: notification.title,
314
+ message: notification.message,
315
+ metadata: notification.metadata
316
+ };
317
+
318
+ fs.appendFileSync(this.options.logFile, JSON.stringify(logEntry) + '\n');
319
+ }
320
+
321
+ /**
322
+ * Send desktop notification
323
+ */
324
+ _sendDesktopNotification(notification) {
325
+ if (!this.options.enableDesktop) {
326
+ return;
327
+ }
328
+
329
+ try {
330
+ // Try to use system notification library
331
+ const notifier = require('node-notifier');
332
+
333
+ notifier.notify({
334
+ title: this.options.desktopTitle,
335
+ subtitle: notification.title,
336
+ message: notification.message,
337
+ priority: notification.priority === 'critical' ? 'critical' : 'normal',
338
+ sound: notification.priority === 'critical' ? 'Bottle' : 'Glass',
339
+ wait: notification.priority === 'critical'
340
+ });
341
+ } catch (error) {
342
+ console.log('Desktop notifications not available:', error.message);
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Send email notification (placeholder)
348
+ */
349
+ _sendEmailNotification(notification) {
350
+ // Placeholder for email implementation
351
+ console.log(`📧 Email notification would be sent for: ${notification.title}`);
352
+ }
353
+
354
+ /**
355
+ * Send Slack notification (placeholder)
356
+ */
357
+ _sendSlackNotification(notification) {
358
+ // Placeholder for Slack implementation
359
+ console.log(`💬 Slack notification would be sent for: ${notification.title}`);
360
+ }
361
+
362
+ /**
363
+ * Check if notification is rate limited
364
+ */
365
+ _isRateLimitKey(key) {
366
+ const now = Date.now();
367
+ const lastTime = this.lastNotificationTime.get(key);
368
+
369
+ if (lastTime && (now - lastTime) < this.options.rateLimitMs) {
370
+ return true;
371
+ }
372
+
373
+ this.lastNotificationTime.set(key, now);
374
+ return false;
375
+ }
376
+
377
+ /**
378
+ * Update notification statistics
379
+ */
380
+ _updateStats(notification) {
381
+ this.stats.totalNotifications++;
382
+ this.stats.lastNotification = new Date().toISOString();
383
+
384
+ // Update channel stats (would be tracked in _sendToChannel)
385
+ // Update priority stats
386
+ this.stats.notificationsByPriority[notification.priority] =
387
+ (this.stats.notificationsByPriority[notification.priority] || 0) + 1;
388
+ }
389
+
390
+ /**
391
+ * Get notification statistics
392
+ */
393
+ getStats() {
394
+ return {
395
+ ...this.stats,
396
+ enabled: this.options.enabled,
397
+ channels: this.options.channels,
398
+ rateLimitActive: this.options.enableRateLimit
399
+ };
400
+ }
401
+
402
+ /**
403
+ * Test notification system
404
+ */
405
+ async testNotification() {
406
+ const testNotification = {
407
+ id: `test-${Date.now()}`,
408
+ type: 'test',
409
+ priority: NOTIFICATION_PRIORITY.MEDIUM,
410
+ title: 'Test Notification',
411
+ message: 'This is a test notification from the continuous scan notification system',
412
+ description: 'If you see this, notifications are working correctly',
413
+ metadata: {
414
+ timestamp: new Date().toISOString(),
415
+ source: 'test'
416
+ }
417
+ };
418
+
419
+ return await this._sendNotification(testNotification);
420
+ }
421
+
422
+ /**
423
+ * Shutdown notification manager
424
+ */
425
+ shutdown() {
426
+ this.removeAllListeners();
427
+ if (this.alertSystem) {
428
+ this.alertSystem.shutdown();
429
+ }
430
+ }
431
+ }
432
+
433
+ module.exports = {
434
+ NotificationManager,
435
+ NOTIFICATION_CHANNELS,
436
+ NOTIFICATION_PRIORITY
437
+ };