mbai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/mbai.js +335 -0
  2. package/package.json +31 -0
package/bin/mbai.js ADDED
@@ -0,0 +1,335 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync, spawn } = require('child_process');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const https = require('https');
7
+ const os = require('os');
8
+ const crypto = require('crypto');
9
+
10
+ const BINARY_BASE_URL = 'https://managedbyai.dev/bin';
11
+ const RELAY_URL = 'wss://atlas-ws.managedbyai.dev';
12
+ const CONFIG_DIR = '/etc/atlas';
13
+ const CONFIG_FILE = path.join(CONFIG_DIR, 'config.yaml');
14
+ const BINARY_PATH = '/usr/local/bin/atlas-agent';
15
+ const SERVICE_NAME = 'atlas-agent';
16
+ const TRIAL_DAYS = 30;
17
+
18
+ function checkRoot() {
19
+ if (process.getuid() !== 0) {
20
+ console.error('Error: This command requires root privileges.');
21
+ console.error('Run with: sudo mbai <command>');
22
+ process.exit(1);
23
+ }
24
+ }
25
+
26
+ function getFingerprint() {
27
+ const parts = [];
28
+
29
+ // Machine ID
30
+ try {
31
+ const machineId = fs.readFileSync('/etc/machine-id', 'utf8').trim();
32
+ parts.push(machineId);
33
+ } catch (e) {}
34
+
35
+ // Hostname
36
+ parts.push(os.hostname());
37
+
38
+ // Combine and hash
39
+ const combined = parts.join('-');
40
+ const hash = crypto.createHash('sha256').update(combined).digest('hex').slice(0, 16);
41
+ return `atlas-${hash}`;
42
+ }
43
+
44
+ function getBinaryName() {
45
+ const platform = os.platform();
46
+ let arch = os.arch();
47
+
48
+ // Map architecture
49
+ if (arch === 'x64') arch = 'amd64';
50
+ if (arch === 'arm64' || arch === 'aarch64') arch = 'arm64';
51
+
52
+ if (platform === 'darwin') {
53
+ return `atlas-agent-darwin-${arch}`;
54
+ } else if (platform === 'linux') {
55
+ return `atlas-agent-linux-${arch}`;
56
+ } else {
57
+ throw new Error(`Unsupported platform: ${platform}/${arch}`);
58
+ }
59
+ }
60
+
61
+ function downloadFile(url, dest) {
62
+ return new Promise((resolve, reject) => {
63
+ const file = fs.createWriteStream(dest);
64
+ https.get(url, (response) => {
65
+ if (response.statusCode === 301 || response.statusCode === 302) {
66
+ // Follow redirect
67
+ https.get(response.headers.location, (res) => {
68
+ res.pipe(file);
69
+ file.on('finish', () => {
70
+ file.close();
71
+ resolve();
72
+ });
73
+ }).on('error', reject);
74
+ } else {
75
+ response.pipe(file);
76
+ file.on('finish', () => {
77
+ file.close();
78
+ resolve();
79
+ });
80
+ }
81
+ }).on('error', reject);
82
+ });
83
+ }
84
+
85
+ async function cmdSetup() {
86
+ checkRoot();
87
+
88
+ console.log('='.repeat(50));
89
+ console.log(' ATLAS - AI-Powered Server Monitoring');
90
+ console.log(' 30-day free trial. No credit card required.');
91
+ console.log('='.repeat(50));
92
+ console.log();
93
+
94
+ const fingerprint = getFingerprint();
95
+ console.log(`Server ID: ${fingerprint}`);
96
+
97
+ // Stop existing service if running
98
+ try {
99
+ const result = execSync('systemctl is-active atlas-agent 2>/dev/null', { encoding: 'utf8' }).trim();
100
+ if (result === 'active') {
101
+ console.log('\nStopping existing Atlas service...');
102
+ execSync('systemctl stop atlas-agent', { stdio: 'inherit' });
103
+ }
104
+ } catch (e) {}
105
+
106
+ // Create directories
107
+ console.log('\nCreating directories...');
108
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
109
+ fs.mkdirSync('/var/atlas/snapshots', { recursive: true });
110
+ fs.mkdirSync('/usr/local/bin', { recursive: true });
111
+
112
+ // Download binary
113
+ const binaryName = getBinaryName();
114
+ const binaryUrl = `${BINARY_BASE_URL}/${binaryName}`;
115
+ console.log(`Downloading Atlas agent (${binaryName})...`);
116
+
117
+ try {
118
+ await downloadFile(binaryUrl, BINARY_PATH);
119
+ fs.chmodSync(BINARY_PATH, 0o755);
120
+ console.log(` Installed: ${BINARY_PATH}`);
121
+ } catch (e) {
122
+ console.error(`Error downloading binary: ${e.message}`);
123
+ process.exit(1);
124
+ }
125
+
126
+ // Download auto-discover script
127
+ const discoverUrl = `${BINARY_BASE_URL}/auto-discover.sh`;
128
+ const discoverPath = '/usr/local/bin/atlas-discover';
129
+
130
+ try {
131
+ await downloadFile(discoverUrl, discoverPath);
132
+ fs.chmodSync(discoverPath, 0o755);
133
+ console.log(` Installed: ${discoverPath}`);
134
+ } catch (e) {
135
+ console.log(' Warning: Could not download auto-discover script');
136
+ }
137
+
138
+ // Generate config
139
+ console.log('\nGenerating configuration...');
140
+
141
+ // Run auto-discovery if available
142
+ if (fs.existsSync(discoverPath)) {
143
+ console.log('Running service discovery...');
144
+ try {
145
+ execSync(`${discoverPath} ${CONFIG_FILE} "" "${RELAY_URL}"`, { stdio: 'inherit' });
146
+ } catch (e) {}
147
+ }
148
+
149
+ // Create basic config if discovery didn't create one
150
+ if (!fs.existsSync(CONFIG_FILE)) {
151
+ const config = `# Atlas Agent Configuration
152
+ server_id: "${fingerprint}"
153
+ relay_url: "${RELAY_URL}"
154
+ trial_start: ${Math.floor(Date.now() / 1000)}
155
+ trial_days: ${TRIAL_DAYS}
156
+ hostname: "${os.hostname()}"
157
+
158
+ metrics:
159
+ enabled: true
160
+ interval_seconds: 30
161
+
162
+ log_watcher:
163
+ enabled: true
164
+ paths:
165
+ - /var/log/syslog
166
+ - /var/log/messages
167
+
168
+ playbooks:
169
+ enabled: true
170
+ `;
171
+ fs.writeFileSync(CONFIG_FILE, config);
172
+ }
173
+
174
+ console.log(` Config: ${CONFIG_FILE}`);
175
+
176
+ // Create systemd service
177
+ console.log('\nCreating systemd service...');
178
+ const serviceContent = `[Unit]
179
+ Description=Atlas Agent - AI-Powered Server Monitoring
180
+ Documentation=https://managedbyai.dev
181
+ After=network-online.target
182
+ Wants=network-online.target
183
+
184
+ [Service]
185
+ Type=simple
186
+ User=root
187
+ Group=root
188
+ ExecStart=${BINARY_PATH} daemon -c ${CONFIG_FILE}
189
+ Restart=always
190
+ RestartSec=10
191
+ Environment=ATLAS_SNAPSHOT_DIR=/var/atlas/snapshots
192
+ StandardOutput=journal
193
+ StandardError=journal
194
+ SyslogIdentifier=atlas-agent
195
+ LimitNOFILE=65536
196
+ LimitNPROC=4096
197
+
198
+ [Install]
199
+ WantedBy=multi-user.target
200
+ `;
201
+
202
+ fs.writeFileSync(`/etc/systemd/system/${SERVICE_NAME}.service`, serviceContent);
203
+ execSync('systemctl daemon-reload');
204
+ execSync(`systemctl enable ${SERVICE_NAME}`);
205
+
206
+ console.log();
207
+ console.log('='.repeat(50));
208
+ console.log(' SETUP COMPLETE');
209
+ console.log('='.repeat(50));
210
+ console.log();
211
+ console.log(`Server ID: ${fingerprint}`);
212
+ console.log();
213
+ console.log('Next steps:');
214
+ console.log(' 1. Start monitoring: sudo mbai start');
215
+ console.log(' 2. Check status: sudo mbai status');
216
+ console.log(' 3. View logs: sudo mbai logs');
217
+ console.log();
218
+ console.log(`Trial: ${TRIAL_DAYS} days free. Claim at https://managedbyai.dev/dashboard`);
219
+ console.log();
220
+ }
221
+
222
+ function cmdStart() {
223
+ checkRoot();
224
+
225
+ if (!fs.existsSync(BINARY_PATH)) {
226
+ console.error("Error: Atlas not installed. Run 'sudo mbai setup' first.");
227
+ process.exit(1);
228
+ }
229
+
230
+ console.log('Starting Atlas agent...');
231
+ execSync(`systemctl start ${SERVICE_NAME}`, { stdio: 'inherit' });
232
+
233
+ // Wait a moment then show status
234
+ setTimeout(() => {
235
+ execSync(`systemctl status ${SERVICE_NAME} --no-pager`, { stdio: 'inherit' });
236
+ }, 2000);
237
+ }
238
+
239
+ function cmdStop() {
240
+ checkRoot();
241
+ console.log('Stopping Atlas agent...');
242
+ execSync(`systemctl stop ${SERVICE_NAME}`, { stdio: 'inherit' });
243
+ console.log('Stopped.');
244
+ }
245
+
246
+ function cmdStatus() {
247
+ try {
248
+ execSync(`systemctl status ${SERVICE_NAME} --no-pager`, { stdio: 'inherit' });
249
+ } catch (e) {}
250
+ }
251
+
252
+ function cmdLogs() {
253
+ const lines = process.argv[3] || '50';
254
+ execSync(`journalctl -u ${SERVICE_NAME} -n ${lines} --no-pager`, { stdio: 'inherit' });
255
+ }
256
+
257
+ function cmdUninstall() {
258
+ checkRoot();
259
+
260
+ console.log('Stopping Atlas agent...');
261
+ try {
262
+ execSync(`systemctl stop ${SERVICE_NAME}`, { stdio: 'pipe' });
263
+ execSync(`systemctl disable ${SERVICE_NAME}`, { stdio: 'pipe' });
264
+ } catch (e) {}
265
+
266
+ console.log('Removing files...');
267
+ const filesToRemove = [
268
+ BINARY_PATH,
269
+ '/usr/local/bin/atlas-discover',
270
+ `/etc/systemd/system/${SERVICE_NAME}.service`
271
+ ];
272
+
273
+ for (const f of filesToRemove) {
274
+ if (fs.existsSync(f)) {
275
+ fs.unlinkSync(f);
276
+ console.log(` Removed: ${f}`);
277
+ }
278
+ }
279
+
280
+ console.log();
281
+ console.log('Uninstalled. Config preserved at /etc/atlas/');
282
+ console.log('To fully remove: sudo rm -rf /etc/atlas /var/atlas');
283
+ }
284
+
285
+ function showHelp() {
286
+ console.log(`
287
+ Atlas Agent - AI-powered server monitoring
288
+
289
+ Usage: mbai <command>
290
+
291
+ Commands:
292
+ setup Download binary, generate config (run first)
293
+ start Start the monitoring daemon
294
+ stop Stop the daemon
295
+ status Check daemon status
296
+ logs View recent logs
297
+ uninstall Remove Atlas agent
298
+
299
+ 30-day free trial. No API key required.
300
+ https://managedbyai.dev
301
+ `);
302
+ }
303
+
304
+ // Main
305
+ const command = process.argv[2];
306
+
307
+ switch (command) {
308
+ case 'setup':
309
+ cmdSetup();
310
+ break;
311
+ case 'start':
312
+ cmdStart();
313
+ break;
314
+ case 'stop':
315
+ cmdStop();
316
+ break;
317
+ case 'status':
318
+ cmdStatus();
319
+ break;
320
+ case 'logs':
321
+ cmdLogs();
322
+ break;
323
+ case 'uninstall':
324
+ cmdUninstall();
325
+ break;
326
+ case '--help':
327
+ case '-h':
328
+ case undefined:
329
+ showHelp();
330
+ break;
331
+ default:
332
+ console.error(`Unknown command: ${command}`);
333
+ showHelp();
334
+ process.exit(1);
335
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "mbai",
3
+ "version": "0.1.0",
4
+ "description": "AI-powered server monitoring that automatically fixes issues",
5
+ "bin": {
6
+ "mbai": "./bin/mbai.js"
7
+ },
8
+ "keywords": [
9
+ "server",
10
+ "monitoring",
11
+ "devops",
12
+ "automation",
13
+ "ai",
14
+ "self-healing",
15
+ "atlas"
16
+ ],
17
+ "author": "ManagedByAI <support@managedbyai.dev>",
18
+ "license": "MIT",
19
+ "homepage": "https://managedbyai.dev",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/managedbyai/atlas-agent"
23
+ },
24
+ "engines": {
25
+ "node": ">=14.0.0"
26
+ },
27
+ "os": [
28
+ "linux",
29
+ "darwin"
30
+ ]
31
+ }