@decentnetwork/beagle 0.1.85 → 0.1.87
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 +6 -5
- package/dist/server.js +46 -27
- 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.86";
|
|
2
2
|
"use strict";
|
|
3
3
|
(() => {
|
|
4
4
|
// packages/beagle-ui/dist/beagle-ui.js
|
|
@@ -4317,8 +4317,9 @@ ${peer.address}`
|
|
|
4317
4317
|
Object.assign(window, { useTweaks });
|
|
4318
4318
|
function ownershipFix(info) {
|
|
4319
4319
|
const r = String(info && info.selfUpdateBlocked || "");
|
|
4320
|
-
const at = r.indexOf("sudo
|
|
4321
|
-
|
|
4320
|
+
const at = r.indexOf("sudo npm i -g");
|
|
4321
|
+
const end = at >= 0 ? r.indexOf(".", at) : -1;
|
|
4322
|
+
return at >= 0 ? r.slice(at, end > at ? end : void 0) : "sudo npm i -g @decentnetwork/beagle@latest";
|
|
4322
4323
|
}
|
|
4323
4324
|
function dkParseDeepLinkAddress() {
|
|
4324
4325
|
try {
|
|
@@ -4860,7 +4861,7 @@ ${peer.address}`
|
|
|
4860
4861
|
lineHeight: 1.6,
|
|
4861
4862
|
borderLeft: "2px solid var(--danger)",
|
|
4862
4863
|
paddingLeft: 10
|
|
4863
|
-
} }, T.updNoPerm || "
|
|
4864
|
+
} }, T.updNoPerm || "This install lives under a system-owned prefix, so updating it is a privileged operation and this button cannot do it. Run it in a terminal:", /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 6, alignItems: "center", marginTop: 6 } }, /* @__PURE__ */ React.createElement("code", { style: {
|
|
4864
4865
|
flex: 1,
|
|
4865
4866
|
minWidth: 0,
|
|
4866
4867
|
fontFamily: "var(--mono)",
|
|
@@ -4872,7 +4873,7 @@ ${peer.address}`
|
|
|
4872
4873
|
padding: "8px 10px",
|
|
4873
4874
|
userSelect: "all",
|
|
4874
4875
|
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" && (() => {
|
|
4876
|
+
} }, 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 || "Do not widen permissions there to make this button work \u2014 a group-writable bin directory lets any admin user replace programs that root later runs. For one-click updates, move npm out of the system prefix instead: `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
4877
|
const m = /`([^`]+)`/.exec(err || "");
|
|
4877
4878
|
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
4879
|
})(), /* @__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
|
@@ -350,11 +350,14 @@ async function npmGlobalInstall(pkg) {
|
|
|
350
350
|
return { ok: false, error: `npm not found — update manually: npm i -g ${pkg}@latest` };
|
|
351
351
|
}
|
|
352
352
|
/**
|
|
353
|
-
* Whether this process could
|
|
353
|
+
* Whether this process could perform a global update at all.
|
|
354
354
|
*
|
|
355
|
-
* Checked up front so the
|
|
356
|
-
*
|
|
357
|
-
*
|
|
355
|
+
* Checked up front so the card can say what is actually true instead of
|
|
356
|
+
* offering a button that fails. A real access() on each directory npm has to
|
|
357
|
+
* write, not a guess from the uid: the package dir it rewrites, the bin dir it
|
|
358
|
+
* re-links through, and the cache it downloads into. Checking only the first
|
|
359
|
+
* reported "you can update" on a machine that then failed on the bin links,
|
|
360
|
+
* and then again on the cache.
|
|
358
361
|
*/
|
|
359
362
|
async function globalNpmWritable() {
|
|
360
363
|
try {
|
|
@@ -366,12 +369,11 @@ async function globalNpmWritable() {
|
|
|
366
369
|
return { ok: true }; // nothing installed there yet
|
|
367
370
|
const { access } = await import("node:fs/promises");
|
|
368
371
|
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.
|
|
373
372
|
await access(scope, constants.W_OK);
|
|
374
373
|
await access(join(prefix, "bin"), constants.W_OK);
|
|
374
|
+
const cache = await npmCacheDir();
|
|
375
|
+
if (cache && existsSync(cache))
|
|
376
|
+
await access(cache, constants.W_OK);
|
|
375
377
|
return { ok: true };
|
|
376
378
|
}
|
|
377
379
|
catch {
|
|
@@ -379,38 +381,55 @@ async function globalNpmWritable() {
|
|
|
379
381
|
}
|
|
380
382
|
}
|
|
381
383
|
/**
|
|
382
|
-
*
|
|
384
|
+
* What to tell someone whose global npm directory this process cannot write.
|
|
383
385
|
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
386
|
+
* NOT a permission change. Two earlier versions of this were.
|
|
387
|
+
*
|
|
388
|
+
* The first said `sudo npm i -g`, which works and leaves the package directory
|
|
389
|
+
* root-owned, so the next unprivileged update fails identically — the advice
|
|
390
|
+
* was what kept people in the loop.
|
|
391
|
+
*
|
|
392
|
+
* The second said `chgrp -R admin` plus `chmod -R g+w` on the bin directory.
|
|
393
|
+
* On the machine it was run on that made node, npm, docker and kubectl
|
|
394
|
+
* writable by every admin user, while the daemon runs as root out of that same
|
|
395
|
+
* /usr/local/bin/node — a root escalation traded for a convenience button. The
|
|
396
|
+
* user stopped it before it did any harm, and was right to.
|
|
397
|
+
*
|
|
398
|
+
* A root-owned prefix is not a misconfiguration to repair. It is the machine
|
|
399
|
+
* saying installs there are privileged. So: say the button cannot do it, give
|
|
400
|
+
* the command to run by hand, and name the one change that removes the problem
|
|
401
|
+
* without weakening anything — moving npm's prefix into $HOME.
|
|
389
402
|
*/
|
|
390
403
|
async function globalNpmOwnershipHint(pkg) {
|
|
391
404
|
const prefix = await npmGlobalPrefix();
|
|
392
405
|
if (!prefix) {
|
|
393
|
-
return `no write access to the global npm
|
|
406
|
+
return `no write access to the global npm directory — update in a terminal with \`sudo npm i -g ${pkg}@latest\`.`;
|
|
394
407
|
}
|
|
395
408
|
const scope = join(prefix, "lib", "node_modules", "@decentnetwork");
|
|
396
|
-
const
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
409
|
+
const cache = await npmCacheDir();
|
|
410
|
+
const cacheNote = cache
|
|
411
|
+
? ` If npm also complains about its cache, that one IS yours to fix: sudo chown -R $(id -u):$(id -g) ${cache}.`
|
|
412
|
+
: "";
|
|
413
|
+
return (`${scope} belongs to root, so updates here are privileged and this button cannot perform them. ` +
|
|
414
|
+
`Update in a terminal: sudo npm i -g ${pkg}@latest.${cacheNote} ` +
|
|
415
|
+
`For one-click updates instead, move npm out of the system prefix — ` +
|
|
416
|
+
`\`npm config set prefix ~/.npm-global\`, then put ~/.npm-global/bin first on PATH. ` +
|
|
417
|
+
`Do not widen permissions under ${prefix} to make this button work.`);
|
|
418
|
+
}
|
|
419
|
+
/** `npm config get cache`, or undefined if npm cannot be reached. */
|
|
420
|
+
async function npmCacheDir() {
|
|
421
|
+
return npmQuery(["config", "get", "cache"]);
|
|
407
422
|
}
|
|
408
423
|
/** `npm prefix -g`, or undefined if npm cannot be reached. */
|
|
409
424
|
async function npmGlobalPrefix() {
|
|
425
|
+
return npmQuery(["prefix", "-g"]);
|
|
426
|
+
}
|
|
427
|
+
/** Run `npm <args>` and return its single-line answer. */
|
|
428
|
+
async function npmQuery(args) {
|
|
410
429
|
const { spawn } = await import("node:child_process");
|
|
411
430
|
return new Promise((res) => {
|
|
412
431
|
try {
|
|
413
|
-
const ch = spawn("npm",
|
|
432
|
+
const ch = spawn("npm", args, { shell: process.platform === "win32" });
|
|
414
433
|
let out = "";
|
|
415
434
|
const timer = setTimeout(() => ch.kill("SIGKILL"), 10_000);
|
|
416
435
|
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.87",
|
|
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.7",
|
|
38
38
|
"@types/js-yaml": "^4.0.9",
|
|
39
39
|
"@types/node": "^20.11.0",
|
|
40
40
|
"@types/yargs": "^17.0.32",
|