@decentnetwork/beagle 0.1.84 → 0.1.86
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/desktop/app.js +2 -2
- package/dist/server.js +47 -3
- package/package.json +2 -2
package/dist/desktop/app.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
window.__DK_UI_VERSION="0.1.
|
|
1
|
+
window.__DK_UI_VERSION="0.1.85";
|
|
2
2
|
"use strict";
|
|
3
3
|
(() => {
|
|
4
4
|
// packages/beagle-ui/dist/beagle-ui.js
|
|
@@ -4872,7 +4872,7 @@ ${peer.address}`
|
|
|
4872
4872
|
padding: "8px 10px",
|
|
4873
4873
|
userSelect: "all",
|
|
4874
4874
|
wordBreak: "break-all"
|
|
4875
|
-
} }, ownershipFix(info)), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy(ownershipFix(info)) }))), phase === "idle" && appBehind && info.mode === "dev" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updDev || "Running from a source checkout \u2014 update with:", /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("code", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)" } }, "git pull && npm run build")), phase === "idle" && appBehind && info.mode === "unknown" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updUnknown || "Update now runs the global install. If that is not how this was installed, run:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, "npm i -g @decentnetwork/beagle@latest"), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy("npm i -g @decentnetwork/beagle@latest") }))), phase === "idle" && appBehind && info.mode === "npx" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updNpx || "Running via npx \u2014 restarting picks up the latest version automatically."), daemonPeerBehind && phase === "idle" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updPeerDaemon || "The peer version belongs to the running agentnet daemon, not to this app. Update it with:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, "npm i -g @decentnetwork/lan@latest && agentnet restart"), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy("npm i -g @decentnetwork/lan@latest && agentnet restart") }))), lanBehind && phase === "idle" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updLanNote || "agentnet (lan): one click reinstalls it and asks the running daemon to restart itself. Manual equivalent:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, "npm i -g @decentnetwork/lan@latest && agentnet restart"), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy("npm i -g @decentnetwork/lan@latest && agentnet restart") }))), phase === "lan-done" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--online)" } }, T.updLanDone || "lan updated \u2014 daemon restarted with the new version \u2713"), phase === "lan-norestart" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--warn, #f59e0b)" } }, T.updLanNoRestart || "lan updated, but the daemon was not running (or refused) \u2014 the new version applies on its next start."), phase === "running" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--dim)" } }, T.updBusy || "Updating\u2026 (about a minute)"), phase === "done" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--online)" } }, T.updDone || "Updated \u2014 restart to apply."), phase === "restarting" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--dim)" } }, T.updRestarting || "Restarting\u2026 this page reloads when it\u2019s back. (If beagle was started by hand in a terminal, run it again.)"), phase === "error" && (() => {
|
|
4875
|
+
} }, ownershipFix(info)), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy(ownershipFix(info)) })), /* @__PURE__ */ React.createElement("div", { style: { marginTop: 6, fontSize: 11.5, color: "var(--faint)" } }, T.updNoPermAlt || "It touches only the directory, not the programs inside it. If you would rather not change anything under /usr/local, the alternative is to move npm out of it: `npm config set prefix ~/.npm-global`, then put `~/.npm-global/bin` first on your PATH.")), phase === "idle" && appBehind && info.mode === "dev" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updDev || "Running from a source checkout \u2014 update with:", /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("code", { style: { fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)" } }, "git pull && npm run build")), phase === "idle" && appBehind && info.mode === "unknown" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updUnknown || "Update now runs the global install. If that is not how this was installed, run:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, "npm i -g @decentnetwork/beagle@latest"), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy("npm i -g @decentnetwork/beagle@latest") }))), phase === "idle" && appBehind && info.mode === "npx" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updNpx || "Running via npx \u2014 restarting picks up the latest version automatically."), daemonPeerBehind && phase === "idle" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updPeerDaemon || "The peer version belongs to the running agentnet daemon, not to this app. Update it with:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, "npm i -g @decentnetwork/lan@latest && agentnet restart"), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy("npm i -g @decentnetwork/lan@latest && agentnet restart") }))), lanBehind && phase === "idle" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--dim)", lineHeight: 1.5 } }, T.updLanNote || "agentnet (lan): one click reinstalls it and asks the running daemon to restart itself. Manual equivalent:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, "npm i -g @decentnetwork/lan@latest && agentnet restart"), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy("npm i -g @decentnetwork/lan@latest && agentnet restart") }))), phase === "lan-done" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--online)" } }, T.updLanDone || "lan updated \u2014 daemon restarted with the new version \u2713"), phase === "lan-norestart" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--warn, #f59e0b)" } }, T.updLanNoRestart || "lan updated, but the daemon was not running (or refused) \u2014 the new version applies on its next start."), phase === "running" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--dim)" } }, T.updBusy || "Updating\u2026 (about a minute)"), phase === "done" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--online)" } }, T.updDone || "Updated \u2014 restart to apply."), phase === "restarting" && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12.5, color: "var(--dim)" } }, T.updRestarting || "Restarting\u2026 this page reloads when it\u2019s back. (If beagle was started by hand in a terminal, run it again.)"), phase === "error" && (() => {
|
|
4876
4876
|
const m = /`([^`]+)`/.exec(err || "");
|
|
4877
4877
|
return /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 12, color: "var(--danger)", wordBreak: "break-word" } }, m ? err.replace("`" + m[1] + "`", "") : err), m && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: 8 } }, /* @__PURE__ */ React.createElement("code", { style: { flex: 1, minWidth: 0, fontFamily: "var(--mono)", fontSize: 11.5, color: "var(--text)", background: "var(--panel-2)", border: "1px solid var(--line)", borderRadius: 8, padding: "8px 10px", userSelect: "all", wordBreak: "break-all" } }, m[1]), /* @__PURE__ */ React.createElement(Btn, { size: "sm", icon: "copy", title: T.copy || "Copy", onClick: () => dkCopy(m[1]) })), m && /* @__PURE__ */ React.createElement("div", { style: { fontFamily: "var(--ui)", fontSize: 11.5, color: "var(--dim)" } }, T.updManualHint || "Run it in a terminal, then click Restart to apply."));
|
|
4878
4878
|
})(), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 } }, (phase === "idle" || phase === "error" || phase === "lan-done" || phase === "lan-norestart") && btn(phase === "idle" ? T.updLater || "Later" : T.receivedClose || "Close", onClose), phase === "idle" && lanBehind && btn(T.updLanNow || "Update lan", doLanUpdate, !appBehind), phase === "idle" && appBehind && (info.mode === "global" || info.mode === "unknown") && btn(T.updNow || "Update now", doUpdate, true), phase === "idle" && appBehind && info.mode === "npx" && btn(T.updRestart || "Restart", doRestart, true), phase === "error" && btn(T.updRestart || "Restart", doRestart, true), phase === "done" && btn(T.updRestart || "Restart", doRestart, true))));
|
package/dist/server.js
CHANGED
|
@@ -366,7 +366,18 @@ async function globalNpmWritable() {
|
|
|
366
366
|
return { ok: true }; // nothing installed there yet
|
|
367
367
|
const { access } = await import("node:fs/promises");
|
|
368
368
|
const { constants } = await import("node:fs");
|
|
369
|
+
// BOTH, and both as directories. npm rewrites the package directory and
|
|
370
|
+
// re-links the binaries, and either one being unwritable stops the update.
|
|
371
|
+
// Checking only the scope reported "you can update" on a machine that then
|
|
372
|
+
// failed on the bin links.
|
|
369
373
|
await access(scope, constants.W_OK);
|
|
374
|
+
await access(join(prefix, "bin"), constants.W_OK);
|
|
375
|
+
// And the cache. A root-owned ~/.npm fails the install just as hard, and
|
|
376
|
+
// reporting "you can update" because the other two were fine is the same
|
|
377
|
+
// false promise this check exists to stop making.
|
|
378
|
+
const cache = await npmCacheDir();
|
|
379
|
+
if (cache && existsSync(cache))
|
|
380
|
+
await access(cache, constants.W_OK);
|
|
370
381
|
return { ok: true };
|
|
371
382
|
}
|
|
372
383
|
catch {
|
|
@@ -388,17 +399,50 @@ async function globalNpmOwnershipHint(pkg) {
|
|
|
388
399
|
return `no write access to the global npm dir. \`sudo npm i -g ${pkg}@latest\` would work but leaves it root-owned, so the next update fails the same way — fix the ownership once instead.`;
|
|
389
400
|
}
|
|
390
401
|
const scope = join(prefix, "lib", "node_modules", "@decentnetwork");
|
|
391
|
-
const
|
|
402
|
+
const bin = join(prefix, "bin");
|
|
403
|
+
// Both DIRECTORIES, not the files inside them. Replacing a package directory
|
|
404
|
+
// or a bin symlink is a rename, and rename needs write permission on the
|
|
405
|
+
// CONTAINING directory — naming the symlinks themselves does nothing when
|
|
406
|
+
// their parent is root-owned. An earlier version of this hint listed
|
|
407
|
+
// bin/agentnet and bin/beagle and left people exactly as stuck, one error
|
|
408
|
+
// further along: the scope chown succeeded and npm then failed on the bin
|
|
409
|
+
// links instead.
|
|
410
|
+
const cache = await npmCacheDir();
|
|
411
|
+
// Three places, because a sudo install poisons three: the package directory
|
|
412
|
+
// it rewrites, the bin directory it re-links through, and the cache it
|
|
413
|
+
// downloads into. Fixing them one at a time just moves the error along —
|
|
414
|
+
// watched exactly that happen on one machine, three rounds, each ending in a
|
|
415
|
+
// different npm message.
|
|
416
|
+
//
|
|
417
|
+
// The bin line is deliberately narrow, and an earlier version of it was not.
|
|
418
|
+
// It said `chgrp -R admin` plus `chmod -R g+w`, which hands every admin user
|
|
419
|
+
// write access to every binary in a shared directory — a way to replace
|
|
420
|
+
// something another user, or root, will run. Creating or replacing a symlink
|
|
421
|
+
// needs write on the CONTAINING directory and nothing else, so: no -R, no
|
|
422
|
+
// group bit, no touching the files inside. Mode stays 755 and only this user
|
|
423
|
+
// gains write.
|
|
424
|
+
//
|
|
425
|
+
// The cleaner answer for anyone willing to change their PATH is not to touch
|
|
426
|
+
// /usr/local at all — `npm config set prefix ~/.npm-global` and put its bin
|
|
427
|
+
// first. That needs more than one line, so the card says it in prose.
|
|
392
428
|
return (`no write access to ${scope}. This is what a first install with sudo leaves behind, and ` +
|
|
393
429
|
`\`sudo npm i -g\` would rebuild it — run this ONCE and updates never need sudo again: ` +
|
|
394
|
-
`sudo chown -R $(id -u):$(id -g) ${scope} ${
|
|
430
|
+
`sudo chown -R $(id -u):$(id -g) ${scope}${cache ? ` ${cache}` : ""} && sudo chown $(id -u) ${bin}`);
|
|
431
|
+
}
|
|
432
|
+
/** `npm config get cache`, or undefined if npm cannot be reached. */
|
|
433
|
+
async function npmCacheDir() {
|
|
434
|
+
return npmQuery(["config", "get", "cache"]);
|
|
395
435
|
}
|
|
396
436
|
/** `npm prefix -g`, or undefined if npm cannot be reached. */
|
|
397
437
|
async function npmGlobalPrefix() {
|
|
438
|
+
return npmQuery(["prefix", "-g"]);
|
|
439
|
+
}
|
|
440
|
+
/** Run `npm <args>` and return its single-line answer. */
|
|
441
|
+
async function npmQuery(args) {
|
|
398
442
|
const { spawn } = await import("node:child_process");
|
|
399
443
|
return new Promise((res) => {
|
|
400
444
|
try {
|
|
401
|
-
const ch = spawn("npm",
|
|
445
|
+
const ch = spawn("npm", args, { shell: process.platform === "win32" });
|
|
402
446
|
let out = "";
|
|
403
447
|
const timer = setTimeout(() => ch.kill("SIGKILL"), 10_000);
|
|
404
448
|
ch.stdout?.on("data", (c) => (out += c));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/beagle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.86",
|
|
4
4
|
"description": "Beagle — P2P chat, file transfer and calls for regular users, on the Decent Network. No admin privilege required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"yargs": "^17.7.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@decentnetwork/beagle-ui": "^0.2.
|
|
37
|
+
"@decentnetwork/beagle-ui": "^0.2.6",
|
|
38
38
|
"@types/js-yaml": "^4.0.9",
|
|
39
39
|
"@types/node": "^20.11.0",
|
|
40
40
|
"@types/yargs": "^17.0.32",
|