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,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
|
+
};
|