fluxy-bot 0.5.34 → 0.5.38
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/cli.js +84 -35
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawn, execSync, spawnSync } from 'child_process';
|
|
4
|
-
import readline from 'readline';
|
|
5
4
|
import fs from 'fs';
|
|
6
5
|
import path from 'path';
|
|
7
6
|
import os from 'os';
|
|
@@ -81,16 +80,6 @@ WantedBy=multi-user.target
|
|
|
81
80
|
`;
|
|
82
81
|
}
|
|
83
82
|
|
|
84
|
-
function askQuestion(query) {
|
|
85
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
86
|
-
return new Promise((resolve) => {
|
|
87
|
-
rl.question(query, (answer) => {
|
|
88
|
-
rl.close();
|
|
89
|
-
resolve(answer);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
|
|
94
83
|
// ── UI helpers ──
|
|
95
84
|
|
|
96
85
|
const c = {
|
|
@@ -215,10 +204,28 @@ function finalMessage(tunnelUrl, relayUrl) {
|
|
|
215
204
|
${c.pink}${c.bold}${link(relayUrl)}${c.reset}`);
|
|
216
205
|
}
|
|
217
206
|
|
|
218
|
-
|
|
207
|
+
if (os.platform() === 'linux') {
|
|
208
|
+
console.log(`
|
|
219
209
|
${c.dim}─────────────────────────────────${c.reset}
|
|
220
|
-
|
|
210
|
+
|
|
211
|
+
${c.bold}${c.white}Commands:${c.reset}
|
|
212
|
+
${c.dim}Status${c.reset} ${c.pink}fluxy daemon status${c.reset}
|
|
213
|
+
${c.dim}Logs${c.reset} ${c.pink}fluxy daemon logs${c.reset}
|
|
214
|
+
${c.dim}Restart${c.reset} ${c.pink}fluxy daemon restart${c.reset}
|
|
215
|
+
${c.dim}Stop${c.reset} ${c.pink}fluxy daemon stop${c.reset}
|
|
216
|
+
${c.dim}Update${c.reset} ${c.pink}fluxy update${c.reset}
|
|
221
217
|
`);
|
|
218
|
+
} else {
|
|
219
|
+
console.log(`
|
|
220
|
+
${c.dim}─────────────────────────────────${c.reset}
|
|
221
|
+
|
|
222
|
+
${c.bold}${c.white}Commands:${c.reset}
|
|
223
|
+
${c.dim}Status${c.reset} ${c.pink}fluxy status${c.reset}
|
|
224
|
+
${c.dim}Update${c.reset} ${c.pink}fluxy update${c.reset}
|
|
225
|
+
|
|
226
|
+
${c.dim}Press Ctrl+C to stop${c.reset}
|
|
227
|
+
`);
|
|
228
|
+
}
|
|
222
229
|
}
|
|
223
230
|
|
|
224
231
|
// ── Steps ──
|
|
@@ -381,6 +388,9 @@ async function init() {
|
|
|
381
388
|
|
|
382
389
|
createConfig();
|
|
383
390
|
|
|
391
|
+
const isLinux = os.platform() === 'linux';
|
|
392
|
+
const hasSystemd = isLinux && (() => { try { execSync('systemctl --version', { stdio: 'ignore' }); return true; } catch { return false; } })();
|
|
393
|
+
|
|
384
394
|
const steps = [
|
|
385
395
|
'Creating config',
|
|
386
396
|
'Installing cloudflared',
|
|
@@ -388,6 +398,7 @@ async function init() {
|
|
|
388
398
|
'Connecting tunnel',
|
|
389
399
|
'Verifying connection',
|
|
390
400
|
'Preparing dashboard',
|
|
401
|
+
...(hasSystemd ? ['Setting up auto-start daemon'] : []),
|
|
391
402
|
];
|
|
392
403
|
|
|
393
404
|
const stepper = new Stepper(steps);
|
|
@@ -419,28 +430,32 @@ async function init() {
|
|
|
419
430
|
await Promise.race([viteWarm, new Promise(r => setTimeout(r, 30_000))]);
|
|
420
431
|
stepper.advance();
|
|
421
432
|
|
|
433
|
+
// Install systemd daemon on Linux
|
|
434
|
+
if (hasSystemd) {
|
|
435
|
+
child.removeAllListeners('exit');
|
|
436
|
+
child.kill('SIGTERM');
|
|
437
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
438
|
+
const nodePath = process.execPath;
|
|
439
|
+
const realHome = os.homedir();
|
|
440
|
+
const res = spawnSync(process.execPath, [process.argv[1], 'daemon', 'install'], {
|
|
441
|
+
stdio: 'pipe',
|
|
442
|
+
env: { ...process.env, FLUXY_NODE_PATH: nodePath, FLUXY_REAL_HOME: realHome },
|
|
443
|
+
});
|
|
444
|
+
stepper.advance();
|
|
445
|
+
stepper.finish();
|
|
446
|
+
finalMessage(tunnelUrl, relayUrl);
|
|
447
|
+
if (res.status === 0) {
|
|
448
|
+
console.log(` ${c.blue}✔${c.reset} Daemon installed — Fluxy will auto-start on boot.`);
|
|
449
|
+
} else {
|
|
450
|
+
console.log(` ${c.yellow}⚠${c.reset} Daemon install failed. Run ${c.pink}fluxy daemon install${c.reset} manually.`);
|
|
451
|
+
}
|
|
452
|
+
console.log('');
|
|
453
|
+
process.exit(res.status ?? 0);
|
|
454
|
+
}
|
|
455
|
+
|
|
422
456
|
stepper.finish();
|
|
423
457
|
finalMessage(tunnelUrl, relayUrl);
|
|
424
458
|
|
|
425
|
-
// Offer daemon install on Linux
|
|
426
|
-
if (os.platform() === 'linux' && process.stdin.isTTY) {
|
|
427
|
-
try {
|
|
428
|
-
const answer = await askQuestion(` ${c.bold}Install as a system daemon (auto-start on boot)?${c.reset} ${c.dim}[Y/n]${c.reset} `);
|
|
429
|
-
if (!answer || answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
|
430
|
-
console.log(`\n ${c.dim}Stopping foreground server...${c.reset}`);
|
|
431
|
-
child.kill('SIGTERM');
|
|
432
|
-
await new Promise((r) => setTimeout(r, 2000));
|
|
433
|
-
const nodePath = process.execPath;
|
|
434
|
-
const realHome = os.homedir();
|
|
435
|
-
const result = spawnSync(process.execPath, [process.argv[1], 'daemon', 'install'], {
|
|
436
|
-
stdio: 'inherit',
|
|
437
|
-
env: { ...process.env, FLUXY_NODE_PATH: nodePath, FLUXY_REAL_HOME: realHome },
|
|
438
|
-
});
|
|
439
|
-
process.exit(result.status ?? 0);
|
|
440
|
-
}
|
|
441
|
-
} catch {}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
459
|
child.stdout.on('data', (d) => {
|
|
445
460
|
process.stdout.write(` ${c.dim}${d.toString().trim()}${c.reset}\n`);
|
|
446
461
|
});
|
|
@@ -456,9 +471,20 @@ async function start() {
|
|
|
456
471
|
return init();
|
|
457
472
|
}
|
|
458
473
|
|
|
474
|
+
const isLinux = os.platform() === 'linux';
|
|
475
|
+
const hasSystemd = isLinux && (() => { try { execSync('systemctl --version', { stdio: 'ignore' }); return true; } catch { return false; } })();
|
|
476
|
+
const needsDaemon = hasSystemd && !isServiceInstalled();
|
|
477
|
+
|
|
459
478
|
banner();
|
|
460
479
|
|
|
461
|
-
const steps = [
|
|
480
|
+
const steps = [
|
|
481
|
+
'Loading config',
|
|
482
|
+
'Starting server',
|
|
483
|
+
'Connecting tunnel',
|
|
484
|
+
'Verifying connection',
|
|
485
|
+
'Preparing dashboard',
|
|
486
|
+
...(needsDaemon ? ['Setting up auto-start daemon'] : []),
|
|
487
|
+
];
|
|
462
488
|
const stepper = new Stepper(steps);
|
|
463
489
|
stepper.start();
|
|
464
490
|
|
|
@@ -482,6 +508,29 @@ async function start() {
|
|
|
482
508
|
await Promise.race([viteWarm, new Promise(r => setTimeout(r, 30_000))]);
|
|
483
509
|
stepper.advance();
|
|
484
510
|
|
|
511
|
+
// Install systemd daemon on Linux if not already installed
|
|
512
|
+
if (needsDaemon) {
|
|
513
|
+
child.removeAllListeners('exit');
|
|
514
|
+
child.kill('SIGTERM');
|
|
515
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
516
|
+
const nodePath = process.execPath;
|
|
517
|
+
const realHome = os.homedir();
|
|
518
|
+
const res = spawnSync(process.execPath, [process.argv[1], 'daemon', 'install'], {
|
|
519
|
+
stdio: 'pipe',
|
|
520
|
+
env: { ...process.env, FLUXY_NODE_PATH: nodePath, FLUXY_REAL_HOME: realHome },
|
|
521
|
+
});
|
|
522
|
+
stepper.advance();
|
|
523
|
+
stepper.finish();
|
|
524
|
+
finalMessage(tunnelUrl, relayUrl);
|
|
525
|
+
if (res.status === 0) {
|
|
526
|
+
console.log(` ${c.blue}✔${c.reset} Daemon installed — Fluxy will auto-start on boot.`);
|
|
527
|
+
} else {
|
|
528
|
+
console.log(` ${c.yellow}⚠${c.reset} Daemon install failed. Run ${c.pink}fluxy daemon install${c.reset} manually.`);
|
|
529
|
+
}
|
|
530
|
+
console.log('');
|
|
531
|
+
process.exit(res.status ?? 0);
|
|
532
|
+
}
|
|
533
|
+
|
|
485
534
|
stepper.finish();
|
|
486
535
|
finalMessage(tunnelUrl, relayUrl);
|
|
487
536
|
|
|
@@ -500,14 +549,14 @@ async function status() {
|
|
|
500
549
|
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf-8'));
|
|
501
550
|
const res = await fetch(`http://localhost:${config.port}/api/health`);
|
|
502
551
|
const data = await res.json();
|
|
503
|
-
console.log(`\n ${c.blue}●${c.reset}
|
|
552
|
+
console.log(`\n ${c.blue}●${c.reset} Fluxy is running`);
|
|
504
553
|
console.log(` ${c.dim}Uptime: ${data.uptime}s${c.reset}`);
|
|
505
554
|
if (config.relay?.url) {
|
|
506
555
|
console.log(` ${c.dim}URL: ${c.reset}${c.pink}${link(config.relay.url)}${c.reset}`);
|
|
507
556
|
}
|
|
508
557
|
console.log(` ${c.dim}Config: ${CONFIG_PATH}${c.reset}\n`);
|
|
509
558
|
} catch {
|
|
510
|
-
console.log(`\n ${c.dim}●${c.reset}
|
|
559
|
+
console.log(`\n ${c.dim}●${c.reset} Fluxy is not running.\n`);
|
|
511
560
|
}
|
|
512
561
|
}
|
|
513
562
|
|