@webmux/agent 0.1.0 → 0.1.1
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/dist/cli.js +105 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
+
import fs2 from "fs";
|
|
4
5
|
import os2 from "os";
|
|
6
|
+
import path2 from "path";
|
|
7
|
+
import { execSync } from "child_process";
|
|
5
8
|
import { Command } from "commander";
|
|
6
9
|
|
|
7
10
|
// src/credentials.ts
|
|
@@ -165,9 +168,9 @@ function assertValidSessionName(name) {
|
|
|
165
168
|
function parseSessionList(stdout) {
|
|
166
169
|
return stdout.split("\n").map((line) => line.trim()).filter(Boolean).flatMap((line) => {
|
|
167
170
|
const parts = line.split(FIELD_SEPARATOR);
|
|
168
|
-
const [name, windows, attachedClients, createdAt, lastActivityAt,
|
|
171
|
+
const [name, windows, attachedClients, createdAt, lastActivityAt, path3] = parts;
|
|
169
172
|
const currentCommand = parts[6] ?? "";
|
|
170
|
-
if (!name || !windows || !attachedClients || !createdAt || !lastActivityAt || !
|
|
173
|
+
if (!name || !windows || !attachedClients || !createdAt || !lastActivityAt || !path3) {
|
|
171
174
|
return [];
|
|
172
175
|
}
|
|
173
176
|
return [
|
|
@@ -177,7 +180,7 @@ function parseSessionList(stdout) {
|
|
|
177
180
|
attachedClients: Number(attachedClients),
|
|
178
181
|
createdAt: Number(createdAt),
|
|
179
182
|
lastActivityAt: Number(lastActivityAt),
|
|
180
|
-
path:
|
|
183
|
+
path: path3,
|
|
181
184
|
currentCommand
|
|
182
185
|
}
|
|
183
186
|
];
|
|
@@ -477,6 +480,7 @@ function buildWsUrl(serverUrl) {
|
|
|
477
480
|
}
|
|
478
481
|
|
|
479
482
|
// src/cli.ts
|
|
483
|
+
var SERVICE_NAME = "webmux-agent";
|
|
480
484
|
var program = new Command();
|
|
481
485
|
program.name("webmux-agent").description("Webmux agent \u2014 connects your machine to the webmux server").version("0.0.0");
|
|
482
486
|
program.command("register").description("Register this agent with a webmux server").requiredOption("--server <url>", "Server URL (e.g. https://webmux.example.com)").requiredOption("--token <token>", "One-time registration token from the server").option("--name <name>", "Display name for this agent (defaults to hostname)").action(async (opts) => {
|
|
@@ -521,13 +525,16 @@ program.command("register").description("Register this agent with a webmux serve
|
|
|
521
525
|
console.log(`[agent] Registration successful!`);
|
|
522
526
|
console.log(`[agent] Agent ID: ${result.agentId}`);
|
|
523
527
|
console.log(`[agent] Credentials saved to ${credentialsPath()}`);
|
|
524
|
-
console.log(
|
|
528
|
+
console.log(``);
|
|
529
|
+
console.log(`Next steps:`);
|
|
530
|
+
console.log(` npx @webmux/agent start # run once`);
|
|
531
|
+
console.log(` npx @webmux/agent service install # install as systemd service`);
|
|
525
532
|
});
|
|
526
533
|
program.command("start").description("Start the agent and connect to the server").action(() => {
|
|
527
534
|
const creds = loadCredentials();
|
|
528
535
|
if (!creds) {
|
|
529
536
|
console.error(
|
|
530
|
-
`[agent] No credentials found at ${credentialsPath()}. Run "webmux
|
|
537
|
+
`[agent] No credentials found at ${credentialsPath()}. Run "npx @webmux/agent register" first.`
|
|
531
538
|
);
|
|
532
539
|
process.exit(1);
|
|
533
540
|
}
|
|
@@ -536,7 +543,7 @@ program.command("start").description("Start the agent and connect to the server"
|
|
|
536
543
|
console.log(`[agent] Agent ID: ${creds.agentId}`);
|
|
537
544
|
const tmux = new TmuxClient({
|
|
538
545
|
socketName: "webmux",
|
|
539
|
-
workspaceRoot:
|
|
546
|
+
workspaceRoot: os2.homedir()
|
|
540
547
|
});
|
|
541
548
|
const connection = new AgentConnection(
|
|
542
549
|
creds.serverUrl,
|
|
@@ -563,5 +570,97 @@ program.command("status").description("Show agent status and credentials info").
|
|
|
563
570
|
console.log(`Server URL: ${creds.serverUrl}`);
|
|
564
571
|
console.log(`Agent ID: ${creds.agentId}`);
|
|
565
572
|
console.log(`Credentials File: ${credentialsPath()}`);
|
|
573
|
+
try {
|
|
574
|
+
const result = execSync(`systemctl --user is-active ${SERVICE_NAME} 2>/dev/null`, { encoding: "utf-8" }).trim();
|
|
575
|
+
console.log(`Service: ${result}`);
|
|
576
|
+
} catch {
|
|
577
|
+
console.log(`Service: not installed`);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
var service = program.command("service").description("Manage the systemd service");
|
|
581
|
+
service.command("install").description("Install and start the agent as a systemd user service").action(() => {
|
|
582
|
+
const creds = loadCredentials();
|
|
583
|
+
if (!creds) {
|
|
584
|
+
console.error(`[agent] Not registered. Run "npx @webmux/agent register" first.`);
|
|
585
|
+
process.exit(1);
|
|
586
|
+
}
|
|
587
|
+
const npxPath = findBinary("npx");
|
|
588
|
+
if (!npxPath) {
|
|
589
|
+
console.error(`[agent] Cannot find npx. Make sure Node.js is installed.`);
|
|
590
|
+
process.exit(1);
|
|
591
|
+
}
|
|
592
|
+
const serviceDir = path2.join(os2.homedir(), ".config", "systemd", "user");
|
|
593
|
+
const servicePath = path2.join(serviceDir, `${SERVICE_NAME}.service`);
|
|
594
|
+
const unit = `[Unit]
|
|
595
|
+
Description=Webmux Agent (${creds.name})
|
|
596
|
+
After=network-online.target
|
|
597
|
+
Wants=network-online.target
|
|
598
|
+
|
|
599
|
+
[Service]
|
|
600
|
+
Type=simple
|
|
601
|
+
ExecStart=${npxPath} -y @webmux/agent start
|
|
602
|
+
Restart=always
|
|
603
|
+
RestartSec=5
|
|
604
|
+
Environment=HOME=${os2.homedir()}
|
|
605
|
+
Environment=PATH=${process.env.PATH}
|
|
606
|
+
WorkingDirectory=${os2.homedir()}
|
|
607
|
+
|
|
608
|
+
[Install]
|
|
609
|
+
WantedBy=default.target
|
|
610
|
+
`;
|
|
611
|
+
fs2.mkdirSync(serviceDir, { recursive: true });
|
|
612
|
+
fs2.writeFileSync(servicePath, unit);
|
|
613
|
+
console.log(`[agent] Service file created: ${servicePath}`);
|
|
614
|
+
try {
|
|
615
|
+
execSync("systemctl --user daemon-reload", { stdio: "inherit" });
|
|
616
|
+
execSync(`systemctl --user enable ${SERVICE_NAME}`, { stdio: "inherit" });
|
|
617
|
+
execSync(`systemctl --user start ${SERVICE_NAME}`, { stdio: "inherit" });
|
|
618
|
+
execSync(`loginctl enable-linger ${os2.userInfo().username}`, { stdio: "inherit" });
|
|
619
|
+
console.log(``);
|
|
620
|
+
console.log(`[agent] Service installed and started!`);
|
|
621
|
+
console.log(`[agent] It will auto-start on boot.`);
|
|
622
|
+
console.log(``);
|
|
623
|
+
console.log(`Useful commands:`);
|
|
624
|
+
console.log(` systemctl --user status ${SERVICE_NAME}`);
|
|
625
|
+
console.log(` journalctl --user -u ${SERVICE_NAME} -f`);
|
|
626
|
+
console.log(` npx @webmux/agent service uninstall`);
|
|
627
|
+
} catch (err) {
|
|
628
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
629
|
+
console.error(`[agent] Failed to enable service: ${message}`);
|
|
630
|
+
console.error(`[agent] Service file was written to ${servicePath}`);
|
|
631
|
+
console.error(`[agent] You can try manually: systemctl --user enable --now ${SERVICE_NAME}`);
|
|
632
|
+
process.exit(1);
|
|
633
|
+
}
|
|
566
634
|
});
|
|
635
|
+
service.command("uninstall").description("Stop and remove the systemd user service").action(() => {
|
|
636
|
+
const servicePath = path2.join(os2.homedir(), ".config", "systemd", "user", `${SERVICE_NAME}.service`);
|
|
637
|
+
try {
|
|
638
|
+
execSync(`systemctl --user stop ${SERVICE_NAME} 2>/dev/null`, { stdio: "inherit" });
|
|
639
|
+
execSync(`systemctl --user disable ${SERVICE_NAME} 2>/dev/null`, { stdio: "inherit" });
|
|
640
|
+
} catch {
|
|
641
|
+
}
|
|
642
|
+
if (fs2.existsSync(servicePath)) {
|
|
643
|
+
fs2.unlinkSync(servicePath);
|
|
644
|
+
console.log(`[agent] Service file removed: ${servicePath}`);
|
|
645
|
+
}
|
|
646
|
+
try {
|
|
647
|
+
execSync("systemctl --user daemon-reload", { stdio: "inherit" });
|
|
648
|
+
} catch {
|
|
649
|
+
}
|
|
650
|
+
console.log(`[agent] Service uninstalled.`);
|
|
651
|
+
});
|
|
652
|
+
service.command("status").description("Show systemd service status").action(() => {
|
|
653
|
+
try {
|
|
654
|
+
execSync(`systemctl --user status ${SERVICE_NAME}`, { stdio: "inherit" });
|
|
655
|
+
} catch {
|
|
656
|
+
console.log(`[agent] Service is not installed or not running.`);
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
function findBinary(name) {
|
|
660
|
+
try {
|
|
661
|
+
return execSync(`which ${name} 2>/dev/null`, { encoding: "utf-8" }).trim();
|
|
662
|
+
} catch {
|
|
663
|
+
return null;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
567
666
|
program.parse();
|