abtars 0.1.0-alpha.19 → 0.1.0-alpha.20
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/bundle/abtars-cli.js +1 -1
- package/bundle/daemon-NPKYZ3CJ.js +292 -0
- package/bundle/daemon-NPKYZ3CJ.js.map +7 -0
- package/bundle/meta.json +7 -7
- package/package.json +1 -1
package/bundle/abtars-cli.js
CHANGED
|
@@ -1957,7 +1957,7 @@ async function main(argv) {
|
|
|
1957
1957
|
return await startCmd();
|
|
1958
1958
|
}
|
|
1959
1959
|
case "daemon": {
|
|
1960
|
-
const { daemon: daemonCmd } = await import("./daemon-
|
|
1960
|
+
const { daemon: daemonCmd } = await import("./daemon-NPKYZ3CJ.js");
|
|
1961
1961
|
return await daemonCmd(argv.slice(1));
|
|
1962
1962
|
}
|
|
1963
1963
|
case "logs": {
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __bundleCreateRequire } from 'node:module'; import { fileURLToPath as __bundleFileURLToPath } from 'node:url'; import { dirname as __bundleDirname } from 'node:path'; const require = __bundleCreateRequire(import.meta.url); const __chunk_filename = __bundleFileURLToPath(import.meta.url); const __chunk_dirname = __bundleDirname(__chunk_filename);
|
|
3
|
+
import {
|
|
4
|
+
init_log_and_swallow,
|
|
5
|
+
logAndSwallow
|
|
6
|
+
} from "./chunk-EX2SRTUE.js";
|
|
7
|
+
import "./chunk-2BY6I4P5.js";
|
|
8
|
+
import "./chunk-MJ6PHMOK.js";
|
|
9
|
+
import "./chunk-7K2YZTLD.js";
|
|
10
|
+
|
|
11
|
+
// src/cli/commands/daemon.ts
|
|
12
|
+
init_log_and_swallow();
|
|
13
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
14
|
+
import { join, dirname } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
function abtarsHome() {
|
|
17
|
+
return process.env["ABTARS_HOME"] ?? join(process.env["HOME"] ?? "", ".abtars");
|
|
18
|
+
}
|
|
19
|
+
function isWSL() {
|
|
20
|
+
try {
|
|
21
|
+
return readFileSync("/proc/version", "utf-8").toLowerCase().includes("microsoft");
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function detectScope() {
|
|
27
|
+
if (existsSync("/etc/systemd/system/abtars.service")) return "system";
|
|
28
|
+
const userUnit = join(process.env["HOME"] ?? "", ".config", "systemd", "user", "abtars-watchdog.service");
|
|
29
|
+
if (existsSync(userUnit)) return "user";
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
function unitName(scope) {
|
|
33
|
+
return scope === "user" ? "abtars-watchdog" : "abtars";
|
|
34
|
+
}
|
|
35
|
+
async function daemonInstall() {
|
|
36
|
+
const platform = process.platform;
|
|
37
|
+
const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
38
|
+
if (platform === "linux" && isWSL()) {
|
|
39
|
+
process.stderr.write(`\u2139\uFE0F WSL detected \u2014 ensure systemd is enabled (wsl.conf: [boot] systemd=true)
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
const sudoUser = process.env["SUDO_USER"];
|
|
43
|
+
if (process.getuid?.() !== 0) {
|
|
44
|
+
process.stderr.write(
|
|
45
|
+
`Requires sudo for system-scope service registration.
|
|
46
|
+
Run: sudo -k $(which abtars) daemon install
|
|
47
|
+
`
|
|
48
|
+
);
|
|
49
|
+
return 2;
|
|
50
|
+
}
|
|
51
|
+
if (!sudoUser) {
|
|
52
|
+
process.stderr.write(`Cannot determine target user \u2014 $SUDO_USER is not set.
|
|
53
|
+
`);
|
|
54
|
+
return 2;
|
|
55
|
+
}
|
|
56
|
+
const { execSync: execSyncHome } = await import("node:child_process");
|
|
57
|
+
const userHome = execSyncHome(`eval echo ~${sudoUser}`, { encoding: "utf-8" }).trim();
|
|
58
|
+
const home = join(userHome, ".abtars");
|
|
59
|
+
const currentLink = join(home, "current");
|
|
60
|
+
if (!existsSync(currentLink)) {
|
|
61
|
+
process.stderr.write(`No release staged. Run 'abtars install' first.
|
|
62
|
+
`);
|
|
63
|
+
return 2;
|
|
64
|
+
}
|
|
65
|
+
if (platform === "darwin") {
|
|
66
|
+
const { execSync, execFileSync } = await import("node:child_process");
|
|
67
|
+
let group = sudoUser;
|
|
68
|
+
try {
|
|
69
|
+
group = execSync(`id -gn ${sudoUser}`, { encoding: "utf-8" }).trim();
|
|
70
|
+
} catch (err) {
|
|
71
|
+
logAndSwallow("daemon", "op", err);
|
|
72
|
+
}
|
|
73
|
+
const plistSrc = join(pkgRoot, "scripts", "com.abtars.daemon.plist");
|
|
74
|
+
if (!existsSync(plistSrc)) {
|
|
75
|
+
process.stderr.write(`Template not found: ${plistSrc}
|
|
76
|
+
`);
|
|
77
|
+
return 1;
|
|
78
|
+
}
|
|
79
|
+
let content = readFileSync(plistSrc, "utf-8");
|
|
80
|
+
content = content.replaceAll("{{USER}}", sudoUser).replaceAll("{{GROUP}}", group);
|
|
81
|
+
const dst = "/Library/LaunchDaemons/com.abtars.daemon.plist";
|
|
82
|
+
const { writeFileSync, chmodSync } = await import("node:fs");
|
|
83
|
+
writeFileSync(dst, content);
|
|
84
|
+
chmodSync(dst, 420);
|
|
85
|
+
try {
|
|
86
|
+
execFileSync("launchctl", ["bootstrap", "system", dst]);
|
|
87
|
+
} catch (err) {
|
|
88
|
+
logAndSwallow("daemon", "op", err);
|
|
89
|
+
}
|
|
90
|
+
process.stdout.write(`\u2713 LaunchDaemon installed at ${dst}
|
|
91
|
+
`);
|
|
92
|
+
process.stdout.write(`\u2713 bridge runs as ${sudoUser}, survives logout + reboot
|
|
93
|
+
`);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
if (platform === "linux") {
|
|
97
|
+
const { execSync, execFileSync } = await import("node:child_process");
|
|
98
|
+
try {
|
|
99
|
+
execSync("systemctl --version", { stdio: "ignore" });
|
|
100
|
+
} catch {
|
|
101
|
+
process.stderr.write(`systemctl not found \u2014 requires systemd.
|
|
102
|
+
`);
|
|
103
|
+
return 2;
|
|
104
|
+
}
|
|
105
|
+
const unitSrc = join(pkgRoot, "scripts", "abtars-daemon.service");
|
|
106
|
+
if (!existsSync(unitSrc)) {
|
|
107
|
+
process.stderr.write(`Template not found: ${unitSrc}
|
|
108
|
+
`);
|
|
109
|
+
return 1;
|
|
110
|
+
}
|
|
111
|
+
let content = readFileSync(unitSrc, "utf-8");
|
|
112
|
+
content = content.replaceAll("{{USER}}", sudoUser);
|
|
113
|
+
let userPath = `/usr/local/bin:/usr/bin:/bin`;
|
|
114
|
+
try {
|
|
115
|
+
userPath = execSyncHome(`su - ${sudoUser} -c 'echo $PATH'`, { encoding: "utf-8" }).trim();
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
content = content.replaceAll("{{PATH}}", userPath);
|
|
119
|
+
const dst = "/etc/systemd/system/abtars.service";
|
|
120
|
+
const { writeFileSync } = await import("node:fs");
|
|
121
|
+
writeFileSync(dst, content);
|
|
122
|
+
execFileSync("systemctl", ["daemon-reload"]);
|
|
123
|
+
execFileSync("systemctl", ["enable", "--now", "abtars"]);
|
|
124
|
+
const manifestPath = join(home, "manifest.json");
|
|
125
|
+
try {
|
|
126
|
+
const { readFileSync: rfs, writeFileSync: wfs } = await import("node:fs");
|
|
127
|
+
const mf = JSON.parse(rfs(manifestPath, "utf-8"));
|
|
128
|
+
mf.installMode = "supervised-daemon";
|
|
129
|
+
wfs(manifestPath, JSON.stringify(mf, null, 2) + "\n");
|
|
130
|
+
} catch {
|
|
131
|
+
}
|
|
132
|
+
process.stdout.write(`\u2713 systemd unit installed at ${dst}
|
|
133
|
+
`);
|
|
134
|
+
process.stdout.write(`\u2713 bridge runs as ${sudoUser}, survives logout + reboot
|
|
135
|
+
`);
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
process.stderr.write(`Unsupported platform: ${platform}
|
|
139
|
+
`);
|
|
140
|
+
return 2;
|
|
141
|
+
}
|
|
142
|
+
async function daemonUninstall() {
|
|
143
|
+
const scope = detectScope();
|
|
144
|
+
if (!scope) {
|
|
145
|
+
process.stderr.write("No daemon service found.\n");
|
|
146
|
+
return 1;
|
|
147
|
+
}
|
|
148
|
+
if (scope === "system") {
|
|
149
|
+
if (process.getuid?.() !== 0) {
|
|
150
|
+
process.stderr.write(`Requires sudo: sudo -k $(which abtars) daemon uninstall
|
|
151
|
+
`);
|
|
152
|
+
return 2;
|
|
153
|
+
}
|
|
154
|
+
const { execFileSync } = await import("node:child_process");
|
|
155
|
+
const { unlinkSync } = await import("node:fs");
|
|
156
|
+
try {
|
|
157
|
+
execFileSync("systemctl", ["stop", "abtars"]);
|
|
158
|
+
} catch (err) {
|
|
159
|
+
logAndSwallow("daemon", "op", err);
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
execFileSync("systemctl", ["disable", "abtars"]);
|
|
163
|
+
} catch (err) {
|
|
164
|
+
logAndSwallow("daemon", "op", err);
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
unlinkSync("/etc/systemd/system/abtars.service");
|
|
168
|
+
} catch (err) {
|
|
169
|
+
logAndSwallow("daemon", "op", err);
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
execFileSync("systemctl", ["daemon-reload"]);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
logAndSwallow("daemon", "op", err);
|
|
175
|
+
}
|
|
176
|
+
process.stdout.write("\u2713 system service removed\n");
|
|
177
|
+
} else {
|
|
178
|
+
const { execFileSync } = await import("node:child_process");
|
|
179
|
+
const { unlinkSync } = await import("node:fs");
|
|
180
|
+
const unit = join(process.env["HOME"] ?? "", ".config", "systemd", "user", "abtars-watchdog.service");
|
|
181
|
+
try {
|
|
182
|
+
execFileSync("systemctl", ["--user", "stop", "abtars-watchdog"]);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
logAndSwallow("daemon", "op", err);
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
execFileSync("systemctl", ["--user", "disable", "abtars-watchdog"]);
|
|
188
|
+
} catch (err) {
|
|
189
|
+
logAndSwallow("daemon", "op", err);
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
unlinkSync(unit);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
logAndSwallow("daemon", "op", err);
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
execFileSync("systemctl", ["--user", "daemon-reload"]);
|
|
198
|
+
} catch (err) {
|
|
199
|
+
logAndSwallow("daemon", "op", err);
|
|
200
|
+
}
|
|
201
|
+
process.stdout.write("\u2713 user service removed\n");
|
|
202
|
+
}
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
async function daemonControl(action) {
|
|
206
|
+
const scope = detectScope();
|
|
207
|
+
if (!scope) {
|
|
208
|
+
process.stderr.write("No daemon service found. Run: abtars daemon install\n");
|
|
209
|
+
return 1;
|
|
210
|
+
}
|
|
211
|
+
const { execFileSync } = await import("node:child_process");
|
|
212
|
+
const unit = unitName(scope);
|
|
213
|
+
const args = scope === "user" ? ["--user", action, unit] : [action, unit];
|
|
214
|
+
try {
|
|
215
|
+
execFileSync("systemctl", args, { stdio: "inherit" });
|
|
216
|
+
process.stdout.write(`\u2713 ${action} ${unit}
|
|
217
|
+
`);
|
|
218
|
+
} catch {
|
|
219
|
+
process.stderr.write(`\u2717 ${action} failed
|
|
220
|
+
`);
|
|
221
|
+
return 1;
|
|
222
|
+
}
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
async function daemonStatus() {
|
|
226
|
+
const scope = detectScope();
|
|
227
|
+
if (!scope) {
|
|
228
|
+
process.stdout.write("No daemon service installed.\n");
|
|
229
|
+
process.stdout.write(" Install: sudo $(which abtars) daemon install\n");
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
const { spawnSync } = await import("node:child_process");
|
|
233
|
+
const unit = unitName(scope);
|
|
234
|
+
const args = scope === "user" ? ["--user", "status", unit] : ["status", unit];
|
|
235
|
+
const r = spawnSync("systemctl", args, { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
|
|
236
|
+
const output = r.stdout || r.stderr || "";
|
|
237
|
+
const activeMatch = output.match(/Active:\s+(.+)/);
|
|
238
|
+
const pidMatch = output.match(/Main PID:\s+(\d+)/);
|
|
239
|
+
process.stdout.write(`\u25CF ${unit} (${scope} scope)
|
|
240
|
+
`);
|
|
241
|
+
process.stdout.write(` ${activeMatch?.[1] ?? "unknown"}
|
|
242
|
+
`);
|
|
243
|
+
if (pidMatch) process.stdout.write(` PID: ${pidMatch[1]}
|
|
244
|
+
`);
|
|
245
|
+
const home = abtarsHome();
|
|
246
|
+
const lockPath = join(home, "bridge.lock");
|
|
247
|
+
if (existsSync(lockPath)) {
|
|
248
|
+
try {
|
|
249
|
+
const lock = JSON.parse(readFileSync(lockPath, "utf-8"));
|
|
250
|
+
if (lock.pid) process.stdout.write(` Bridge PID: ${lock.pid}
|
|
251
|
+
`);
|
|
252
|
+
if (lock.startedAt) {
|
|
253
|
+
const upMs = Date.now() - new Date(lock.startedAt).getTime();
|
|
254
|
+
const upMin = Math.round(upMs / 6e4);
|
|
255
|
+
process.stdout.write(` Uptime: ${upMin >= 60 ? `${Math.floor(upMin / 60)}h ${upMin % 60}m` : `${upMin}m`}
|
|
256
|
+
`);
|
|
257
|
+
}
|
|
258
|
+
if (lock.version) process.stdout.write(` Version: ${lock.version}
|
|
259
|
+
`);
|
|
260
|
+
if (lock.restartReason) process.stdout.write(` Last restart: ${lock.restartReason}
|
|
261
|
+
`);
|
|
262
|
+
} catch {
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
async function daemon(args) {
|
|
268
|
+
const sub = args[0] ?? "status";
|
|
269
|
+
switch (sub) {
|
|
270
|
+
case "install":
|
|
271
|
+
return daemonInstall();
|
|
272
|
+
case "uninstall":
|
|
273
|
+
return daemonUninstall();
|
|
274
|
+
case "start":
|
|
275
|
+
return daemonControl("start");
|
|
276
|
+
case "stop":
|
|
277
|
+
return daemonControl("stop");
|
|
278
|
+
case "restart":
|
|
279
|
+
return daemonControl("restart");
|
|
280
|
+
case "status":
|
|
281
|
+
return daemonStatus();
|
|
282
|
+
default:
|
|
283
|
+
process.stderr.write(`Unknown: abtars daemon ${sub}
|
|
284
|
+
Usage: abtars daemon [install|uninstall|start|stop|restart|status]
|
|
285
|
+
`);
|
|
286
|
+
return 1;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
export {
|
|
290
|
+
daemon
|
|
291
|
+
};
|
|
292
|
+
//# sourceMappingURL=daemon-NPKYZ3CJ.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli/commands/daemon.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * `abtars daemon` \u2014 manage the system service (install/uninstall/start/stop/restart/status).\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { logAndSwallow } from \"../../components/log-and-swallow.js\";\n\nfunction abtarsHome(): string {\n return process.env[\"ABTARS_HOME\"] ?? join(process.env[\"HOME\"] ?? \"\", \".abtars\");\n}\n\nfunction isWSL(): boolean {\n try { return readFileSync(\"/proc/version\", \"utf-8\").toLowerCase().includes(\"microsoft\"); } catch { return false; }\n}\n\ntype Scope = \"system\" | \"user\" | null;\n\nfunction detectScope(): Scope {\n if (existsSync(\"/etc/systemd/system/abtars.service\")) return \"system\";\n const userUnit = join(process.env[\"HOME\"] ?? \"\", \".config\", \"systemd\", \"user\", \"abtars-watchdog.service\");\n if (existsSync(userUnit)) return \"user\";\n return null;\n}\nfunction unitName(scope: Scope): string {\n return scope === \"user\" ? \"abtars-watchdog\" : \"abtars\";\n}\n\n// \u2500\u2500 install \u2500\u2500\n\nasync function daemonInstall(): Promise<number> {\n const platform = process.platform;\n const pkgRoot = join(dirname(fileURLToPath(import.meta.url)), \"..\");\n\n if (platform === \"linux\" && isWSL()) {\n process.stderr.write(`\u2139\uFE0F WSL detected \u2014 ensure systemd is enabled (wsl.conf: [boot] systemd=true)\\n`);\n }\n\n const sudoUser = process.env[\"SUDO_USER\"];\n if (process.getuid?.() !== 0) {\n process.stderr.write(\n `Requires sudo for system-scope service registration.\\n` +\n `Run: sudo -k $(which abtars) daemon install\\n`,\n );\n return 2;\n }\n if (!sudoUser) {\n process.stderr.write(`Cannot determine target user \u2014 $SUDO_USER is not set.\\n`);\n return 2;\n }\n\n // Resolve the SUDO_USER's home, not root's\n const { execSync: execSyncHome } = await import(\"node:child_process\");\n const userHome = execSyncHome(`eval echo ~${sudoUser}`, { encoding: \"utf-8\" }).trim();\n const home = join(userHome, \".abtars\");\n\n const currentLink = join(home, \"current\");\n if (!existsSync(currentLink)) {\n process.stderr.write(`No release staged. Run 'abtars install' first.\\n`);\n return 2;\n }\n\n if (platform === \"darwin\") {\n const { execSync, execFileSync } = await import(\"node:child_process\");\n let group = sudoUser;\n try { group = execSync(`id -gn ${sudoUser}`, { encoding: \"utf-8\" }).trim(); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n\n const plistSrc = join(pkgRoot, \"scripts\", \"com.abtars.daemon.plist\");\n if (!existsSync(plistSrc)) { process.stderr.write(`Template not found: ${plistSrc}\\n`); return 1; }\n let content = readFileSync(plistSrc, \"utf-8\");\n content = content.replaceAll(\"{{USER}}\", sudoUser).replaceAll(\"{{GROUP}}\", group);\n const dst = \"/Library/LaunchDaemons/com.abtars.daemon.plist\";\n\n const { writeFileSync, chmodSync } = await import(\"node:fs\");\n writeFileSync(dst, content);\n chmodSync(dst, 0o644);\n try { execFileSync(\"launchctl\", [\"bootstrap\", \"system\", dst]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n process.stdout.write(`\u2713 LaunchDaemon installed at ${dst}\\n`);\n process.stdout.write(`\u2713 bridge runs as ${sudoUser}, survives logout + reboot\\n`);\n return 0;\n }\n\n if (platform === \"linux\") {\n const { execSync, execFileSync } = await import(\"node:child_process\");\n try { execSync(\"systemctl --version\", { stdio: \"ignore\" }); } catch {\n process.stderr.write(`systemctl not found \u2014 requires systemd.\\n`);\n return 2;\n }\n\n const unitSrc = join(pkgRoot, \"scripts\", \"abtars-daemon.service\");\n if (!existsSync(unitSrc)) { process.stderr.write(`Template not found: ${unitSrc}\\n`); return 1; }\n let content = readFileSync(unitSrc, \"utf-8\");\n content = content.replaceAll(\"{{USER}}\", sudoUser);\n // Get the user's full login PATH (includes nvm, cargo, etc.)\n let userPath = `/usr/local/bin:/usr/bin:/bin`;\n try { userPath = execSyncHome(`su - ${sudoUser} -c 'echo $PATH'`, { encoding: \"utf-8\" }).trim(); } catch { /* fallback */ }\n content = content.replaceAll(\"{{PATH}}\", userPath);\n const dst = \"/etc/systemd/system/abtars.service\";\n\n const { writeFileSync } = await import(\"node:fs\");\n writeFileSync(dst, content);\n execFileSync(\"systemctl\", [\"daemon-reload\"]);\n execFileSync(\"systemctl\", [\"enable\", \"--now\", \"abtars\"]);\n // Update manifest mode\n const manifestPath = join(home, \"manifest.json\");\n try {\n const { readFileSync: rfs, writeFileSync: wfs } = await import(\"node:fs\");\n const mf = JSON.parse(rfs(manifestPath, \"utf-8\"));\n mf.installMode = \"supervised-daemon\";\n wfs(manifestPath, JSON.stringify(mf, null, 2) + \"\\n\");\n } catch { /* best effort */ }\n process.stdout.write(`\u2713 systemd unit installed at ${dst}\\n`);\n process.stdout.write(`\u2713 bridge runs as ${sudoUser}, survives logout + reboot\\n`);\n return 0;\n }\n\n process.stderr.write(`Unsupported platform: ${platform}\\n`);\n return 2;\n}\n\n// \u2500\u2500 uninstall \u2500\u2500\n\nasync function daemonUninstall(): Promise<number> {\n const scope = detectScope();\n if (!scope) { process.stderr.write(\"No daemon service found.\\n\"); return 1; }\n\n if (scope === \"system\") {\n if (process.getuid?.() !== 0) {\n process.stderr.write(`Requires sudo: sudo -k $(which abtars) daemon uninstall\\n`);\n return 2;\n }\n const { execFileSync } = await import(\"node:child_process\");\n const { unlinkSync } = await import(\"node:fs\");\n try { execFileSync(\"systemctl\", [\"stop\", \"abtars\"]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n try { execFileSync(\"systemctl\", [\"disable\", \"abtars\"]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n try { unlinkSync(\"/etc/systemd/system/abtars.service\"); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n try { execFileSync(\"systemctl\", [\"daemon-reload\"]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n process.stdout.write(\"\u2713 system service removed\\n\");\n } else {\n const { execFileSync } = await import(\"node:child_process\");\n const { unlinkSync } = await import(\"node:fs\");\n const unit = join(process.env[\"HOME\"] ?? \"\", \".config\", \"systemd\", \"user\", \"abtars-watchdog.service\");\n try { execFileSync(\"systemctl\", [\"--user\", \"stop\", \"abtars-watchdog\"]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n try { execFileSync(\"systemctl\", [\"--user\", \"disable\", \"abtars-watchdog\"]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n try { unlinkSync(unit); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n try { execFileSync(\"systemctl\", [\"--user\", \"daemon-reload\"]); } catch (err) { logAndSwallow(\"daemon\", \"op\", err); }\n process.stdout.write(\"\u2713 user service removed\\n\");\n }\n return 0;\n}\n\n// \u2500\u2500 start/stop/restart \u2500\u2500\n\nasync function daemonControl(action: \"start\" | \"stop\" | \"restart\"): Promise<number> {\n const scope = detectScope();\n if (!scope) { process.stderr.write(\"No daemon service found. Run: abtars daemon install\\n\"); return 1; }\n const { execFileSync } = await import(\"node:child_process\");\n const unit = unitName(scope);\n const args = scope === \"user\" ? [\"--user\", action, unit] : [action, unit];\n try {\n execFileSync(\"systemctl\", args, { stdio: \"inherit\" });\n process.stdout.write(`\u2713 ${action} ${unit}\\n`);\n } catch {\n process.stderr.write(`\u2717 ${action} failed\\n`);\n return 1;\n }\n return 0;\n}\n\n// \u2500\u2500 status \u2500\u2500\n\nasync function daemonStatus(): Promise<number> {\n const scope = detectScope();\n if (!scope) {\n process.stdout.write(\"No daemon service installed.\\n\");\n process.stdout.write(\" Install: sudo $(which abtars) daemon install\\n\");\n return 0;\n }\n\n const { spawnSync } = await import(\"node:child_process\");\n const unit = unitName(scope);\n const args = scope === \"user\" ? [\"--user\", \"status\", unit] : [\"status\", unit];\n const r = spawnSync(\"systemctl\", args, { encoding: \"utf-8\", stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const output = r.stdout || r.stderr || \"\";\n\n // Parse active state\n const activeMatch = output.match(/Active:\\s+(.+)/);\n const pidMatch = output.match(/Main PID:\\s+(\\d+)/);\n\n process.stdout.write(`\u25CF ${unit} (${scope} scope)\\n`);\n process.stdout.write(` ${activeMatch?.[1] ?? \"unknown\"}\\n`);\n if (pidMatch) process.stdout.write(` PID: ${pidMatch[1]}\\n`);\n\n // Bridge info from bridge.lock\n const home = abtarsHome();\n const lockPath = join(home, \"bridge.lock\");\n if (existsSync(lockPath)) {\n try {\n const lock = JSON.parse(readFileSync(lockPath, \"utf-8\"));\n if (lock.pid) process.stdout.write(` Bridge PID: ${lock.pid}\\n`);\n if (lock.startedAt) {\n const upMs = Date.now() - new Date(lock.startedAt).getTime();\n const upMin = Math.round(upMs / 60000);\n process.stdout.write(` Uptime: ${upMin >= 60 ? `${Math.floor(upMin / 60)}h ${upMin % 60}m` : `${upMin}m`}\\n`);\n }\n if (lock.version) process.stdout.write(` Version: ${lock.version}\\n`);\n if (lock.restartReason) process.stdout.write(` Last restart: ${lock.restartReason}\\n`);\n } catch { /* ignore */ }\n }\n return 0;\n}\n\n// \u2500\u2500 router \u2500\u2500\n\nexport async function daemon(args: string[]): Promise<number> {\n const sub = args[0] ?? \"status\";\n switch (sub) {\n case \"install\": return daemonInstall();\n case \"uninstall\": return daemonUninstall();\n case \"start\": return daemonControl(\"start\");\n case \"stop\": return daemonControl(\"stop\");\n case \"restart\": return daemonControl(\"restart\");\n case \"status\": return daemonStatus();\n default:\n process.stderr.write(`Unknown: abtars daemon ${sub}\\nUsage: abtars daemon [install|uninstall|start|stop|restart|status]\\n`);\n return 1;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/bundle/meta.json
CHANGED
|
@@ -28824,7 +28824,7 @@
|
|
|
28824
28824
|
"format": "esm"
|
|
28825
28825
|
},
|
|
28826
28826
|
"src/cli/commands/daemon.ts": {
|
|
28827
|
-
"bytes":
|
|
28827
|
+
"bytes": 9652,
|
|
28828
28828
|
"imports": [
|
|
28829
28829
|
{
|
|
28830
28830
|
"path": "node:fs",
|
|
@@ -29234,13 +29234,13 @@
|
|
|
29234
29234
|
},
|
|
29235
29235
|
"bytes": 1250
|
|
29236
29236
|
},
|
|
29237
|
-
"bundle/daemon-
|
|
29237
|
+
"bundle/daemon-NPKYZ3CJ.js.map": {
|
|
29238
29238
|
"imports": [],
|
|
29239
29239
|
"exports": [],
|
|
29240
29240
|
"inputs": {},
|
|
29241
|
-
"bytes":
|
|
29241
|
+
"bytes": 16777
|
|
29242
29242
|
},
|
|
29243
|
-
"bundle/daemon-
|
|
29243
|
+
"bundle/daemon-NPKYZ3CJ.js": {
|
|
29244
29244
|
"imports": [
|
|
29245
29245
|
{
|
|
29246
29246
|
"path": "bundle/chunk-EX2SRTUE.js",
|
|
@@ -29340,10 +29340,10 @@
|
|
|
29340
29340
|
"entryPoint": "src/cli/commands/daemon.ts",
|
|
29341
29341
|
"inputs": {
|
|
29342
29342
|
"src/cli/commands/daemon.ts": {
|
|
29343
|
-
"bytesInOutput":
|
|
29343
|
+
"bytesInOutput": 9216
|
|
29344
29344
|
}
|
|
29345
29345
|
},
|
|
29346
|
-
"bytes":
|
|
29346
|
+
"bytes": 9875
|
|
29347
29347
|
},
|
|
29348
29348
|
"bundle/logs-EK4HYRKR.js.map": {
|
|
29349
29349
|
"imports": [],
|
|
@@ -40348,7 +40348,7 @@
|
|
|
40348
40348
|
"kind": "dynamic-import"
|
|
40349
40349
|
},
|
|
40350
40350
|
{
|
|
40351
|
-
"path": "bundle/daemon-
|
|
40351
|
+
"path": "bundle/daemon-NPKYZ3CJ.js",
|
|
40352
40352
|
"kind": "dynamic-import"
|
|
40353
40353
|
},
|
|
40354
40354
|
{
|