bs9 1.0.0 → 1.3.0

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.
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { serve } from "bun";
4
+ import { randomBytes } from "node:crypto";
5
+
6
+ interface AdvancedWidget {
7
+ id: string;
8
+ type: 'metric' | 'chart' | 'alert' | 'custom';
9
+ title: string;
10
+ config: Record<string, any>;
11
+ position: { x: number; y: number; width: number; height: number };
12
+ }
13
+
14
+ interface AnomalyDetection {
15
+ service: string;
16
+ metric: string;
17
+ baseline: number;
18
+ threshold: number;
19
+ detected: boolean;
20
+ timestamp: number;
21
+ }
22
+
23
+ interface AlertCorrelation {
24
+ id: string;
25
+ alerts: Array<{
26
+ service: string;
27
+ type: string;
28
+ severity: 'low' | 'medium' | 'high' | 'critical';
29
+ timestamp: number;
30
+ }>;
31
+ correlation: number;
32
+ rootCause?: string;
33
+ }
34
+
35
+ class AdvancedMonitoring {
36
+ private widgets: Map<string, AdvancedWidget> = new Map();
37
+ private anomalies: Map<string, AnomalyDetection> = new Map();
38
+ private correlations: Map<string, AlertCorrelation> = new Map();
39
+ private baselines: Map<string, number> = new Map();
40
+
41
+ constructor() {
42
+ this.initializeDefaultWidgets();
43
+ }
44
+
45
+ private initializeDefaultWidgets(): void {
46
+ // CPU Usage Widget
47
+ this.widgets.set('cpu-usage', {
48
+ id: 'cpu-usage',
49
+ type: 'metric',
50
+ title: 'CPU Usage',
51
+ config: {
52
+ metric: 'cpu',
53
+ unit: '%',
54
+ threshold: 80,
55
+ refreshInterval: 5000
56
+ },
57
+ position: { x: 0, y: 0, width: 300, height: 200 }
58
+ });
59
+
60
+ // Memory Usage Widget
61
+ this.widgets.set('memory-usage', {
62
+ id: 'memory-usage',
63
+ type: 'metric',
64
+ title: 'Memory Usage',
65
+ config: {
66
+ metric: 'memory',
67
+ unit: 'MB',
68
+ threshold: 90,
69
+ refreshInterval: 5000
70
+ },
71
+ position: { x: 320, y: 0, width: 300, height: 200 }
72
+ });
73
+
74
+ // Service Health Chart
75
+ this.widgets.set('service-health', {
76
+ id: 'service-health',
77
+ type: 'chart',
78
+ title: 'Service Health',
79
+ config: {
80
+ chartType: 'line',
81
+ timeRange: '1h',
82
+ metrics: ['cpu', 'memory', 'response_time'],
83
+ refreshInterval: 10000
84
+ },
85
+ position: { x: 0, y: 220, width: 620, height: 300 }
86
+ });
87
+
88
+ // Alert Status Widget
89
+ this.widgets.set('alert-status', {
90
+ id: 'alert-status',
91
+ type: 'alert',
92
+ title: 'Active Alerts',
93
+ config: {
94
+ severity: ['high', 'critical'],
95
+ refreshInterval: 3000
96
+ },
97
+ position: { x: 640, y: 0, width: 300, height: 200 }
98
+ });
99
+ }
100
+
101
+ addWidget(widget: AdvancedWidget): void {
102
+ this.widgets.set(widget.id, widget);
103
+ }
104
+
105
+ removeWidget(widgetId: string): void {
106
+ this.widgets.delete(widgetId);
107
+ }
108
+
109
+ updateWidget(widgetId: string, updates: Partial<AdvancedWidget>): void {
110
+ const widget = this.widgets.get(widgetId);
111
+ if (widget) {
112
+ Object.assign(widget, updates);
113
+ }
114
+ }
115
+
116
+ getWidgets(): AdvancedWidget[] {
117
+ return Array.from(this.widgets.values());
118
+ }
119
+
120
+ async detectAnomalies(serviceMetrics: Record<string, any>): Promise<AnomalyDetection[]> {
121
+ const anomalies: AnomalyDetection[] = [];
122
+
123
+ for (const [serviceName, metrics] of Object.entries(serviceMetrics)) {
124
+ for (const [metricName, value] of Object.entries(metrics)) {
125
+ const key = `${serviceName}-${metricName}`;
126
+ const baseline = this.baselines.get(key) || 0;
127
+
128
+ // Simple anomaly detection using statistical deviation
129
+ const deviation = Math.abs((value as number) - baseline) / baseline;
130
+ const threshold = 0.3; // 30% deviation threshold
131
+
132
+ if (deviation > threshold) {
133
+ const anomaly: AnomalyDetection = {
134
+ service: serviceName,
135
+ metric: metricName,
136
+ baseline,
137
+ threshold: baseline * (1 + threshold),
138
+ detected: true,
139
+ timestamp: Date.now()
140
+ };
141
+
142
+ anomalies.push(anomaly);
143
+ this.anomalies.set(key, anomaly);
144
+ }
145
+ }
146
+ }
147
+
148
+ return anomalies;
149
+ }
150
+
151
+ async correlateAlerts(alerts: Array<any>): Promise<AlertCorrelation[]> {
152
+ const correlations: AlertCorrelation[] = [];
153
+
154
+ // Simple correlation based on time proximity and service relationships
155
+ for (let i = 0; i < alerts.length; i++) {
156
+ for (let j = i + 1; j < alerts.length; j++) {
157
+ const alert1 = alerts[i];
158
+ const alert2 = alerts[j];
159
+
160
+ const timeDiff = Math.abs(alert1.timestamp - alert2.timestamp);
161
+ const timeThreshold = 60000; // 1 minute
162
+
163
+ if (timeDiff < timeThreshold) {
164
+ const correlation: AlertCorrelation = {
165
+ id: randomBytes(8).toString('hex'),
166
+ alerts: [alert1, alert2],
167
+ correlation: 1 - (timeDiff / timeThreshold)
168
+ };
169
+
170
+ correlations.push(correlation);
171
+ this.correlations.set(correlation.id, correlation);
172
+ }
173
+ }
174
+ }
175
+
176
+ return correlations;
177
+ }
178
+
179
+ updateBaseline(service: string, metric: string, value: number): void {
180
+ const key = `${service}-${metric}`;
181
+ const currentBaseline = this.baselines.get(key) || 0;
182
+
183
+ // Exponential moving average for baseline
184
+ const alpha = 0.1;
185
+ const newBaseline = alpha * (value as number) + (1 - alpha) * currentBaseline;
186
+
187
+ this.baselines.set(key, newBaseline);
188
+ }
189
+
190
+ getAnomalies(): AnomalyDetection[] {
191
+ return Array.from(this.anomalies.values());
192
+ }
193
+
194
+ getCorrelations(): AlertCorrelation[] {
195
+ return Array.from(this.correlations.values());
196
+ }
197
+
198
+ generateDashboard(): string {
199
+ const widgets = this.getWidgets();
200
+
201
+ return `
202
+ <!DOCTYPE html>
203
+ <html lang="en">
204
+ <head>
205
+ <meta charset="UTF-8">
206
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
207
+ <title>BS9 Advanced Monitoring Dashboard</title>
208
+ <style>
209
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }
210
+ .dashboard { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px; max-width: 1400px; margin: 0 auto; }
211
+ .widget { background: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
212
+ .widget-header { font-size: 18px; font-weight: 600; margin-bottom: 15px; color: #333; }
213
+ .widget-content { min-height: 150px; }
214
+ .metric-value { font-size: 36px; font-weight: bold; color: #007bff; }
215
+ .metric-unit { font-size: 14px; color: #666; margin-left: 5px; }
216
+ .alert-item { padding: 10px; margin: 5px 0; border-left: 4px solid #dc3545; background: #f8d7da; }
217
+ .anomaly-item { padding: 10px; margin: 5px 0; border-left: 4px solid #ffc107; background: #fff3cd; }
218
+ .chart-container { height: 200px; background: #f8f9fa; border-radius: 4px; display: flex; align-items: center; justify-content: center; }
219
+ </style>
220
+ </head>
221
+ <body>
222
+ <h1>🔍 BS9 Advanced Monitoring Dashboard</h1>
223
+
224
+ <div class="dashboard">
225
+ ${widgets.map(widget => this.renderWidget(widget)).join('')}
226
+ </div>
227
+
228
+ <script>
229
+ // Auto-refresh widgets
230
+ setInterval(() => {
231
+ fetch('/api/advanced-metrics')
232
+ .then(response => response.json())
233
+ .then(data => {
234
+ updateWidgets(data);
235
+ })
236
+ .catch(error => console.error('Failed to fetch metrics:', error));
237
+ }, 5000);
238
+
239
+ function updateWidgets(data) {
240
+ // Update widget content based on data
241
+ console.log('Updating widgets with data:', data);
242
+ }
243
+ </script>
244
+ </body>
245
+ </html>`;
246
+ }
247
+
248
+ private renderWidget(widget: AdvancedWidget): string {
249
+ switch (widget.type) {
250
+ case 'metric':
251
+ return `
252
+ <div class="widget" style="grid-column: span ${Math.ceil(widget.position.width / 300)};">
253
+ <div class="widget-header">${widget.title}</div>
254
+ <div class="widget-content">
255
+ <div class="metric-value" id="${widget.id}-value">${typeof widget.config.value === 'number' ? widget.config.value : '--'}</div>
256
+ <span class="metric-unit">${widget.config.unit}</span>
257
+ </div>
258
+ </div>
259
+ `;
260
+
261
+ case 'chart':
262
+ return `
263
+ <div class="widget" style="grid-column: span ${Math.ceil(widget.position.width / 300)};">
264
+ <div class="widget-header">${widget.title}</div>
265
+ <div class="widget-content">
266
+ <div class="chart-container">
267
+ 📊 ${widget.config.chartType.toUpperCase()} Chart
268
+ </div>
269
+ </div>
270
+ </div>
271
+ `;
272
+
273
+ case 'alert':
274
+ return `
275
+ <div class="widget" style="grid-column: span ${Math.ceil(widget.position.width / 300)};">
276
+ <div class="widget-header">${widget.title}</div>
277
+ <div class="widget-content" id="${widget.id}-alerts">
278
+ <div class="alert-item">No active alerts</div>
279
+ </div>
280
+ </div>
281
+ `;
282
+
283
+ default:
284
+ return `
285
+ <div class="widget">
286
+ <div class="widget-header">${widget.title}</div>
287
+ <div class="widget-content">
288
+ Custom widget content
289
+ </div>
290
+ </div>
291
+ `;
292
+ }
293
+ }
294
+ }
295
+
296
+ export async function advancedMonitoringCommand(options: any): Promise<void> {
297
+ const monitoring = new AdvancedMonitoring();
298
+
299
+ console.log('🔍 Starting Advanced Monitoring Dashboard...');
300
+ console.log('📊 Features:');
301
+ console.log(' - Custom widgets');
302
+ console.log(' - Anomaly detection');
303
+ console.log(' - Alert correlation');
304
+ console.log(' - Performance baselines');
305
+
306
+ const server = serve({
307
+ port: options.port || 8090,
308
+ async fetch(req) {
309
+ const url = new URL(req.url);
310
+
311
+ if (url.pathname === '/') {
312
+ return new Response(monitoring.generateDashboard(), {
313
+ headers: { 'Content-Type': 'text/html' }
314
+ });
315
+ }
316
+
317
+ if (url.pathname === '/api/advanced-metrics') {
318
+ // Mock advanced metrics data
319
+ const metrics = {
320
+ widgets: monitoring.getWidgets(),
321
+ anomalies: monitoring.getAnomalies(),
322
+ correlations: monitoring.getCorrelations(),
323
+ timestamp: Date.now()
324
+ };
325
+
326
+ return new Response(JSON.stringify(metrics), {
327
+ headers: { 'Content-Type': 'application/json' }
328
+ });
329
+ }
330
+
331
+ return new Response('Not Found', { status: 404 });
332
+ }
333
+ });
334
+
335
+ console.log(`✅ Advanced monitoring dashboard started on http://localhost:${options.port || 8090}`);
336
+ console.log('🔗 Features available:');
337
+ console.log(' - Real-time anomaly detection');
338
+ console.log(' - Alert correlation analysis');
339
+ console.log(' - Custom widget configuration');
340
+ console.log(' - Performance baseline tracking');
341
+ }
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { platform } from "node:os";
4
+
5
+ export type Platform = 'linux' | 'darwin' | 'win32';
6
+
7
+ export interface PlatformInfo {
8
+ platform: Platform;
9
+ isLinux: boolean;
10
+ isMacOS: boolean;
11
+ isWindows: boolean;
12
+ serviceManager: 'systemd' | 'launchd' | 'windows-service';
13
+ configDir: string;
14
+ logDir: string;
15
+ serviceDir: string;
16
+ }
17
+
18
+ export function getPlatformInfo(): PlatformInfo {
19
+ const currentPlatform = platform() as Platform;
20
+
21
+ const baseInfo: PlatformInfo = {
22
+ platform: currentPlatform,
23
+ isLinux: currentPlatform === 'linux',
24
+ isMacOS: currentPlatform === 'darwin',
25
+ isWindows: currentPlatform === 'win32',
26
+ serviceManager: 'systemd',
27
+ configDir: '',
28
+ logDir: '',
29
+ serviceDir: ''
30
+ };
31
+
32
+ switch (currentPlatform) {
33
+ case 'linux':
34
+ baseInfo.serviceManager = 'systemd';
35
+ baseInfo.configDir = `${process.env.HOME}/.config/bs9`;
36
+ baseInfo.logDir = `${process.env.HOME}/.local/share/bs9/logs`;
37
+ baseInfo.serviceDir = `${process.env.HOME}/.config/systemd/user`;
38
+ break;
39
+
40
+ case 'darwin':
41
+ baseInfo.serviceManager = 'launchd';
42
+ baseInfo.configDir = `${process.env.HOME}/.bs9`;
43
+ baseInfo.logDir = `${process.env.HOME}/.bs9/logs`;
44
+ baseInfo.serviceDir = `${process.env.HOME}/Library/LaunchAgents`;
45
+ break;
46
+
47
+ case 'win32':
48
+ baseInfo.serviceManager = 'windows-service';
49
+ baseInfo.configDir = `${process.env.USERPROFILE}/.bs9`;
50
+ baseInfo.logDir = `${process.env.USERPROFILE}/.bs9/logs`;
51
+ baseInfo.serviceDir = `${process.env.USERPROFILE}/.bs9/services`;
52
+ break;
53
+
54
+ default:
55
+ throw new Error(`Unsupported platform: ${currentPlatform}`);
56
+ }
57
+
58
+ return baseInfo;
59
+ }
60
+
61
+ export function isSupportedPlatform(): boolean {
62
+ const supportedPlatforms: Platform[] = ['linux', 'darwin', 'win32'];
63
+ return supportedPlatforms.includes(platform() as Platform);
64
+ }
65
+
66
+ export function getPlatformSpecificCommands(): string[] {
67
+ const currentPlatform = platform() as Platform;
68
+
69
+ switch (currentPlatform) {
70
+ case 'linux':
71
+ return ['start', 'stop', 'restart', 'status', 'logs', 'monit', 'web', 'alert', 'export', 'deps', 'profile', 'loadbalancer', 'dbpool'];
72
+
73
+ case 'darwin':
74
+ return ['start', 'stop', 'restart', 'status', 'logs', 'monit', 'web', 'alert', 'export', 'deps', 'profile', 'loadbalancer', 'dbpool', 'macos'];
75
+
76
+ case 'win32':
77
+ return ['start', 'stop', 'restart', 'status', 'logs', 'monit', 'web', 'alert', 'export', 'deps', 'profile', 'loadbalancer', 'dbpool', 'windows'];
78
+
79
+ default:
80
+ return [];
81
+ }
82
+ }
83
+
84
+ export function getPlatformHelp(): string {
85
+ const currentPlatform = platform() as Platform;
86
+
87
+ switch (currentPlatform) {
88
+ case 'linux':
89
+ return `
90
+ 🐧 Linux Platform Features:
91
+ • Systemd-based service management
92
+ • User-mode service execution
93
+ • Advanced security hardening
94
+ • Resource limits and sandboxing
95
+
96
+ Available Commands:
97
+ ${getPlatformSpecificCommands().join(', ')}
98
+ `;
99
+
100
+ case 'darwin':
101
+ return `
102
+ 🍎 macOS Platform Features:
103
+ • Launchd service management
104
+ • Native macOS integration
105
+ • Automatic service recovery
106
+ • Standard macOS logging
107
+
108
+ Available Commands:
109
+ ${getPlatformSpecificCommands().join(', ')}
110
+
111
+ macOS-specific:
112
+ • bs9 macos create - Create launchd service
113
+ • bs9 macos start - Start launchd service
114
+ • bs9 macos stop - Stop launchd service
115
+ `;
116
+
117
+ case 'win32':
118
+ return `
119
+ 🪟 Windows Platform Features:
120
+ • Windows service management
121
+ • PowerShell-based automation
122
+ • Event log integration
123
+ • Service recovery policies
124
+
125
+ Available Commands:
126
+ ${getPlatformSpecificCommands().join(', ')}
127
+
128
+ Windows-specific:
129
+ • bs9 windows create - Create Windows service
130
+ • bs9 windows start - Start Windows service
131
+ • bs9 windows stop - Stop Windows service
132
+ `;
133
+
134
+ default:
135
+ return `❌ Platform ${currentPlatform} is not supported`;
136
+ }
137
+ }