bs9 1.3.2 → 1.3.4
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/bin/bs9 +1 -1
- package/dist/bs9-317ap6v2. +181 -0
- package/dist/bs9-3yvwj0zz. +185 -0
- package/dist/bs9-4vmeq5ds. +181 -0
- package/dist/bs9-qh3aahvk. +181 -0
- package/dist/bs9.js +5 -1
- package/package.json +2 -1
- package/src/commands/update.ts +20 -40
package/bin/bs9
CHANGED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { startCommand } from "../src/commands/start.js";
|
|
5
|
+
import { stopCommand } from "../src/commands/stop.js";
|
|
6
|
+
import { restartCommand } from "../src/commands/restart.js";
|
|
7
|
+
import { statusCommand } from "../src/commands/status.js";
|
|
8
|
+
import { logsCommand } from "../src/commands/logs.js";
|
|
9
|
+
import { monitCommand } from "../src/commands/monit.js";
|
|
10
|
+
import { webCommand } from "../src/commands/web.js";
|
|
11
|
+
import { alertCommand } from "../src/commands/alert.js";
|
|
12
|
+
import { exportCommand } from "../src/commands/export.js";
|
|
13
|
+
import { depsCommand } from "../src/commands/deps.js";
|
|
14
|
+
import { profileCommand } from "../src/commands/profile.js";
|
|
15
|
+
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
16
|
+
import { windowsCommand } from "../src/windows/service.js";
|
|
17
|
+
import { launchdCommand } from "../src/macos/launchd.js";
|
|
18
|
+
import { updateCommand } from "../src/commands/update.js";
|
|
19
|
+
import { dbpoolCommand } from "../src/database/pool.js";
|
|
20
|
+
import { advancedMonitoringCommand } from "../src/monitoring/advanced.js";
|
|
21
|
+
import { consulCommand } from "../src/discovery/consul.js";
|
|
22
|
+
|
|
23
|
+
const program = new Command();
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.name("bs9")
|
|
27
|
+
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
28
|
+
.version("1.3.4");
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command("start")
|
|
32
|
+
.description("Start a process with hardened systemd unit")
|
|
33
|
+
.argument("<file>", "Application file to start")
|
|
34
|
+
.option("-n, --name <name>", "Service name")
|
|
35
|
+
.option("-p, --port <port>", "Port number", "3000")
|
|
36
|
+
.option("-h, --host <host>", "Host address", "localhost")
|
|
37
|
+
.option("--https", "Use HTTPS protocol")
|
|
38
|
+
.option("-e, --env <env>", "Environment variables (can be used multiple times)", (value, previous) => [...(previous || []), value])
|
|
39
|
+
.option("--otel", "Enable OpenTelemetry instrumentation", true)
|
|
40
|
+
.option("--prometheus", "Enable Prometheus metrics", true)
|
|
41
|
+
.option("--build", "Build TypeScript to JavaScript before starting")
|
|
42
|
+
.action(startCommand);
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command("stop")
|
|
46
|
+
.description("Stop a managed service")
|
|
47
|
+
.argument("<name>", "Service name")
|
|
48
|
+
.action(stopCommand);
|
|
49
|
+
|
|
50
|
+
program
|
|
51
|
+
.command("restart")
|
|
52
|
+
.description("Restart a managed service")
|
|
53
|
+
.argument("<name>", "Service name")
|
|
54
|
+
.action(restartCommand);
|
|
55
|
+
|
|
56
|
+
program
|
|
57
|
+
.command("status")
|
|
58
|
+
.description("Show status and SRE metrics for all services")
|
|
59
|
+
.option("-w, --watch", "Watch mode (refresh every 2s)")
|
|
60
|
+
.action(statusCommand);
|
|
61
|
+
|
|
62
|
+
program
|
|
63
|
+
.command("logs")
|
|
64
|
+
.description("Show logs for a service (via journalctl)")
|
|
65
|
+
.argument("<name>", "Service name")
|
|
66
|
+
.option("-f, --follow", "Follow logs")
|
|
67
|
+
.option("-n, --lines <number>", "Number of lines", "50")
|
|
68
|
+
.action(logsCommand);
|
|
69
|
+
|
|
70
|
+
program
|
|
71
|
+
.command("monit")
|
|
72
|
+
.description("Real-time terminal dashboard for all services")
|
|
73
|
+
.option("-r, --refresh <seconds>", "Refresh interval in seconds", "2")
|
|
74
|
+
.action(monitCommand);
|
|
75
|
+
|
|
76
|
+
program
|
|
77
|
+
.command("web")
|
|
78
|
+
.description("Start web-based monitoring dashboard")
|
|
79
|
+
.option("-p, --port <port>", "Port for web dashboard", "8080")
|
|
80
|
+
.option("-d, --detach", "Run in background")
|
|
81
|
+
.action(webCommand);
|
|
82
|
+
|
|
83
|
+
program
|
|
84
|
+
.command("alert")
|
|
85
|
+
.description("Configure alert thresholds and webhooks")
|
|
86
|
+
.option("--enable", "Enable alerts")
|
|
87
|
+
.option("--disable", "Disable alerts")
|
|
88
|
+
.option("--webhook <url>", "Set webhook URL for alerts")
|
|
89
|
+
.option("--cpu <percentage>", "CPU threshold percentage")
|
|
90
|
+
.option("--memory <percentage>", "Memory threshold percentage")
|
|
91
|
+
.option("--errorRate <percentage>", "Error rate threshold percentage")
|
|
92
|
+
.option("--uptime <percentage>", "Uptime threshold percentage")
|
|
93
|
+
.option("--cooldown <seconds>", "Alert cooldown period in seconds")
|
|
94
|
+
.option("--service <name>", "Configure alerts for specific service")
|
|
95
|
+
.option("--list", "List current alert configuration")
|
|
96
|
+
.option("--test", "Test webhook connectivity")
|
|
97
|
+
.action(alertCommand);
|
|
98
|
+
|
|
99
|
+
program
|
|
100
|
+
.command("export")
|
|
101
|
+
.description("Export historical metrics data")
|
|
102
|
+
.option("-f, --format <format>", "Export format (json|csv)", "json")
|
|
103
|
+
.option("-h, --hours <hours>", "Hours of data to export", "24")
|
|
104
|
+
.option("-o, --output <file>", "Output file path")
|
|
105
|
+
.option("-s, --service <name>", "Export specific service metrics")
|
|
106
|
+
.action(exportCommand);
|
|
107
|
+
|
|
108
|
+
program
|
|
109
|
+
.command("deps")
|
|
110
|
+
.description("Visualize service dependencies")
|
|
111
|
+
.option("-f, --format <format>", "Output format (text|dot|json)", "text")
|
|
112
|
+
.option("-o, --output <file>", "Output file path")
|
|
113
|
+
.action(depsCommand);
|
|
114
|
+
|
|
115
|
+
program
|
|
116
|
+
.command("profile")
|
|
117
|
+
.description("Performance profiling for services")
|
|
118
|
+
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
119
|
+
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
120
|
+
.option("-s, --service <name>", "Service name to profile")
|
|
121
|
+
.option("-o, --output <file>", "Output file path")
|
|
122
|
+
.action(profileCommand);
|
|
123
|
+
|
|
124
|
+
program
|
|
125
|
+
.command("loadbalancer")
|
|
126
|
+
.description("Load balancer management")
|
|
127
|
+
.argument("<action>", "Action to perform")
|
|
128
|
+
.option("-p, --port <port>", "Load balancer port", "8080")
|
|
129
|
+
.option("-a, --algorithm <type>", "Load balancing algorithm", "round-robin")
|
|
130
|
+
.option("-b, --backends <list>", "Backend servers (host:port,host:port)")
|
|
131
|
+
.option("--health-check", "Enable health checking", true)
|
|
132
|
+
.option("--health-path <path>", "Health check path", "/healthz")
|
|
133
|
+
.option("--health-interval <ms>", "Health check interval", "10000")
|
|
134
|
+
.action(loadbalancerCommand);
|
|
135
|
+
|
|
136
|
+
program
|
|
137
|
+
.command("dbpool")
|
|
138
|
+
.description("Database connection pool management")
|
|
139
|
+
.argument("<action>", "Action to perform")
|
|
140
|
+
.option("--host <host>", "Database host", "localhost")
|
|
141
|
+
.option("--port <port>", "Database port", "5432")
|
|
142
|
+
.option("--database <name>", "Database name", "testdb")
|
|
143
|
+
.option("--username <user>", "Database username", "user")
|
|
144
|
+
.option("--password <pass>", "Database password", "password")
|
|
145
|
+
.option("--max-connections <num>", "Maximum connections", "10")
|
|
146
|
+
.option("--min-connections <num>", "Minimum connections", "2")
|
|
147
|
+
.option("--concurrency <num>", "Test concurrency", "10")
|
|
148
|
+
.option("--iterations <num>", "Test iterations", "100")
|
|
149
|
+
.action(dbpoolCommand);
|
|
150
|
+
|
|
151
|
+
program
|
|
152
|
+
.command("update")
|
|
153
|
+
.description("Update BS9 to latest version")
|
|
154
|
+
.option("--check", "Check for updates without installing")
|
|
155
|
+
.option("--force", "Force update even if already latest")
|
|
156
|
+
.option("--rollback", "Rollback to previous version")
|
|
157
|
+
.option("--version <version>", "Update to specific version")
|
|
158
|
+
.action(updateCommand);
|
|
159
|
+
|
|
160
|
+
program
|
|
161
|
+
.command("advanced")
|
|
162
|
+
.description("Advanced monitoring dashboard")
|
|
163
|
+
.option("--port <port>", "Dashboard port", "8090")
|
|
164
|
+
.action(advancedMonitoringCommand);
|
|
165
|
+
|
|
166
|
+
program
|
|
167
|
+
.command("consul")
|
|
168
|
+
.description("Consul service discovery")
|
|
169
|
+
.argument("<action>", "Action to perform")
|
|
170
|
+
.option("--consul-url <url>", "Consul URL", "http://localhost:8500")
|
|
171
|
+
.option("--name <name>", "Service name")
|
|
172
|
+
.option("--id <id>", "Service ID")
|
|
173
|
+
.option("--address <address>", "Service address")
|
|
174
|
+
.option("--port <port>", "Service port")
|
|
175
|
+
.option("--tags <tags>", "Service tags (comma-separated)")
|
|
176
|
+
.option("--health-check <url>", "Health check URL")
|
|
177
|
+
.option("--meta <json>", "Service metadata (JSON)")
|
|
178
|
+
.option("--service <service>", "Service name for discovery")
|
|
179
|
+
.action(consulCommand);
|
|
180
|
+
|
|
181
|
+
program.parse();
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
// Get version from package.json
|
|
4
|
+
const packageJson = await import("../package.json", { assert: { type: "json" } });
|
|
5
|
+
const VERSION = packageJson.default.version;
|
|
6
|
+
|
|
7
|
+
import { Command } from "commander";
|
|
8
|
+
import { startCommand } from "../src/commands/start.js";
|
|
9
|
+
import { stopCommand } from "../src/commands/stop.js";
|
|
10
|
+
import { restartCommand } from "../src/commands/restart.js";
|
|
11
|
+
import { statusCommand } from "../src/commands/status.js";
|
|
12
|
+
import { logsCommand } from "../src/commands/logs.js";
|
|
13
|
+
import { monitCommand } from "../src/commands/monit.js";
|
|
14
|
+
import { webCommand } from "../src/commands/web.js";
|
|
15
|
+
import { alertCommand } from "../src/commands/alert.js";
|
|
16
|
+
import { exportCommand } from "../src/commands/export.js";
|
|
17
|
+
import { depsCommand } from "../src/commands/deps.js";
|
|
18
|
+
import { profileCommand } from "../src/commands/profile.js";
|
|
19
|
+
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
20
|
+
import { windowsCommand } from "../src/windows/service.js";
|
|
21
|
+
import { launchdCommand } from "../src/macos/launchd.js";
|
|
22
|
+
import { updateCommand } from "../src/commands/update.js";
|
|
23
|
+
import { dbpoolCommand } from "../src/database/pool.js";
|
|
24
|
+
import { advancedMonitoringCommand } from "../src/monitoring/advanced.js";
|
|
25
|
+
import { consulCommand } from "../src/discovery/consul.js";
|
|
26
|
+
|
|
27
|
+
const program = new Command();
|
|
28
|
+
|
|
29
|
+
program
|
|
30
|
+
.name("bs9")
|
|
31
|
+
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
32
|
+
.version(VERSION);
|
|
33
|
+
|
|
34
|
+
program
|
|
35
|
+
.command("start")
|
|
36
|
+
.description("Start a process with hardened systemd unit")
|
|
37
|
+
.argument("<file>", "Application file to start")
|
|
38
|
+
.option("-n, --name <name>", "Service name")
|
|
39
|
+
.option("-p, --port <port>", "Port number", "3000")
|
|
40
|
+
.option("-h, --host <host>", "Host address", "localhost")
|
|
41
|
+
.option("--https", "Use HTTPS protocol")
|
|
42
|
+
.option("-e, --env <env>", "Environment variables (can be used multiple times)", (value, previous) => [...(previous || []), value])
|
|
43
|
+
.option("--otel", "Enable OpenTelemetry instrumentation", true)
|
|
44
|
+
.option("--prometheus", "Enable Prometheus metrics", true)
|
|
45
|
+
.option("--build", "Build TypeScript to JavaScript before starting")
|
|
46
|
+
.action(startCommand);
|
|
47
|
+
|
|
48
|
+
program
|
|
49
|
+
.command("stop")
|
|
50
|
+
.description("Stop a managed service")
|
|
51
|
+
.argument("<name>", "Service name")
|
|
52
|
+
.action(stopCommand);
|
|
53
|
+
|
|
54
|
+
program
|
|
55
|
+
.command("restart")
|
|
56
|
+
.description("Restart a managed service")
|
|
57
|
+
.argument("<name>", "Service name")
|
|
58
|
+
.action(restartCommand);
|
|
59
|
+
|
|
60
|
+
program
|
|
61
|
+
.command("status")
|
|
62
|
+
.description("Show status and SRE metrics for all services")
|
|
63
|
+
.option("-w, --watch", "Watch mode (refresh every 2s)")
|
|
64
|
+
.action(statusCommand);
|
|
65
|
+
|
|
66
|
+
program
|
|
67
|
+
.command("logs")
|
|
68
|
+
.description("Show logs for a service (via journalctl)")
|
|
69
|
+
.argument("<name>", "Service name")
|
|
70
|
+
.option("-f, --follow", "Follow logs")
|
|
71
|
+
.option("-n, --lines <number>", "Number of lines", "50")
|
|
72
|
+
.action(logsCommand);
|
|
73
|
+
|
|
74
|
+
program
|
|
75
|
+
.command("monit")
|
|
76
|
+
.description("Real-time terminal dashboard for all services")
|
|
77
|
+
.option("-r, --refresh <seconds>", "Refresh interval in seconds", "2")
|
|
78
|
+
.action(monitCommand);
|
|
79
|
+
|
|
80
|
+
program
|
|
81
|
+
.command("web")
|
|
82
|
+
.description("Start web-based monitoring dashboard")
|
|
83
|
+
.option("-p, --port <port>", "Port for web dashboard", "8080")
|
|
84
|
+
.option("-d, --detach", "Run in background")
|
|
85
|
+
.action(webCommand);
|
|
86
|
+
|
|
87
|
+
program
|
|
88
|
+
.command("alert")
|
|
89
|
+
.description("Configure alert thresholds and webhooks")
|
|
90
|
+
.option("--enable", "Enable alerts")
|
|
91
|
+
.option("--disable", "Disable alerts")
|
|
92
|
+
.option("--webhook <url>", "Set webhook URL for alerts")
|
|
93
|
+
.option("--cpu <percentage>", "CPU threshold percentage")
|
|
94
|
+
.option("--memory <percentage>", "Memory threshold percentage")
|
|
95
|
+
.option("--errorRate <percentage>", "Error rate threshold percentage")
|
|
96
|
+
.option("--uptime <percentage>", "Uptime threshold percentage")
|
|
97
|
+
.option("--cooldown <seconds>", "Alert cooldown period in seconds")
|
|
98
|
+
.option("--service <name>", "Configure alerts for specific service")
|
|
99
|
+
.option("--list", "List current alert configuration")
|
|
100
|
+
.option("--test", "Test webhook connectivity")
|
|
101
|
+
.action(alertCommand);
|
|
102
|
+
|
|
103
|
+
program
|
|
104
|
+
.command("export")
|
|
105
|
+
.description("Export historical metrics data")
|
|
106
|
+
.option("-f, --format <format>", "Export format (json|csv)", "json")
|
|
107
|
+
.option("-h, --hours <hours>", "Hours of data to export", "24")
|
|
108
|
+
.option("-o, --output <file>", "Output file path")
|
|
109
|
+
.option("-s, --service <name>", "Export specific service metrics")
|
|
110
|
+
.action(exportCommand);
|
|
111
|
+
|
|
112
|
+
program
|
|
113
|
+
.command("deps")
|
|
114
|
+
.description("Visualize service dependencies")
|
|
115
|
+
.option("-f, --format <format>", "Output format (text|dot|json)", "text")
|
|
116
|
+
.option("-o, --output <file>", "Output file path")
|
|
117
|
+
.action(depsCommand);
|
|
118
|
+
|
|
119
|
+
program
|
|
120
|
+
.command("profile")
|
|
121
|
+
.description("Performance profiling for services")
|
|
122
|
+
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
123
|
+
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
124
|
+
.option("-s, --service <name>", "Service name to profile")
|
|
125
|
+
.option("-o, --output <file>", "Output file path")
|
|
126
|
+
.action(profileCommand);
|
|
127
|
+
|
|
128
|
+
program
|
|
129
|
+
.command("loadbalancer")
|
|
130
|
+
.description("Load balancer management")
|
|
131
|
+
.argument("<action>", "Action to perform")
|
|
132
|
+
.option("-p, --port <port>", "Load balancer port", "8080")
|
|
133
|
+
.option("-a, --algorithm <type>", "Load balancing algorithm", "round-robin")
|
|
134
|
+
.option("-b, --backends <list>", "Backend servers (host:port,host:port)")
|
|
135
|
+
.option("--health-check", "Enable health checking", true)
|
|
136
|
+
.option("--health-path <path>", "Health check path", "/healthz")
|
|
137
|
+
.option("--health-interval <ms>", "Health check interval", "10000")
|
|
138
|
+
.action(loadbalancerCommand);
|
|
139
|
+
|
|
140
|
+
program
|
|
141
|
+
.command("dbpool")
|
|
142
|
+
.description("Database connection pool management")
|
|
143
|
+
.argument("<action>", "Action to perform")
|
|
144
|
+
.option("--host <host>", "Database host", "localhost")
|
|
145
|
+
.option("--port <port>", "Database port", "5432")
|
|
146
|
+
.option("--database <name>", "Database name", "testdb")
|
|
147
|
+
.option("--username <user>", "Database username", "user")
|
|
148
|
+
.option("--password <pass>", "Database password", "password")
|
|
149
|
+
.option("--max-connections <num>", "Maximum connections", "10")
|
|
150
|
+
.option("--min-connections <num>", "Minimum connections", "2")
|
|
151
|
+
.option("--concurrency <num>", "Test concurrency", "10")
|
|
152
|
+
.option("--iterations <num>", "Test iterations", "100")
|
|
153
|
+
.action(dbpoolCommand);
|
|
154
|
+
|
|
155
|
+
program
|
|
156
|
+
.command("update")
|
|
157
|
+
.description("Update BS9 to latest version")
|
|
158
|
+
.option("--check", "Check for updates without installing")
|
|
159
|
+
.option("--force", "Force update even if already latest")
|
|
160
|
+
.option("--rollback", "Rollback to previous version")
|
|
161
|
+
.option("--version <version>", "Update to specific version")
|
|
162
|
+
.action(updateCommand);
|
|
163
|
+
|
|
164
|
+
program
|
|
165
|
+
.command("advanced")
|
|
166
|
+
.description("Advanced monitoring dashboard")
|
|
167
|
+
.option("--port <port>", "Dashboard port", "8090")
|
|
168
|
+
.action(advancedMonitoringCommand);
|
|
169
|
+
|
|
170
|
+
program
|
|
171
|
+
.command("consul")
|
|
172
|
+
.description("Consul service discovery")
|
|
173
|
+
.argument("<action>", "Action to perform")
|
|
174
|
+
.option("--consul-url <url>", "Consul URL", "http://localhost:8500")
|
|
175
|
+
.option("--name <name>", "Service name")
|
|
176
|
+
.option("--id <id>", "Service ID")
|
|
177
|
+
.option("--address <address>", "Service address")
|
|
178
|
+
.option("--port <port>", "Service port")
|
|
179
|
+
.option("--tags <tags>", "Service tags (comma-separated)")
|
|
180
|
+
.option("--health-check <url>", "Health check URL")
|
|
181
|
+
.option("--meta <json>", "Service metadata (JSON)")
|
|
182
|
+
.option("--service <service>", "Service name for discovery")
|
|
183
|
+
.action(consulCommand);
|
|
184
|
+
|
|
185
|
+
program.parse();
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { startCommand } from "../src/commands/start.js";
|
|
5
|
+
import { stopCommand } from "../src/commands/stop.js";
|
|
6
|
+
import { restartCommand } from "../src/commands/restart.js";
|
|
7
|
+
import { statusCommand } from "../src/commands/status.js";
|
|
8
|
+
import { logsCommand } from "../src/commands/logs.js";
|
|
9
|
+
import { monitCommand } from "../src/commands/monit.js";
|
|
10
|
+
import { webCommand } from "../src/commands/web.js";
|
|
11
|
+
import { alertCommand } from "../src/commands/alert.js";
|
|
12
|
+
import { exportCommand } from "../src/commands/export.js";
|
|
13
|
+
import { depsCommand } from "../src/commands/deps.js";
|
|
14
|
+
import { profileCommand } from "../src/commands/profile.js";
|
|
15
|
+
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
16
|
+
import { windowsCommand } from "../src/windows/service.js";
|
|
17
|
+
import { launchdCommand } from "../src/macos/launchd.js";
|
|
18
|
+
import { updateCommand } from "../src/commands/update.js";
|
|
19
|
+
import { dbpoolCommand } from "../src/database/pool.js";
|
|
20
|
+
import { advancedMonitoringCommand } from "../src/monitoring/advanced.js";
|
|
21
|
+
import { consulCommand } from "../src/discovery/consul.js";
|
|
22
|
+
|
|
23
|
+
const program = new Command();
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.name("bs9")
|
|
27
|
+
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
28
|
+
.version("1.3.3");
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command("start")
|
|
32
|
+
.description("Start a process with hardened systemd unit")
|
|
33
|
+
.argument("<file>", "Application file to start")
|
|
34
|
+
.option("-n, --name <name>", "Service name")
|
|
35
|
+
.option("-p, --port <port>", "Port number", "3000")
|
|
36
|
+
.option("-h, --host <host>", "Host address", "localhost")
|
|
37
|
+
.option("--https", "Use HTTPS protocol")
|
|
38
|
+
.option("-e, --env <env>", "Environment variables (can be used multiple times)", (value, previous) => [...(previous || []), value])
|
|
39
|
+
.option("--otel", "Enable OpenTelemetry instrumentation", true)
|
|
40
|
+
.option("--prometheus", "Enable Prometheus metrics", true)
|
|
41
|
+
.option("--build", "Build TypeScript to JavaScript before starting")
|
|
42
|
+
.action(startCommand);
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command("stop")
|
|
46
|
+
.description("Stop a managed service")
|
|
47
|
+
.argument("<name>", "Service name")
|
|
48
|
+
.action(stopCommand);
|
|
49
|
+
|
|
50
|
+
program
|
|
51
|
+
.command("restart")
|
|
52
|
+
.description("Restart a managed service")
|
|
53
|
+
.argument("<name>", "Service name")
|
|
54
|
+
.action(restartCommand);
|
|
55
|
+
|
|
56
|
+
program
|
|
57
|
+
.command("status")
|
|
58
|
+
.description("Show status and SRE metrics for all services")
|
|
59
|
+
.option("-w, --watch", "Watch mode (refresh every 2s)")
|
|
60
|
+
.action(statusCommand);
|
|
61
|
+
|
|
62
|
+
program
|
|
63
|
+
.command("logs")
|
|
64
|
+
.description("Show logs for a service (via journalctl)")
|
|
65
|
+
.argument("<name>", "Service name")
|
|
66
|
+
.option("-f, --follow", "Follow logs")
|
|
67
|
+
.option("-n, --lines <number>", "Number of lines", "50")
|
|
68
|
+
.action(logsCommand);
|
|
69
|
+
|
|
70
|
+
program
|
|
71
|
+
.command("monit")
|
|
72
|
+
.description("Real-time terminal dashboard for all services")
|
|
73
|
+
.option("-r, --refresh <seconds>", "Refresh interval in seconds", "2")
|
|
74
|
+
.action(monitCommand);
|
|
75
|
+
|
|
76
|
+
program
|
|
77
|
+
.command("web")
|
|
78
|
+
.description("Start web-based monitoring dashboard")
|
|
79
|
+
.option("-p, --port <port>", "Port for web dashboard", "8080")
|
|
80
|
+
.option("-d, --detach", "Run in background")
|
|
81
|
+
.action(webCommand);
|
|
82
|
+
|
|
83
|
+
program
|
|
84
|
+
.command("alert")
|
|
85
|
+
.description("Configure alert thresholds and webhooks")
|
|
86
|
+
.option("--enable", "Enable alerts")
|
|
87
|
+
.option("--disable", "Disable alerts")
|
|
88
|
+
.option("--webhook <url>", "Set webhook URL for alerts")
|
|
89
|
+
.option("--cpu <percentage>", "CPU threshold percentage")
|
|
90
|
+
.option("--memory <percentage>", "Memory threshold percentage")
|
|
91
|
+
.option("--errorRate <percentage>", "Error rate threshold percentage")
|
|
92
|
+
.option("--uptime <percentage>", "Uptime threshold percentage")
|
|
93
|
+
.option("--cooldown <seconds>", "Alert cooldown period in seconds")
|
|
94
|
+
.option("--service <name>", "Configure alerts for specific service")
|
|
95
|
+
.option("--list", "List current alert configuration")
|
|
96
|
+
.option("--test", "Test webhook connectivity")
|
|
97
|
+
.action(alertCommand);
|
|
98
|
+
|
|
99
|
+
program
|
|
100
|
+
.command("export")
|
|
101
|
+
.description("Export historical metrics data")
|
|
102
|
+
.option("-f, --format <format>", "Export format (json|csv)", "json")
|
|
103
|
+
.option("-h, --hours <hours>", "Hours of data to export", "24")
|
|
104
|
+
.option("-o, --output <file>", "Output file path")
|
|
105
|
+
.option("-s, --service <name>", "Export specific service metrics")
|
|
106
|
+
.action(exportCommand);
|
|
107
|
+
|
|
108
|
+
program
|
|
109
|
+
.command("deps")
|
|
110
|
+
.description("Visualize service dependencies")
|
|
111
|
+
.option("-f, --format <format>", "Output format (text|dot|json)", "text")
|
|
112
|
+
.option("-o, --output <file>", "Output file path")
|
|
113
|
+
.action(depsCommand);
|
|
114
|
+
|
|
115
|
+
program
|
|
116
|
+
.command("profile")
|
|
117
|
+
.description("Performance profiling for services")
|
|
118
|
+
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
119
|
+
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
120
|
+
.option("-s, --service <name>", "Service name to profile")
|
|
121
|
+
.option("-o, --output <file>", "Output file path")
|
|
122
|
+
.action(profileCommand);
|
|
123
|
+
|
|
124
|
+
program
|
|
125
|
+
.command("loadbalancer")
|
|
126
|
+
.description("Load balancer management")
|
|
127
|
+
.argument("<action>", "Action to perform")
|
|
128
|
+
.option("-p, --port <port>", "Load balancer port", "8080")
|
|
129
|
+
.option("-a, --algorithm <type>", "Load balancing algorithm", "round-robin")
|
|
130
|
+
.option("-b, --backends <list>", "Backend servers (host:port,host:port)")
|
|
131
|
+
.option("--health-check", "Enable health checking", true)
|
|
132
|
+
.option("--health-path <path>", "Health check path", "/healthz")
|
|
133
|
+
.option("--health-interval <ms>", "Health check interval", "10000")
|
|
134
|
+
.action(loadbalancerCommand);
|
|
135
|
+
|
|
136
|
+
program
|
|
137
|
+
.command("dbpool")
|
|
138
|
+
.description("Database connection pool management")
|
|
139
|
+
.argument("<action>", "Action to perform")
|
|
140
|
+
.option("--host <host>", "Database host", "localhost")
|
|
141
|
+
.option("--port <port>", "Database port", "5432")
|
|
142
|
+
.option("--database <name>", "Database name", "testdb")
|
|
143
|
+
.option("--username <user>", "Database username", "user")
|
|
144
|
+
.option("--password <pass>", "Database password", "password")
|
|
145
|
+
.option("--max-connections <num>", "Maximum connections", "10")
|
|
146
|
+
.option("--min-connections <num>", "Minimum connections", "2")
|
|
147
|
+
.option("--concurrency <num>", "Test concurrency", "10")
|
|
148
|
+
.option("--iterations <num>", "Test iterations", "100")
|
|
149
|
+
.action(dbpoolCommand);
|
|
150
|
+
|
|
151
|
+
program
|
|
152
|
+
.command("update")
|
|
153
|
+
.description("Update BS9 to latest version")
|
|
154
|
+
.option("--check", "Check for updates without installing")
|
|
155
|
+
.option("--force", "Force update even if already latest")
|
|
156
|
+
.option("--rollback", "Rollback to previous version")
|
|
157
|
+
.option("--version <version>", "Update to specific version")
|
|
158
|
+
.action(updateCommand);
|
|
159
|
+
|
|
160
|
+
program
|
|
161
|
+
.command("advanced")
|
|
162
|
+
.description("Advanced monitoring dashboard")
|
|
163
|
+
.option("--port <port>", "Dashboard port", "8090")
|
|
164
|
+
.action(advancedMonitoringCommand);
|
|
165
|
+
|
|
166
|
+
program
|
|
167
|
+
.command("consul")
|
|
168
|
+
.description("Consul service discovery")
|
|
169
|
+
.argument("<action>", "Action to perform")
|
|
170
|
+
.option("--consul-url <url>", "Consul URL", "http://localhost:8500")
|
|
171
|
+
.option("--name <name>", "Service name")
|
|
172
|
+
.option("--id <id>", "Service ID")
|
|
173
|
+
.option("--address <address>", "Service address")
|
|
174
|
+
.option("--port <port>", "Service port")
|
|
175
|
+
.option("--tags <tags>", "Service tags (comma-separated)")
|
|
176
|
+
.option("--health-check <url>", "Health check URL")
|
|
177
|
+
.option("--meta <json>", "Service metadata (JSON)")
|
|
178
|
+
.option("--service <service>", "Service name for discovery")
|
|
179
|
+
.action(consulCommand);
|
|
180
|
+
|
|
181
|
+
program.parse();
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { startCommand } from "../src/commands/start.js";
|
|
5
|
+
import { stopCommand } from "../src/commands/stop.js";
|
|
6
|
+
import { restartCommand } from "../src/commands/restart.js";
|
|
7
|
+
import { statusCommand } from "../src/commands/status.js";
|
|
8
|
+
import { logsCommand } from "../src/commands/logs.js";
|
|
9
|
+
import { monitCommand } from "../src/commands/monit.js";
|
|
10
|
+
import { webCommand } from "../src/commands/web.js";
|
|
11
|
+
import { alertCommand } from "../src/commands/alert.js";
|
|
12
|
+
import { exportCommand } from "../src/commands/export.js";
|
|
13
|
+
import { depsCommand } from "../src/commands/deps.js";
|
|
14
|
+
import { profileCommand } from "../src/commands/profile.js";
|
|
15
|
+
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
16
|
+
import { windowsCommand } from "../src/windows/service.js";
|
|
17
|
+
import { launchdCommand } from "../src/macos/launchd.js";
|
|
18
|
+
import { updateCommand } from "../src/commands/update.js";
|
|
19
|
+
import { dbpoolCommand } from "../src/database/pool.js";
|
|
20
|
+
import { advancedMonitoringCommand } from "../src/monitoring/advanced.js";
|
|
21
|
+
import { consulCommand } from "../src/discovery/consul.js";
|
|
22
|
+
|
|
23
|
+
const program = new Command();
|
|
24
|
+
|
|
25
|
+
program
|
|
26
|
+
.name("bs9")
|
|
27
|
+
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
28
|
+
.version("1.3.2");
|
|
29
|
+
|
|
30
|
+
program
|
|
31
|
+
.command("start")
|
|
32
|
+
.description("Start a process with hardened systemd unit")
|
|
33
|
+
.argument("<file>", "Application file to start")
|
|
34
|
+
.option("-n, --name <name>", "Service name")
|
|
35
|
+
.option("-p, --port <port>", "Port number", "3000")
|
|
36
|
+
.option("-h, --host <host>", "Host address", "localhost")
|
|
37
|
+
.option("--https", "Use HTTPS protocol")
|
|
38
|
+
.option("-e, --env <env>", "Environment variables (can be used multiple times)", (value, previous) => [...(previous || []), value])
|
|
39
|
+
.option("--otel", "Enable OpenTelemetry instrumentation", true)
|
|
40
|
+
.option("--prometheus", "Enable Prometheus metrics", true)
|
|
41
|
+
.option("--build", "Build TypeScript to JavaScript before starting")
|
|
42
|
+
.action(startCommand);
|
|
43
|
+
|
|
44
|
+
program
|
|
45
|
+
.command("stop")
|
|
46
|
+
.description("Stop a managed service")
|
|
47
|
+
.argument("<name>", "Service name")
|
|
48
|
+
.action(stopCommand);
|
|
49
|
+
|
|
50
|
+
program
|
|
51
|
+
.command("restart")
|
|
52
|
+
.description("Restart a managed service")
|
|
53
|
+
.argument("<name>", "Service name")
|
|
54
|
+
.action(restartCommand);
|
|
55
|
+
|
|
56
|
+
program
|
|
57
|
+
.command("status")
|
|
58
|
+
.description("Show status and SRE metrics for all services")
|
|
59
|
+
.option("-w, --watch", "Watch mode (refresh every 2s)")
|
|
60
|
+
.action(statusCommand);
|
|
61
|
+
|
|
62
|
+
program
|
|
63
|
+
.command("logs")
|
|
64
|
+
.description("Show logs for a service (via journalctl)")
|
|
65
|
+
.argument("<name>", "Service name")
|
|
66
|
+
.option("-f, --follow", "Follow logs")
|
|
67
|
+
.option("-n, --lines <number>", "Number of lines", "50")
|
|
68
|
+
.action(logsCommand);
|
|
69
|
+
|
|
70
|
+
program
|
|
71
|
+
.command("monit")
|
|
72
|
+
.description("Real-time terminal dashboard for all services")
|
|
73
|
+
.option("-r, --refresh <seconds>", "Refresh interval in seconds", "2")
|
|
74
|
+
.action(monitCommand);
|
|
75
|
+
|
|
76
|
+
program
|
|
77
|
+
.command("web")
|
|
78
|
+
.description("Start web-based monitoring dashboard")
|
|
79
|
+
.option("-p, --port <port>", "Port for web dashboard", "8080")
|
|
80
|
+
.option("-d, --detach", "Run in background")
|
|
81
|
+
.action(webCommand);
|
|
82
|
+
|
|
83
|
+
program
|
|
84
|
+
.command("alert")
|
|
85
|
+
.description("Configure alert thresholds and webhooks")
|
|
86
|
+
.option("--enable", "Enable alerts")
|
|
87
|
+
.option("--disable", "Disable alerts")
|
|
88
|
+
.option("--webhook <url>", "Set webhook URL for alerts")
|
|
89
|
+
.option("--cpu <percentage>", "CPU threshold percentage")
|
|
90
|
+
.option("--memory <percentage>", "Memory threshold percentage")
|
|
91
|
+
.option("--errorRate <percentage>", "Error rate threshold percentage")
|
|
92
|
+
.option("--uptime <percentage>", "Uptime threshold percentage")
|
|
93
|
+
.option("--cooldown <seconds>", "Alert cooldown period in seconds")
|
|
94
|
+
.option("--service <name>", "Configure alerts for specific service")
|
|
95
|
+
.option("--list", "List current alert configuration")
|
|
96
|
+
.option("--test", "Test webhook connectivity")
|
|
97
|
+
.action(alertCommand);
|
|
98
|
+
|
|
99
|
+
program
|
|
100
|
+
.command("export")
|
|
101
|
+
.description("Export historical metrics data")
|
|
102
|
+
.option("-f, --format <format>", "Export format (json|csv)", "json")
|
|
103
|
+
.option("-h, --hours <hours>", "Hours of data to export", "24")
|
|
104
|
+
.option("-o, --output <file>", "Output file path")
|
|
105
|
+
.option("-s, --service <name>", "Export specific service metrics")
|
|
106
|
+
.action(exportCommand);
|
|
107
|
+
|
|
108
|
+
program
|
|
109
|
+
.command("deps")
|
|
110
|
+
.description("Visualize service dependencies")
|
|
111
|
+
.option("-f, --format <format>", "Output format (text|dot|json)", "text")
|
|
112
|
+
.option("-o, --output <file>", "Output file path")
|
|
113
|
+
.action(depsCommand);
|
|
114
|
+
|
|
115
|
+
program
|
|
116
|
+
.command("profile")
|
|
117
|
+
.description("Performance profiling for services")
|
|
118
|
+
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
119
|
+
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
120
|
+
.option("-s, --service <name>", "Service name to profile")
|
|
121
|
+
.option("-o, --output <file>", "Output file path")
|
|
122
|
+
.action(profileCommand);
|
|
123
|
+
|
|
124
|
+
program
|
|
125
|
+
.command("loadbalancer")
|
|
126
|
+
.description("Load balancer management")
|
|
127
|
+
.argument("<action>", "Action to perform")
|
|
128
|
+
.option("-p, --port <port>", "Load balancer port", "8080")
|
|
129
|
+
.option("-a, --algorithm <type>", "Load balancing algorithm", "round-robin")
|
|
130
|
+
.option("-b, --backends <list>", "Backend servers (host:port,host:port)")
|
|
131
|
+
.option("--health-check", "Enable health checking", true)
|
|
132
|
+
.option("--health-path <path>", "Health check path", "/healthz")
|
|
133
|
+
.option("--health-interval <ms>", "Health check interval", "10000")
|
|
134
|
+
.action(loadbalancerCommand);
|
|
135
|
+
|
|
136
|
+
program
|
|
137
|
+
.command("dbpool")
|
|
138
|
+
.description("Database connection pool management")
|
|
139
|
+
.argument("<action>", "Action to perform")
|
|
140
|
+
.option("--host <host>", "Database host", "localhost")
|
|
141
|
+
.option("--port <port>", "Database port", "5432")
|
|
142
|
+
.option("--database <name>", "Database name", "testdb")
|
|
143
|
+
.option("--username <user>", "Database username", "user")
|
|
144
|
+
.option("--password <pass>", "Database password", "password")
|
|
145
|
+
.option("--max-connections <num>", "Maximum connections", "10")
|
|
146
|
+
.option("--min-connections <num>", "Minimum connections", "2")
|
|
147
|
+
.option("--concurrency <num>", "Test concurrency", "10")
|
|
148
|
+
.option("--iterations <num>", "Test iterations", "100")
|
|
149
|
+
.action(dbpoolCommand);
|
|
150
|
+
|
|
151
|
+
program
|
|
152
|
+
.command("update")
|
|
153
|
+
.description("Update BS9 to latest version")
|
|
154
|
+
.option("--check", "Check for updates without installing")
|
|
155
|
+
.option("--force", "Force update even if already latest")
|
|
156
|
+
.option("--rollback", "Rollback to previous version")
|
|
157
|
+
.option("--version <version>", "Update to specific version")
|
|
158
|
+
.action(updateCommand);
|
|
159
|
+
|
|
160
|
+
program
|
|
161
|
+
.command("advanced")
|
|
162
|
+
.description("Advanced monitoring dashboard")
|
|
163
|
+
.option("--port <port>", "Dashboard port", "8090")
|
|
164
|
+
.action(advancedMonitoringCommand);
|
|
165
|
+
|
|
166
|
+
program
|
|
167
|
+
.command("consul")
|
|
168
|
+
.description("Consul service discovery")
|
|
169
|
+
.argument("<action>", "Action to perform")
|
|
170
|
+
.option("--consul-url <url>", "Consul URL", "http://localhost:8500")
|
|
171
|
+
.option("--name <name>", "Service name")
|
|
172
|
+
.option("--id <id>", "Service ID")
|
|
173
|
+
.option("--address <address>", "Service address")
|
|
174
|
+
.option("--port <port>", "Service port")
|
|
175
|
+
.option("--tags <tags>", "Service tags (comma-separated)")
|
|
176
|
+
.option("--health-check <url>", "Health check URL")
|
|
177
|
+
.option("--meta <json>", "Service metadata (JSON)")
|
|
178
|
+
.option("--service <service>", "Service name for discovery")
|
|
179
|
+
.action(consulCommand);
|
|
180
|
+
|
|
181
|
+
program.parse();
|
package/dist/bs9.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bs9",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Bun Sentinel 9 - High-performance, non-root process manager for Bun",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"scripts": {
|
|
18
18
|
"start": "bun run src/index.ts",
|
|
19
19
|
"build": "bun build ./bin/bs9 --outdir ./dist --target bun",
|
|
20
|
+
"build:version": "node scripts/update-version.js",
|
|
20
21
|
"audit": "bun audit"
|
|
21
22
|
},
|
|
22
23
|
"keywords": [
|
package/src/commands/update.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { existsSync, writeFileSync, mkdirSync } from "node:fs";
|
|
|
5
5
|
import { join, dirname } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
import { getPlatformInfo } from "../platform/detect.js";
|
|
8
|
+
import * as fs from "node:fs";
|
|
8
9
|
|
|
9
10
|
interface UpdateOptions {
|
|
10
11
|
check?: boolean;
|
|
@@ -52,11 +53,11 @@ class BS9Updater {
|
|
|
52
53
|
try {
|
|
53
54
|
// Use the actual package.json path from the project root
|
|
54
55
|
const packageJson = join(process.cwd(), 'package.json');
|
|
55
|
-
const content =
|
|
56
|
+
const content = fs.readFileSync(packageJson, 'utf8');
|
|
56
57
|
const pkg = JSON.parse(content);
|
|
57
58
|
return pkg.version;
|
|
58
59
|
} catch {
|
|
59
|
-
return '1.
|
|
60
|
+
return '1.3.3'; // Fallback version
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -67,7 +68,7 @@ class BS9Updater {
|
|
|
67
68
|
return data.version;
|
|
68
69
|
} catch (error) {
|
|
69
70
|
console.warn('⚠️ Failed to fetch latest version from npm, using fallback');
|
|
70
|
-
return '1.3.
|
|
71
|
+
return '1.3.3'; // Return current version as fallback
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -140,49 +141,28 @@ class BS9Updater {
|
|
|
140
141
|
public async performUpdate(targetVersion?: string): Promise<void> {
|
|
141
142
|
console.log('🔄 Starting BS9 update...');
|
|
142
143
|
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
console.log(`✅ Backup created: ${backup.version}-${backup.timestamp}`);
|
|
147
|
-
|
|
148
|
-
// Update package.json version
|
|
149
|
-
const packageJsonPath = join(process.cwd(), 'package.json');
|
|
150
|
-
const packageJson = JSON.parse(require('fs').readFileSync(packageJsonPath, 'utf-8'));
|
|
151
|
-
const oldVersion = packageJson.version;
|
|
152
|
-
packageJson.version = targetVersion || await this.getLatestVersion();
|
|
153
|
-
|
|
154
|
-
require('fs').writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
155
|
-
console.log(`📝 Updated version: ${oldVersion} → ${packageJson.version}`);
|
|
144
|
+
// Get latest version if not specified
|
|
145
|
+
const latestVersion = targetVersion || await this.getLatestVersion();
|
|
146
|
+
const currentVersion = this.getCurrentVersion();
|
|
156
147
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
console.log('✅ Dependencies installed');
|
|
162
|
-
} catch (error) {
|
|
163
|
-
console.error('❌ Failed to install dependencies:', error);
|
|
164
|
-
await this.rollback(backup);
|
|
165
|
-
throw error;
|
|
148
|
+
if (currentVersion === latestVersion && !targetVersion) {
|
|
149
|
+
console.log('✅ BS9 is already up to date');
|
|
150
|
+
console.log(` Current version: ${currentVersion}`);
|
|
151
|
+
return;
|
|
166
152
|
}
|
|
167
153
|
|
|
168
|
-
|
|
169
|
-
|
|
154
|
+
console.log(`� Updating from ${currentVersion} to ${latestVersion}`);
|
|
155
|
+
|
|
156
|
+
// Use npm to update globally
|
|
157
|
+
console.log('📦 Installing latest version...');
|
|
170
158
|
try {
|
|
171
|
-
execSync(
|
|
172
|
-
console.log('✅
|
|
159
|
+
execSync(`bun install -g bs9@${latestVersion}`, { stdio: 'inherit' });
|
|
160
|
+
console.log('✅ BS9 updated successfully!');
|
|
161
|
+
console.log(` Version: ${latestVersion}`);
|
|
173
162
|
} catch (error) {
|
|
174
|
-
console.error('❌
|
|
175
|
-
|
|
176
|
-
throw error;
|
|
163
|
+
console.error('❌ Failed to update BS9:', error);
|
|
164
|
+
console.log('💡 Try: bun install -g bs9@latest');
|
|
177
165
|
}
|
|
178
|
-
|
|
179
|
-
// Save backup info
|
|
180
|
-
const backupInfoPath = join(this.backupDir, `current-backup.json`);
|
|
181
|
-
writeFileSync(backupInfoPath, JSON.stringify(backup, null, 2));
|
|
182
|
-
|
|
183
|
-
console.log('🎉 BS9 updated successfully!');
|
|
184
|
-
console.log(` Version: ${packageJson.version}`);
|
|
185
|
-
console.log(` Backup: ${backup.version}-${backup.timestamp}`);
|
|
186
166
|
}
|
|
187
167
|
|
|
188
168
|
public async rollback(backup?: BackupInfo): Promise<void> {
|