@decentnetwork/lan 0.1.295 → 0.1.296
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/commands.js +49 -2
- package/dist/ui/desktop/app.js +1 -1
- package/package.json +1 -1
package/dist/cli/commands.js
CHANGED
|
@@ -77,6 +77,18 @@ function assertDaemonNotRunning(config, commandName) {
|
|
|
77
77
|
* if the socket isn't there / hangs up.
|
|
78
78
|
*/
|
|
79
79
|
/** Who, if anyone, is holding the identity lock without serving IPC. */
|
|
80
|
+
class IdentityHeldByBeagle extends Error {
|
|
81
|
+
pid;
|
|
82
|
+
command;
|
|
83
|
+
port;
|
|
84
|
+
constructor(pid, command, port) {
|
|
85
|
+
super(`beagle (pid ${pid}) holds this identity on port ${port}`);
|
|
86
|
+
this.pid = pid;
|
|
87
|
+
this.command = command;
|
|
88
|
+
this.port = port;
|
|
89
|
+
this.name = "IdentityHeldByBeagle";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
80
92
|
function readIdentityHolder(dataDir) {
|
|
81
93
|
try {
|
|
82
94
|
const pid = Number.parseInt(readFileSync(join(dataDir, "daemon.pid"), "utf8").trim(), 10);
|
|
@@ -89,7 +101,14 @@ function readIdentityHolder(dataDir) {
|
|
|
89
101
|
.trim().split("\n")[0]?.slice(0, 90) ?? command;
|
|
90
102
|
}
|
|
91
103
|
catch { /* ps is best-effort */ }
|
|
92
|
-
|
|
104
|
+
let port;
|
|
105
|
+
try {
|
|
106
|
+
const p = Number.parseInt(readFileSync(join(dataDir, "holder.http-port"), "utf8").trim(), 10);
|
|
107
|
+
if (Number.isFinite(p) && p > 0)
|
|
108
|
+
port = p;
|
|
109
|
+
}
|
|
110
|
+
catch { /* older beagle, or none running */ }
|
|
111
|
+
return { pid, command, port };
|
|
93
112
|
}
|
|
94
113
|
catch {
|
|
95
114
|
return undefined;
|
|
@@ -109,6 +128,15 @@ async function ipcCall(config, req, timeoutMs = 30_000) {
|
|
|
109
128
|
// beagle had been holding the identity for six hours.
|
|
110
129
|
const holder = readIdentityHolder(config.carrier.dataDir);
|
|
111
130
|
if (holder) {
|
|
131
|
+
// beagle publishes the port of its own HTTP API next to the lock, so we
|
|
132
|
+
// can finish the job instead of only naming the obstacle. The documented
|
|
133
|
+
// upgrade is `npm i -g @decentnetwork/lan@latest && agentnet restart`,
|
|
134
|
+
// and on a machine where beagle holds the identity the second half had
|
|
135
|
+
// nothing to talk to: the person was left with a new package installed
|
|
136
|
+
// and a process still running the old one, twice in one evening.
|
|
137
|
+
if (holder.port) {
|
|
138
|
+
throw new IdentityHeldByBeagle(holder.pid, holder.command, holder.port);
|
|
139
|
+
}
|
|
112
140
|
throw new Error(`No daemon here — pid ${holder.pid} holds this identity (${holder.command}). ` +
|
|
113
141
|
`That is beagle running embedded; restart it from the app, or stop it and then \`agentnet up\`.`);
|
|
114
142
|
}
|
|
@@ -2773,7 +2801,26 @@ export async function cmdRestart(args) {
|
|
|
2773
2801
|
if (daemonPid(config) === null) {
|
|
2774
2802
|
throw new Error("Daemon not running. Start it once with 'agentnet up' (needs sudo for TUN); after that 'agentnet restart' takes care of upgrades without further sudo prompts.");
|
|
2775
2803
|
}
|
|
2776
|
-
|
|
2804
|
+
let res;
|
|
2805
|
+
try {
|
|
2806
|
+
res = await ipcCall(config, { op: "self-restart" });
|
|
2807
|
+
}
|
|
2808
|
+
catch (err) {
|
|
2809
|
+
// beagle holds the identity and runs its own HTTP API. Restart THAT — it is
|
|
2810
|
+
// what "restart" means on this machine, and refusing here left the person
|
|
2811
|
+
// with a freshly installed package and a process still running the old one.
|
|
2812
|
+
if (err instanceof IdentityHeldByBeagle) {
|
|
2813
|
+
const r = await fetch(`http://127.0.0.1:${err.port}/api/update-restart`, { method: "POST" })
|
|
2814
|
+
.catch((e) => { throw new Error(`beagle (pid ${err.pid}) is on port ${err.port} but did not answer: ${String(e)}`); });
|
|
2815
|
+
if (!r.ok)
|
|
2816
|
+
throw new Error(`beagle refused the restart: HTTP ${r.status}`);
|
|
2817
|
+
console.log(`No daemon here — beagle holds this identity (pid ${err.pid}). Asked it to restart.`);
|
|
2818
|
+
console.log(` ${err.command}`);
|
|
2819
|
+
console.log("A beagle under launchd/pm2 comes back on its own; one started by hand in a terminal just exits — start it again there.");
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2822
|
+
throw err;
|
|
2823
|
+
}
|
|
2777
2824
|
if (!res.ok)
|
|
2778
2825
|
throw new Error(`Daemon refused: ${res.error}`);
|
|
2779
2826
|
const data = res.data;
|
package/dist/ui/desktop/app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
window.__DK_UI_VERSION="0.1.
|
|
1
|
+
window.__DK_UI_VERSION="0.1.296";
|
|
2
2
|
const ICON_PATHS = {
|
|
3
3
|
// ---- tab bar (the four must feel like one set) ----
|
|
4
4
|
users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.296",
|
|
4
4
|
"description": "Private virtual LAN for self-hosted services and AI agents, built on Elastos Carrier. NAT-traversal, name service, ACL, all over a peer-to-peer mesh — no public IP required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|