demobite 1.18.4 → 1.18.5
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/launcher/index.mjs +13 -7
- package/package.json +1 -1
package/launcher/index.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import os from "node:os";
|
|
|
25
25
|
import path from "node:path";
|
|
26
26
|
import { fileURLToPath } from "node:url";
|
|
27
27
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
28
|
+
import { createHash } from "node:crypto";
|
|
28
29
|
|
|
29
30
|
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
30
31
|
const pkg = JSON.parse(fs.readFileSync(path.join(pkgRoot, "package.json"), "utf8"));
|
|
@@ -61,7 +62,12 @@ const LOCK = path.join(HOME, "listen.lock");
|
|
|
61
62
|
const LOG = path.join(HOME, "listen.log");
|
|
62
63
|
const STATE = path.join(HOME, "state.json");
|
|
63
64
|
const CHILDREN = path.join(HOME, "children.json");
|
|
64
|
-
|
|
65
|
+
// A second home (DEMOBITE_HOME, used by tests and rigs) gets its own service name, so `off` on a rig can
|
|
66
|
+
// never unload the real one (2026-10-16: a scratch rig's `off` removed the founder's service).
|
|
67
|
+
const HOME_TAG = process.env.DEMOBITE_HOME ? "." + createHash("sha1").update(HOME).digest("hex").slice(0, 8) : "";
|
|
68
|
+
const SERVICE_LABEL = `com.demobites.listen${HOME_TAG}`;
|
|
69
|
+
const SERVICE_UNIT = `demobite${HOME_TAG}.service`;
|
|
70
|
+
const RUN_NAME = `DemoBites${HOME_TAG}`;
|
|
65
71
|
const SERVICE = process.argv.includes("--service");
|
|
66
72
|
const launcherPath = fileURLToPath(import.meta.url);
|
|
67
73
|
const readJson = (f) => { try { return JSON.parse(fs.readFileSync(f, "utf8")); } catch { return null; } };
|
|
@@ -70,11 +76,11 @@ const pidAlive = (pid) => { if (!pid) return false; try { process.kill(pid, 0);
|
|
|
70
76
|
const ago = (iso) => { const s = Math.max(0, Math.round((Date.now() - new Date(iso).getTime()) / 1000)); return s < 60 ? `${s} s ago` : s < 3600 ? `${Math.round(s / 60)} min ago` : `${Math.round(s / 3600)} h ago`; };
|
|
71
77
|
const serviceDef = () => {
|
|
72
78
|
if (process.platform === "darwin") return { file: path.join(os.homedir(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`) };
|
|
73
|
-
if (process.platform === "linux") return { file: path.join(os.homedir(), ".config", "systemd", "user",
|
|
79
|
+
if (process.platform === "linux") return { file: path.join(os.homedir(), ".config", "systemd", "user", SERVICE_UNIT) };
|
|
74
80
|
return { file: path.join(HOME, "service.vbs") };
|
|
75
81
|
};
|
|
76
82
|
const serviceInstalled = () => {
|
|
77
|
-
if (process.platform === "win32") { const r = spawnSync("reg", ["query", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v",
|
|
83
|
+
if (process.platform === "win32") { const r = spawnSync("reg", ["query", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v", RUN_NAME], { encoding: "utf8" }); return r.status === 0; }
|
|
78
84
|
return fs.existsSync(serviceDef().file);
|
|
79
85
|
};
|
|
80
86
|
const killListener = () => {
|
|
@@ -107,8 +113,8 @@ if (arg === "logs") {
|
|
|
107
113
|
if (arg === "off") {
|
|
108
114
|
const def = serviceDef();
|
|
109
115
|
if (process.platform === "darwin") spawnSync("launchctl", ["bootout", `gui/${process.getuid()}/${SERVICE_LABEL}`], { stdio: "ignore" });
|
|
110
|
-
else if (process.platform === "linux") spawnSync("systemctl", ["--user", "disable", "--now",
|
|
111
|
-
else spawnSync("reg", ["delete", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v",
|
|
116
|
+
else if (process.platform === "linux") spawnSync("systemctl", ["--user", "disable", "--now", SERVICE_UNIT], { stdio: "ignore" });
|
|
117
|
+
else spawnSync("reg", ["delete", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v", RUN_NAME, "/f"], { stdio: "ignore" });
|
|
112
118
|
fs.rmSync(def.file, { force: true });
|
|
113
119
|
const pid = killListener();
|
|
114
120
|
// the browsers of an interrupted take go with it
|
|
@@ -322,14 +328,14 @@ if (arg === "on") {
|
|
|
322
328
|
fs.writeFileSync(def.file, unit);
|
|
323
329
|
killListener();
|
|
324
330
|
spawnSync("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" });
|
|
325
|
-
const r = spawnSync("systemctl", ["--user", "enable", "--now",
|
|
331
|
+
const r = spawnSync("systemctl", ["--user", "enable", "--now", SERVICE_UNIT], { encoding: "utf8" });
|
|
326
332
|
if (r.status !== 0) { warn(`systemd refused the service: ${(r.stderr || "").trim()}`); process.exit(1); }
|
|
327
333
|
} else {
|
|
328
334
|
// Windows: a Run entry that starts the listener hidden at logon (no console window), via a tiny script.
|
|
329
335
|
const q = (t) => `""${t}""`;
|
|
330
336
|
const vbs = `Set sh = CreateObject("WScript.Shell")\nsh.CurrentDirectory = "${cwd}"\nsh.Run "${args.map((a) => q(a)).join(" ")} >> ${q(LOG)} 2>&1", 0, False\n`;
|
|
331
337
|
fs.writeFileSync(def.file, vbs);
|
|
332
|
-
spawnSync("reg", ["add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v",
|
|
338
|
+
spawnSync("reg", ["add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", "/v", RUN_NAME, "/t", "REG_SZ", "/d", `wscript.exe "${def.file}"`, "/f"], { stdio: "ignore" });
|
|
333
339
|
killListener();
|
|
334
340
|
spawnSync("wscript.exe", [def.file], { stdio: "ignore" });
|
|
335
341
|
}
|
package/package.json
CHANGED