bs9 1.3.5 → 1.3.7
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 +14 -2
- package/bin/bs9 +22 -2
- package/dist/bs9-6h4w11ar. +201 -0
- package/dist/bs9-c399ds6a. +181 -0
- package/dist/bs9-zpqd24hj. +189 -0
- package/dist/bs9.js +1 -1
- package/package.json +1 -1
- package/src/alerting/config.ts +9 -0
- package/src/commands/alert.ts +9 -0
- package/src/commands/delete.ts +178 -0
- package/src/commands/deps.ts +9 -0
- package/src/commands/export.ts +9 -0
- package/src/commands/logs.ts +9 -0
- package/src/commands/monit.ts +9 -0
- package/src/commands/profile.ts +9 -0
- package/src/commands/restart.ts +9 -0
- package/src/commands/start.ts +9 -0
- package/src/commands/status.ts +9 -0
- package/src/commands/stop.ts +9 -0
- package/src/commands/update.ts +9 -0
- package/src/commands/web.ts +9 -0
- package/src/database/pool.ts +9 -0
- package/src/discovery/consul.ts +9 -0
- package/src/injectors/otel.ts +9 -0
- package/src/loadbalancer/manager.ts +9 -0
- package/src/macos/launchd.ts +9 -0
- package/src/monitoring/advanced.ts +9 -0
- package/src/platform/detect.ts +9 -0
- package/src/storage/metrics.ts +9 -0
- package/src/web/dashboard.ts +9 -0
- package/src/windows/service.ts +9 -0
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# BS9 (Bun Sentinel 9) 🚀
|
|
2
2
|
|
|
3
3
|
[](https://opensource.org/licenses/MIT)
|
|
4
|
-
[](https://github.com/xarhang/bs9)
|
|
5
5
|
[](SECURITY.md)
|
|
6
6
|
[](PRODUCTION.md)
|
|
7
7
|
[](https://github.com/bs9/bs9)
|
|
@@ -566,7 +566,19 @@ bs9 export --service myapp --hours 24
|
|
|
566
566
|
|
|
567
567
|
## 📄 License
|
|
568
568
|
|
|
569
|
-
MIT License - see LICENSE file for details.
|
|
569
|
+
**MIT License** - see [LICENSE](LICENSE) file for details.
|
|
570
|
+
|
|
571
|
+
BS9 is 100% open source and free for everyone - no restrictions, no enterprise features, no paid tiers. All features are available to everyone under the MIT license.
|
|
572
|
+
|
|
573
|
+
### 🤝 Support Open Source
|
|
574
|
+
If you find BS9 useful, please consider:
|
|
575
|
+
- ⭐ Starring this repository
|
|
576
|
+
- 🐛 Reporting issues and feature requests
|
|
577
|
+
- 💬 Contributing code or documentation
|
|
578
|
+
- 🎯 Sponsoring the project (GitHub Sponsors)
|
|
579
|
+
- 📢 Sharing with your community
|
|
580
|
+
|
|
581
|
+
**BS9 is community-driven and will always remain free and open source.**
|
|
570
582
|
|
|
571
583
|
---
|
|
572
584
|
|
package/bin/bs9
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { join, dirname } from "node:path";
|
|
6
|
+
|
|
7
|
+
// Read version from package.json
|
|
8
|
+
const packageJsonPath = join(dirname(import.meta.path), '..', 'package.json');
|
|
9
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
10
|
+
const version = packageJson.version;
|
|
11
|
+
|
|
4
12
|
import { startCommand } from "../src/commands/start.js";
|
|
5
13
|
import { stopCommand } from "../src/commands/stop.js";
|
|
6
14
|
import { restartCommand } from "../src/commands/restart.js";
|
|
@@ -12,6 +20,7 @@ import { alertCommand } from "../src/commands/alert.js";
|
|
|
12
20
|
import { exportCommand } from "../src/commands/export.js";
|
|
13
21
|
import { depsCommand } from "../src/commands/deps.js";
|
|
14
22
|
import { profileCommand } from "../src/commands/profile.js";
|
|
23
|
+
import { deleteCommand } from "../src/commands/delete.js";
|
|
15
24
|
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
16
25
|
import { windowsCommand } from "../src/windows/service.js";
|
|
17
26
|
import { launchdCommand } from "../src/macos/launchd.js";
|
|
@@ -25,7 +34,7 @@ const program = new Command();
|
|
|
25
34
|
program
|
|
26
35
|
.name("bs9")
|
|
27
36
|
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
28
|
-
.version(
|
|
37
|
+
.version(version);
|
|
29
38
|
|
|
30
39
|
program
|
|
31
40
|
.command("start")
|
|
@@ -118,9 +127,20 @@ program
|
|
|
118
127
|
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
119
128
|
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
120
129
|
.option("-s, --service <name>", "Service name to profile")
|
|
121
|
-
.option("
|
|
130
|
+
.option("--flamegraph", "Generate flame graph")
|
|
131
|
+
.option("--top <number>", "Show top N functions", "10")
|
|
122
132
|
.action(profileCommand);
|
|
123
133
|
|
|
134
|
+
program
|
|
135
|
+
.command("delete")
|
|
136
|
+
.description("Delete managed services")
|
|
137
|
+
.argument("[name]", "Service name (optional)")
|
|
138
|
+
.option("-a, --all", "Delete all services")
|
|
139
|
+
.option("-f, --force", "Force deletion without errors")
|
|
140
|
+
.option("-r, --remove", "Remove service configuration files")
|
|
141
|
+
.option("-t, --timeout <seconds>", "Timeout for graceful shutdown", "30")
|
|
142
|
+
.action(deleteCommand);
|
|
143
|
+
|
|
124
144
|
program
|
|
125
145
|
.command("loadbalancer")
|
|
126
146
|
.description("Load balancer management")
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { join, dirname } from "node:path";
|
|
6
|
+
|
|
7
|
+
// Read version from package.json
|
|
8
|
+
const packageJsonPath = join(dirname(import.meta.path), '..', 'package.json');
|
|
9
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
10
|
+
const version = packageJson.version;
|
|
11
|
+
|
|
12
|
+
import { startCommand } from "../src/commands/start.js";
|
|
13
|
+
import { stopCommand } from "../src/commands/stop.js";
|
|
14
|
+
import { restartCommand } from "../src/commands/restart.js";
|
|
15
|
+
import { statusCommand } from "../src/commands/status.js";
|
|
16
|
+
import { logsCommand } from "../src/commands/logs.js";
|
|
17
|
+
import { monitCommand } from "../src/commands/monit.js";
|
|
18
|
+
import { webCommand } from "../src/commands/web.js";
|
|
19
|
+
import { alertCommand } from "../src/commands/alert.js";
|
|
20
|
+
import { exportCommand } from "../src/commands/export.js";
|
|
21
|
+
import { depsCommand } from "../src/commands/deps.js";
|
|
22
|
+
import { profileCommand } from "../src/commands/profile.js";
|
|
23
|
+
import { deleteCommand } from "../src/commands/delete.js";
|
|
24
|
+
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
25
|
+
import { windowsCommand } from "../src/windows/service.js";
|
|
26
|
+
import { launchdCommand } from "../src/macos/launchd.js";
|
|
27
|
+
import { updateCommand } from "../src/commands/update.js";
|
|
28
|
+
import { dbpoolCommand } from "../src/database/pool.js";
|
|
29
|
+
import { advancedMonitoringCommand } from "../src/monitoring/advanced.js";
|
|
30
|
+
import { consulCommand } from "../src/discovery/consul.js";
|
|
31
|
+
|
|
32
|
+
const program = new Command();
|
|
33
|
+
|
|
34
|
+
program
|
|
35
|
+
.name("bs9")
|
|
36
|
+
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
37
|
+
.version(version);
|
|
38
|
+
|
|
39
|
+
program
|
|
40
|
+
.command("start")
|
|
41
|
+
.description("Start a process with hardened systemd unit")
|
|
42
|
+
.argument("<file>", "Application file to start")
|
|
43
|
+
.option("-n, --name <name>", "Service name")
|
|
44
|
+
.option("-p, --port <port>", "Port number", "3000")
|
|
45
|
+
.option("-h, --host <host>", "Host address", "localhost")
|
|
46
|
+
.option("--https", "Use HTTPS protocol")
|
|
47
|
+
.option("-e, --env <env>", "Environment variables (can be used multiple times)", (value, previous) => [...(previous || []), value])
|
|
48
|
+
.option("--otel", "Enable OpenTelemetry instrumentation", true)
|
|
49
|
+
.option("--prometheus", "Enable Prometheus metrics", true)
|
|
50
|
+
.option("--build", "Build TypeScript to JavaScript before starting")
|
|
51
|
+
.action(startCommand);
|
|
52
|
+
|
|
53
|
+
program
|
|
54
|
+
.command("stop")
|
|
55
|
+
.description("Stop a managed service")
|
|
56
|
+
.argument("<name>", "Service name")
|
|
57
|
+
.action(stopCommand);
|
|
58
|
+
|
|
59
|
+
program
|
|
60
|
+
.command("restart")
|
|
61
|
+
.description("Restart a managed service")
|
|
62
|
+
.argument("<name>", "Service name")
|
|
63
|
+
.action(restartCommand);
|
|
64
|
+
|
|
65
|
+
program
|
|
66
|
+
.command("status")
|
|
67
|
+
.description("Show status and SRE metrics for all services")
|
|
68
|
+
.option("-w, --watch", "Watch mode (refresh every 2s)")
|
|
69
|
+
.action(statusCommand);
|
|
70
|
+
|
|
71
|
+
program
|
|
72
|
+
.command("logs")
|
|
73
|
+
.description("Show logs for a service (via journalctl)")
|
|
74
|
+
.argument("<name>", "Service name")
|
|
75
|
+
.option("-f, --follow", "Follow logs")
|
|
76
|
+
.option("-n, --lines <number>", "Number of lines", "50")
|
|
77
|
+
.action(logsCommand);
|
|
78
|
+
|
|
79
|
+
program
|
|
80
|
+
.command("monit")
|
|
81
|
+
.description("Real-time terminal dashboard for all services")
|
|
82
|
+
.option("-r, --refresh <seconds>", "Refresh interval in seconds", "2")
|
|
83
|
+
.action(monitCommand);
|
|
84
|
+
|
|
85
|
+
program
|
|
86
|
+
.command("web")
|
|
87
|
+
.description("Start web-based monitoring dashboard")
|
|
88
|
+
.option("-p, --port <port>", "Port for web dashboard", "8080")
|
|
89
|
+
.option("-d, --detach", "Run in background")
|
|
90
|
+
.action(webCommand);
|
|
91
|
+
|
|
92
|
+
program
|
|
93
|
+
.command("alert")
|
|
94
|
+
.description("Configure alert thresholds and webhooks")
|
|
95
|
+
.option("--enable", "Enable alerts")
|
|
96
|
+
.option("--disable", "Disable alerts")
|
|
97
|
+
.option("--webhook <url>", "Set webhook URL for alerts")
|
|
98
|
+
.option("--cpu <percentage>", "CPU threshold percentage")
|
|
99
|
+
.option("--memory <percentage>", "Memory threshold percentage")
|
|
100
|
+
.option("--errorRate <percentage>", "Error rate threshold percentage")
|
|
101
|
+
.option("--uptime <percentage>", "Uptime threshold percentage")
|
|
102
|
+
.option("--cooldown <seconds>", "Alert cooldown period in seconds")
|
|
103
|
+
.option("--service <name>", "Configure alerts for specific service")
|
|
104
|
+
.option("--list", "List current alert configuration")
|
|
105
|
+
.option("--test", "Test webhook connectivity")
|
|
106
|
+
.action(alertCommand);
|
|
107
|
+
|
|
108
|
+
program
|
|
109
|
+
.command("export")
|
|
110
|
+
.description("Export historical metrics data")
|
|
111
|
+
.option("-f, --format <format>", "Export format (json|csv)", "json")
|
|
112
|
+
.option("-h, --hours <hours>", "Hours of data to export", "24")
|
|
113
|
+
.option("-o, --output <file>", "Output file path")
|
|
114
|
+
.option("-s, --service <name>", "Export specific service metrics")
|
|
115
|
+
.action(exportCommand);
|
|
116
|
+
|
|
117
|
+
program
|
|
118
|
+
.command("deps")
|
|
119
|
+
.description("Visualize service dependencies")
|
|
120
|
+
.option("-f, --format <format>", "Output format (text|dot|json)", "text")
|
|
121
|
+
.option("-o, --output <file>", "Output file path")
|
|
122
|
+
.action(depsCommand);
|
|
123
|
+
|
|
124
|
+
program
|
|
125
|
+
.command("profile")
|
|
126
|
+
.description("Performance profiling for services")
|
|
127
|
+
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
128
|
+
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
129
|
+
.option("-s, --service <name>", "Service name to profile")
|
|
130
|
+
.option("--flamegraph", "Generate flame graph")
|
|
131
|
+
.option("--top <number>", "Show top N functions", "10")
|
|
132
|
+
.action(profileCommand);
|
|
133
|
+
|
|
134
|
+
program
|
|
135
|
+
.command("delete")
|
|
136
|
+
.description("Delete managed services")
|
|
137
|
+
.argument("[name]", "Service name (optional)")
|
|
138
|
+
.option("-a, --all", "Delete all services")
|
|
139
|
+
.option("-f, --force", "Force deletion without errors")
|
|
140
|
+
.option("-r, --remove", "Remove service configuration files")
|
|
141
|
+
.option("-t, --timeout <seconds>", "Timeout for graceful shutdown", "30")
|
|
142
|
+
.action(deleteCommand);
|
|
143
|
+
|
|
144
|
+
program
|
|
145
|
+
.command("loadbalancer")
|
|
146
|
+
.description("Load balancer management")
|
|
147
|
+
.argument("<action>", "Action to perform")
|
|
148
|
+
.option("-p, --port <port>", "Load balancer port", "8080")
|
|
149
|
+
.option("-a, --algorithm <type>", "Load balancing algorithm", "round-robin")
|
|
150
|
+
.option("-b, --backends <list>", "Backend servers (host:port,host:port)")
|
|
151
|
+
.option("--health-check", "Enable health checking", true)
|
|
152
|
+
.option("--health-path <path>", "Health check path", "/healthz")
|
|
153
|
+
.option("--health-interval <ms>", "Health check interval", "10000")
|
|
154
|
+
.action(loadbalancerCommand);
|
|
155
|
+
|
|
156
|
+
program
|
|
157
|
+
.command("dbpool")
|
|
158
|
+
.description("Database connection pool management")
|
|
159
|
+
.argument("<action>", "Action to perform")
|
|
160
|
+
.option("--host <host>", "Database host", "localhost")
|
|
161
|
+
.option("--port <port>", "Database port", "5432")
|
|
162
|
+
.option("--database <name>", "Database name", "testdb")
|
|
163
|
+
.option("--username <user>", "Database username", "user")
|
|
164
|
+
.option("--password <pass>", "Database password", "password")
|
|
165
|
+
.option("--max-connections <num>", "Maximum connections", "10")
|
|
166
|
+
.option("--min-connections <num>", "Minimum connections", "2")
|
|
167
|
+
.option("--concurrency <num>", "Test concurrency", "10")
|
|
168
|
+
.option("--iterations <num>", "Test iterations", "100")
|
|
169
|
+
.action(dbpoolCommand);
|
|
170
|
+
|
|
171
|
+
program
|
|
172
|
+
.command("update")
|
|
173
|
+
.description("Update BS9 to latest version")
|
|
174
|
+
.option("--check", "Check for updates without installing")
|
|
175
|
+
.option("--force", "Force update even if already latest")
|
|
176
|
+
.option("--rollback", "Rollback to previous version")
|
|
177
|
+
.option("--version <version>", "Update to specific version")
|
|
178
|
+
.action(updateCommand);
|
|
179
|
+
|
|
180
|
+
program
|
|
181
|
+
.command("advanced")
|
|
182
|
+
.description("Advanced monitoring dashboard")
|
|
183
|
+
.option("--port <port>", "Dashboard port", "8090")
|
|
184
|
+
.action(advancedMonitoringCommand);
|
|
185
|
+
|
|
186
|
+
program
|
|
187
|
+
.command("consul")
|
|
188
|
+
.description("Consul service discovery")
|
|
189
|
+
.argument("<action>", "Action to perform")
|
|
190
|
+
.option("--consul-url <url>", "Consul URL", "http://localhost:8500")
|
|
191
|
+
.option("--name <name>", "Service name")
|
|
192
|
+
.option("--id <id>", "Service ID")
|
|
193
|
+
.option("--address <address>", "Service address")
|
|
194
|
+
.option("--port <port>", "Service port")
|
|
195
|
+
.option("--tags <tags>", "Service tags (comma-separated)")
|
|
196
|
+
.option("--health-check <url>", "Health check URL")
|
|
197
|
+
.option("--meta <json>", "Service metadata (JSON)")
|
|
198
|
+
.option("--service <service>", "Service name for discovery")
|
|
199
|
+
.action(consulCommand);
|
|
200
|
+
|
|
201
|
+
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.6");
|
|
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,189 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { Command } from "commander";
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
5
|
+
import { join, dirname } from "node:path";
|
|
6
|
+
|
|
7
|
+
// Read version from package.json
|
|
8
|
+
const packageJsonPath = join(dirname(import.meta.path), '..', 'package.json');
|
|
9
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
10
|
+
const version = packageJson.version;
|
|
11
|
+
|
|
12
|
+
import { startCommand } from "../src/commands/start.js";
|
|
13
|
+
import { stopCommand } from "../src/commands/stop.js";
|
|
14
|
+
import { restartCommand } from "../src/commands/restart.js";
|
|
15
|
+
import { statusCommand } from "../src/commands/status.js";
|
|
16
|
+
import { logsCommand } from "../src/commands/logs.js";
|
|
17
|
+
import { monitCommand } from "../src/commands/monit.js";
|
|
18
|
+
import { webCommand } from "../src/commands/web.js";
|
|
19
|
+
import { alertCommand } from "../src/commands/alert.js";
|
|
20
|
+
import { exportCommand } from "../src/commands/export.js";
|
|
21
|
+
import { depsCommand } from "../src/commands/deps.js";
|
|
22
|
+
import { profileCommand } from "../src/commands/profile.js";
|
|
23
|
+
import { loadbalancerCommand } from "../src/loadbalancer/manager.js";
|
|
24
|
+
import { windowsCommand } from "../src/windows/service.js";
|
|
25
|
+
import { launchdCommand } from "../src/macos/launchd.js";
|
|
26
|
+
import { updateCommand } from "../src/commands/update.js";
|
|
27
|
+
import { dbpoolCommand } from "../src/database/pool.js";
|
|
28
|
+
import { advancedMonitoringCommand } from "../src/monitoring/advanced.js";
|
|
29
|
+
import { consulCommand } from "../src/discovery/consul.js";
|
|
30
|
+
|
|
31
|
+
const program = new Command();
|
|
32
|
+
|
|
33
|
+
program
|
|
34
|
+
.name("bs9")
|
|
35
|
+
.description("BS9 (Bun Sentinel 9) — Mission-critical process manager CLI")
|
|
36
|
+
.version(version);
|
|
37
|
+
|
|
38
|
+
program
|
|
39
|
+
.command("start")
|
|
40
|
+
.description("Start a process with hardened systemd unit")
|
|
41
|
+
.argument("<file>", "Application file to start")
|
|
42
|
+
.option("-n, --name <name>", "Service name")
|
|
43
|
+
.option("-p, --port <port>", "Port number", "3000")
|
|
44
|
+
.option("-h, --host <host>", "Host address", "localhost")
|
|
45
|
+
.option("--https", "Use HTTPS protocol")
|
|
46
|
+
.option("-e, --env <env>", "Environment variables (can be used multiple times)", (value, previous) => [...(previous || []), value])
|
|
47
|
+
.option("--otel", "Enable OpenTelemetry instrumentation", true)
|
|
48
|
+
.option("--prometheus", "Enable Prometheus metrics", true)
|
|
49
|
+
.option("--build", "Build TypeScript to JavaScript before starting")
|
|
50
|
+
.action(startCommand);
|
|
51
|
+
|
|
52
|
+
program
|
|
53
|
+
.command("stop")
|
|
54
|
+
.description("Stop a managed service")
|
|
55
|
+
.argument("<name>", "Service name")
|
|
56
|
+
.action(stopCommand);
|
|
57
|
+
|
|
58
|
+
program
|
|
59
|
+
.command("restart")
|
|
60
|
+
.description("Restart a managed service")
|
|
61
|
+
.argument("<name>", "Service name")
|
|
62
|
+
.action(restartCommand);
|
|
63
|
+
|
|
64
|
+
program
|
|
65
|
+
.command("status")
|
|
66
|
+
.description("Show status and SRE metrics for all services")
|
|
67
|
+
.option("-w, --watch", "Watch mode (refresh every 2s)")
|
|
68
|
+
.action(statusCommand);
|
|
69
|
+
|
|
70
|
+
program
|
|
71
|
+
.command("logs")
|
|
72
|
+
.description("Show logs for a service (via journalctl)")
|
|
73
|
+
.argument("<name>", "Service name")
|
|
74
|
+
.option("-f, --follow", "Follow logs")
|
|
75
|
+
.option("-n, --lines <number>", "Number of lines", "50")
|
|
76
|
+
.action(logsCommand);
|
|
77
|
+
|
|
78
|
+
program
|
|
79
|
+
.command("monit")
|
|
80
|
+
.description("Real-time terminal dashboard for all services")
|
|
81
|
+
.option("-r, --refresh <seconds>", "Refresh interval in seconds", "2")
|
|
82
|
+
.action(monitCommand);
|
|
83
|
+
|
|
84
|
+
program
|
|
85
|
+
.command("web")
|
|
86
|
+
.description("Start web-based monitoring dashboard")
|
|
87
|
+
.option("-p, --port <port>", "Port for web dashboard", "8080")
|
|
88
|
+
.option("-d, --detach", "Run in background")
|
|
89
|
+
.action(webCommand);
|
|
90
|
+
|
|
91
|
+
program
|
|
92
|
+
.command("alert")
|
|
93
|
+
.description("Configure alert thresholds and webhooks")
|
|
94
|
+
.option("--enable", "Enable alerts")
|
|
95
|
+
.option("--disable", "Disable alerts")
|
|
96
|
+
.option("--webhook <url>", "Set webhook URL for alerts")
|
|
97
|
+
.option("--cpu <percentage>", "CPU threshold percentage")
|
|
98
|
+
.option("--memory <percentage>", "Memory threshold percentage")
|
|
99
|
+
.option("--errorRate <percentage>", "Error rate threshold percentage")
|
|
100
|
+
.option("--uptime <percentage>", "Uptime threshold percentage")
|
|
101
|
+
.option("--cooldown <seconds>", "Alert cooldown period in seconds")
|
|
102
|
+
.option("--service <name>", "Configure alerts for specific service")
|
|
103
|
+
.option("--list", "List current alert configuration")
|
|
104
|
+
.option("--test", "Test webhook connectivity")
|
|
105
|
+
.action(alertCommand);
|
|
106
|
+
|
|
107
|
+
program
|
|
108
|
+
.command("export")
|
|
109
|
+
.description("Export historical metrics data")
|
|
110
|
+
.option("-f, --format <format>", "Export format (json|csv)", "json")
|
|
111
|
+
.option("-h, --hours <hours>", "Hours of data to export", "24")
|
|
112
|
+
.option("-o, --output <file>", "Output file path")
|
|
113
|
+
.option("-s, --service <name>", "Export specific service metrics")
|
|
114
|
+
.action(exportCommand);
|
|
115
|
+
|
|
116
|
+
program
|
|
117
|
+
.command("deps")
|
|
118
|
+
.description("Visualize service dependencies")
|
|
119
|
+
.option("-f, --format <format>", "Output format (text|dot|json)", "text")
|
|
120
|
+
.option("-o, --output <file>", "Output file path")
|
|
121
|
+
.action(depsCommand);
|
|
122
|
+
|
|
123
|
+
program
|
|
124
|
+
.command("profile")
|
|
125
|
+
.description("Performance profiling for services")
|
|
126
|
+
.option("-d, --duration <seconds>", "Profiling duration", "60")
|
|
127
|
+
.option("-i, --interval <ms>", "Sampling interval", "1000")
|
|
128
|
+
.option("-s, --service <name>", "Service name to profile")
|
|
129
|
+
.option("-o, --output <file>", "Output file path")
|
|
130
|
+
.action(profileCommand);
|
|
131
|
+
|
|
132
|
+
program
|
|
133
|
+
.command("loadbalancer")
|
|
134
|
+
.description("Load balancer management")
|
|
135
|
+
.argument("<action>", "Action to perform")
|
|
136
|
+
.option("-p, --port <port>", "Load balancer port", "8080")
|
|
137
|
+
.option("-a, --algorithm <type>", "Load balancing algorithm", "round-robin")
|
|
138
|
+
.option("-b, --backends <list>", "Backend servers (host:port,host:port)")
|
|
139
|
+
.option("--health-check", "Enable health checking", true)
|
|
140
|
+
.option("--health-path <path>", "Health check path", "/healthz")
|
|
141
|
+
.option("--health-interval <ms>", "Health check interval", "10000")
|
|
142
|
+
.action(loadbalancerCommand);
|
|
143
|
+
|
|
144
|
+
program
|
|
145
|
+
.command("dbpool")
|
|
146
|
+
.description("Database connection pool management")
|
|
147
|
+
.argument("<action>", "Action to perform")
|
|
148
|
+
.option("--host <host>", "Database host", "localhost")
|
|
149
|
+
.option("--port <port>", "Database port", "5432")
|
|
150
|
+
.option("--database <name>", "Database name", "testdb")
|
|
151
|
+
.option("--username <user>", "Database username", "user")
|
|
152
|
+
.option("--password <pass>", "Database password", "password")
|
|
153
|
+
.option("--max-connections <num>", "Maximum connections", "10")
|
|
154
|
+
.option("--min-connections <num>", "Minimum connections", "2")
|
|
155
|
+
.option("--concurrency <num>", "Test concurrency", "10")
|
|
156
|
+
.option("--iterations <num>", "Test iterations", "100")
|
|
157
|
+
.action(dbpoolCommand);
|
|
158
|
+
|
|
159
|
+
program
|
|
160
|
+
.command("update")
|
|
161
|
+
.description("Update BS9 to latest version")
|
|
162
|
+
.option("--check", "Check for updates without installing")
|
|
163
|
+
.option("--force", "Force update even if already latest")
|
|
164
|
+
.option("--rollback", "Rollback to previous version")
|
|
165
|
+
.option("--version <version>", "Update to specific version")
|
|
166
|
+
.action(updateCommand);
|
|
167
|
+
|
|
168
|
+
program
|
|
169
|
+
.command("advanced")
|
|
170
|
+
.description("Advanced monitoring dashboard")
|
|
171
|
+
.option("--port <port>", "Dashboard port", "8090")
|
|
172
|
+
.action(advancedMonitoringCommand);
|
|
173
|
+
|
|
174
|
+
program
|
|
175
|
+
.command("consul")
|
|
176
|
+
.description("Consul service discovery")
|
|
177
|
+
.argument("<action>", "Action to perform")
|
|
178
|
+
.option("--consul-url <url>", "Consul URL", "http://localhost:8500")
|
|
179
|
+
.option("--name <name>", "Service name")
|
|
180
|
+
.option("--id <id>", "Service ID")
|
|
181
|
+
.option("--address <address>", "Service address")
|
|
182
|
+
.option("--port <port>", "Service port")
|
|
183
|
+
.option("--tags <tags>", "Service tags (comma-separated)")
|
|
184
|
+
.option("--health-check <url>", "Health check URL")
|
|
185
|
+
.option("--meta <json>", "Service metadata (JSON)")
|
|
186
|
+
.option("--service <service>", "Service name for discovery")
|
|
187
|
+
.action(consulCommand);
|
|
188
|
+
|
|
189
|
+
program.parse();
|
package/dist/bs9.js
CHANGED
package/package.json
CHANGED
package/src/alerting/config.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
4
13
|
import { join } from "node:path";
|
|
5
14
|
import { homedir } from "node:os";
|
package/src/commands/alert.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { AlertManager } from "../alerting/config.js";
|
|
4
13
|
|
|
5
14
|
interface AlertOptions {
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { execSync } from "node:child_process";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import { getPlatformInfo } from "../platform/detect.js";
|
|
15
|
+
|
|
16
|
+
interface DeleteOptions {
|
|
17
|
+
all?: boolean;
|
|
18
|
+
force?: boolean;
|
|
19
|
+
remove?: boolean;
|
|
20
|
+
timeout?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Security: Service name validation
|
|
24
|
+
function isValidServiceName(name: string): boolean {
|
|
25
|
+
// Only allow alphanumeric, hyphens, underscores, and dots
|
|
26
|
+
// Prevent command injection and path traversal
|
|
27
|
+
const validPattern = /^[a-zA-Z0-9._-]+$/;
|
|
28
|
+
return validPattern.test(name) && name.length <= 64 && !name.includes('..') && !name.includes('/');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export async function deleteCommand(name: string, options: DeleteOptions): Promise<void> {
|
|
32
|
+
const platformInfo = getPlatformInfo();
|
|
33
|
+
|
|
34
|
+
// Handle delete all services
|
|
35
|
+
if (options.all) {
|
|
36
|
+
await deleteAllServices(platformInfo, options);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Security: Validate service name
|
|
41
|
+
if (!isValidServiceName(name)) {
|
|
42
|
+
console.error(`❌ Security: Invalid service name: ${name}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
if (platformInfo.isLinux) {
|
|
48
|
+
// Security: Use shell escaping to prevent injection
|
|
49
|
+
const escapedName = name.replace(/[^a-zA-Z0-9._-]/g, '');
|
|
50
|
+
|
|
51
|
+
// Stop the service first
|
|
52
|
+
try {
|
|
53
|
+
execSync(`systemctl --user stop "${escapedName}"`, { stdio: "inherit" });
|
|
54
|
+
} catch (error) {
|
|
55
|
+
// Service might not be running, continue with deletion
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Disable the service
|
|
59
|
+
try {
|
|
60
|
+
execSync(`systemctl --user disable "${escapedName}"`, { stdio: "inherit" });
|
|
61
|
+
} catch (error) {
|
|
62
|
+
// Service might not exist, continue
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Remove the service file if requested
|
|
66
|
+
if (options.remove) {
|
|
67
|
+
const serviceFile = join(platformInfo.serviceDir, `${escapedName}.service`);
|
|
68
|
+
try {
|
|
69
|
+
execSync(`rm -f "${serviceFile}"`, { stdio: "inherit" });
|
|
70
|
+
console.log(`🗑️ Service file removed: ${serviceFile}`);
|
|
71
|
+
} catch (error) {
|
|
72
|
+
// File might not exist, continue
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log(`🗑️ Service '${name}' deleted successfully`);
|
|
77
|
+
} else if (platformInfo.isMacOS) {
|
|
78
|
+
const { launchdCommand } = await import("../macos/launchd.js");
|
|
79
|
+
await launchdCommand('delete', { name: `bs9.${name}` });
|
|
80
|
+
|
|
81
|
+
if (options.remove) {
|
|
82
|
+
const plistFile = join(platformInfo.serviceDir, `bs9.${name}.plist`);
|
|
83
|
+
try {
|
|
84
|
+
execSync(`rm -f "${plistFile}"`, { stdio: "inherit" });
|
|
85
|
+
console.log(`🗑️ Service file removed: ${plistFile}`);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
// File might not exist, continue
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} else if (platformInfo.isWindows) {
|
|
91
|
+
const { windowsCommand } = await import("../windows/service.js");
|
|
92
|
+
await windowsCommand('delete', { name: `BS9_${name}` });
|
|
93
|
+
|
|
94
|
+
if (options.remove) {
|
|
95
|
+
// Windows service removal is handled by the windowsCommand
|
|
96
|
+
console.log(`🗑️ Windows service 'BS9_${name}' deleted`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.error(`❌ Failed to delete service '${name}': ${err}`);
|
|
101
|
+
if (!options.force) {
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function deleteAllServices(platformInfo: any, options: DeleteOptions): Promise<void> {
|
|
108
|
+
try {
|
|
109
|
+
console.log("🗑️ Deleting all BS9 services...");
|
|
110
|
+
|
|
111
|
+
if (platformInfo.isLinux) {
|
|
112
|
+
// Get all BS9 services
|
|
113
|
+
const listOutput = execSync("systemctl --user list-units --type=service --no-pager --no-legend", { encoding: "utf-8" });
|
|
114
|
+
const lines = listOutput.split("\n").filter(line => line.includes(".service"));
|
|
115
|
+
|
|
116
|
+
const bs9Services: string[] = [];
|
|
117
|
+
|
|
118
|
+
for (const line of lines) {
|
|
119
|
+
const match = line.match(/^(?:\s*([●\s○]))?\s*([^\s]+)\.service\s+([^\s]+)\s+([^\s]+)\s+(.+)$/);
|
|
120
|
+
if (match) {
|
|
121
|
+
const [, serviceName] = match;
|
|
122
|
+
|
|
123
|
+
// Only process BS9 services
|
|
124
|
+
if (match[5].includes("Bun Service:") || match[5].includes("BS9 Service:")) {
|
|
125
|
+
bs9Services.push(serviceName);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (bs9Services.length === 0) {
|
|
131
|
+
console.log("ℹ️ No BS9 services found to delete");
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
console.log(`Found ${bs9Services.length} BS9 services to delete...`);
|
|
136
|
+
|
|
137
|
+
for (const serviceName of bs9Services) {
|
|
138
|
+
try {
|
|
139
|
+
// Stop the service
|
|
140
|
+
execSync(`systemctl --user stop "${serviceName}"`, { stdio: "inherit" });
|
|
141
|
+
|
|
142
|
+
// Disable the service
|
|
143
|
+
execSync(`systemctl --user disable "${serviceName}"`, { stdio: "inherit" });
|
|
144
|
+
|
|
145
|
+
// Remove service file if requested
|
|
146
|
+
if (options.remove) {
|
|
147
|
+
const serviceFile = join(platformInfo.serviceDir, `${serviceName}.service`);
|
|
148
|
+
execSync(`rm -f "${serviceFile}"`, { stdio: "inherit" });
|
|
149
|
+
console.log(` 🗑️ Deleted service file: ${serviceName}`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(` 🗑️ Deleted service: ${serviceName}`);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error(` ⚠️ Failed to delete service '${serviceName}': ${error}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
} else if (platformInfo.isMacOS) {
|
|
159
|
+
// For macOS, we would need to list all launchd agents
|
|
160
|
+
// This is more complex, so for now we'll provide a message
|
|
161
|
+
console.log("📝 To delete all services on macOS, you need to manually remove the plist files from:");
|
|
162
|
+
console.log(` ${platformInfo.serviceDir}/bs9.*.plist`);
|
|
163
|
+
console.log(" And then run: launchctl unload ~/Library/LaunchAgents/bs9.*.plist");
|
|
164
|
+
} else if (platformInfo.isWindows) {
|
|
165
|
+
// For Windows, we would need to query all BS9 services
|
|
166
|
+
// This is more complex, so for now we'll provide a message
|
|
167
|
+
console.log("📝 To delete all services on Windows, use PowerShell:");
|
|
168
|
+
console.log(" Get-Service -Name \"BS9_*\" | ForEach-Object { Stop-Service $_.Name; Remove-Service $_.Name }");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log(`✅ All BS9 services deletion process completed`);
|
|
172
|
+
} catch (err) {
|
|
173
|
+
console.error(`❌ Failed to delete all services: ${err}`);
|
|
174
|
+
if (!options.force) {
|
|
175
|
+
process.exit(1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
package/src/commands/deps.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { setTimeout } from "node:timers/promises";
|
|
5
14
|
|
package/src/commands/export.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { MetricsStorage } from "../storage/metrics.js";
|
|
4
13
|
import { writeFileSync } from "node:fs";
|
|
5
14
|
|
package/src/commands/logs.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
|
|
5
14
|
interface LogsOptions {
|
package/src/commands/monit.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { setTimeout } from "node:timers/promises";
|
|
5
14
|
|
package/src/commands/profile.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { setTimeout } from "node:timers/promises";
|
|
5
14
|
|
package/src/commands/restart.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { getPlatformInfo } from "../platform/detect.js";
|
|
5
14
|
|
package/src/commands/start.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
4
13
|
import { join, basename, resolve, dirname } from "node:path";
|
|
5
14
|
import { execSync } from "node:child_process";
|
package/src/commands/status.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { getPlatformInfo } from "../platform/detect.js";
|
|
5
14
|
import { readFileSync } from "node:fs";
|
package/src/commands/stop.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { join } from "node:path";
|
|
5
14
|
import { getPlatformInfo } from "../platform/detect.js";
|
package/src/commands/update.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { existsSync, writeFileSync, mkdirSync } from "node:fs";
|
|
5
14
|
import { join, dirname } from "node:path";
|
package/src/commands/web.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { spawn } from "node:child_process";
|
|
5
14
|
import { randomBytes } from "node:crypto";
|
package/src/database/pool.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
// Security: Input validation functions
|
|
4
13
|
function isValidHost(host: string): boolean {
|
|
5
14
|
const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/;
|
package/src/discovery/consul.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
|
|
5
14
|
interface ConsulService {
|
package/src/injectors/otel.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { writeFileSync, readFileSync, existsSync } from "node:fs";
|
|
4
13
|
import { join, dirname } from "node:path";
|
|
5
14
|
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { serve } from "bun";
|
|
4
13
|
import { setTimeout } from "node:timers/promises";
|
|
5
14
|
|
package/src/macos/launchd.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { existsSync, writeFileSync, mkdirSync } from "node:fs";
|
|
5
14
|
import { join, dirname } from "node:path";
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { serve } from "bun";
|
|
4
13
|
import { randomBytes } from "node:crypto";
|
|
5
14
|
|
package/src/platform/detect.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { platform } from "node:os";
|
|
4
13
|
|
|
5
14
|
export type Platform = 'linux' | 'darwin' | 'win32';
|
package/src/storage/metrics.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { writeFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
|
|
4
13
|
import { join } from "node:path";
|
|
5
14
|
import { homedir } from "node:os";
|
package/src/web/dashboard.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { serve } from "bun";
|
|
4
13
|
import { execSync } from "node:child_process";
|
|
5
14
|
import { join } from "node:path";
|
package/src/windows/service.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* BS9 - Bun Sentinel 9
|
|
5
|
+
* High-performance, non-root process manager for Bun
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2026 BS9 (Bun Sentinel 9)
|
|
8
|
+
* Licensed under the MIT License
|
|
9
|
+
* https://github.com/xarhang/bs9
|
|
10
|
+
*/
|
|
11
|
+
|
|
3
12
|
import { execSync } from "node:child_process";
|
|
4
13
|
import { existsSync, writeFileSync, mkdirSync } from "node:fs";
|
|
5
14
|
import { join, dirname } from "node:path";
|