@decentnetwork/lan 0.1.52 → 0.1.53
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.d.ts +10 -0
- package/dist/cli/commands.js +80 -0
- package/dist/cli/index.js +4 -1
- package/package.json +1 -1
package/dist/cli/commands.d.ts
CHANGED
|
@@ -269,6 +269,16 @@ export declare function cmdDnsHosts(args: {
|
|
|
269
269
|
export declare function cmdDiag(args: {
|
|
270
270
|
configDir?: string;
|
|
271
271
|
}): Promise<void>;
|
|
272
|
+
/**
|
|
273
|
+
* `agentnet doctor` — a self-service health check. Walks the common
|
|
274
|
+
* failure points we keep hitting (config in the wrong place under sudo,
|
|
275
|
+
* daemon down, no dora, peers stuck "connecting" because the other end
|
|
276
|
+
* runs old code) and prints the exact fix for each, so a user can debug
|
|
277
|
+
* without reading source or asking anyone.
|
|
278
|
+
*/
|
|
279
|
+
export declare function cmdDoctor(args: {
|
|
280
|
+
configDir?: string;
|
|
281
|
+
}): Promise<void>;
|
|
272
282
|
/**
|
|
273
283
|
* Enable dora integration. Accepts either `--address` (preferred — the
|
|
274
284
|
* full Carrier address of the dora server; we derive its userid and
|
package/dist/cli/commands.js
CHANGED
|
@@ -1267,6 +1267,86 @@ export async function cmdDiag(args) {
|
|
|
1267
1267
|
}
|
|
1268
1268
|
console.log(JSON.stringify(res.data, null, 2));
|
|
1269
1269
|
}
|
|
1270
|
+
/**
|
|
1271
|
+
* `agentnet doctor` — a self-service health check. Walks the common
|
|
1272
|
+
* failure points we keep hitting (config in the wrong place under sudo,
|
|
1273
|
+
* daemon down, no dora, peers stuck "connecting" because the other end
|
|
1274
|
+
* runs old code) and prints the exact fix for each, so a user can debug
|
|
1275
|
+
* without reading source or asking anyone.
|
|
1276
|
+
*/
|
|
1277
|
+
export async function cmdDoctor(args) {
|
|
1278
|
+
const ok = (s) => console.log(` ✓ ${s}`);
|
|
1279
|
+
const bad = (s, fix) => {
|
|
1280
|
+
console.log(` ✗ ${s}`);
|
|
1281
|
+
if (fix)
|
|
1282
|
+
console.log(` → ${fix}`);
|
|
1283
|
+
};
|
|
1284
|
+
const info = (s) => console.log(` · ${s}`);
|
|
1285
|
+
console.log("agentnet doctor\n");
|
|
1286
|
+
// 1. Resolve config dir, working around the sudo HOME trap: under
|
|
1287
|
+
// `sudo` ~ resolves to /root, but the config usually lives in the
|
|
1288
|
+
// invoking user's home — the #1 "Not initialized" confusion.
|
|
1289
|
+
let dir = args.configDir || ConfigLoader.defaultConfigDir();
|
|
1290
|
+
let configPath = resolve(dir, "config.yaml");
|
|
1291
|
+
if (!existsSync(configPath) && process.env.SUDO_USER) {
|
|
1292
|
+
const altDir = resolve(`/home/${process.env.SUDO_USER}`, ".agentnet");
|
|
1293
|
+
if (existsSync(resolve(altDir, "config.yaml"))) {
|
|
1294
|
+
info(`Config not in ${dir} (running under sudo); using ${altDir}`);
|
|
1295
|
+
dir = altDir;
|
|
1296
|
+
configPath = resolve(altDir, "config.yaml");
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
if (!existsSync(configPath)) {
|
|
1300
|
+
bad(`No config at ${configPath}`, "run: agentnet init");
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
ok(`Config: ${configPath}`);
|
|
1304
|
+
const config = await ConfigLoader.load(configPath);
|
|
1305
|
+
// 2. Daemon running?
|
|
1306
|
+
const pid = daemonPid(config);
|
|
1307
|
+
if (pid === null) {
|
|
1308
|
+
bad("Daemon is not running", `start it: sudo agentnet up --real-tun --config-dir ${dir}`);
|
|
1309
|
+
info("Logs go to /var/log/agentnet.log (NOT journalctl) when run as a service.");
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
ok(`Daemon running (pid ${pid})`);
|
|
1313
|
+
const res = await ipcCall(config, { op: "diag" });
|
|
1314
|
+
if (!res.ok) {
|
|
1315
|
+
bad(`Daemon not responding over IPC: ${res.error}`, "restart it");
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
const d = res.data;
|
|
1319
|
+
if (d.identity?.address)
|
|
1320
|
+
ok(`Identity: ${d.identity.address}`);
|
|
1321
|
+
const ip = d.tun?.ip || d.allocatedIp;
|
|
1322
|
+
if (ip)
|
|
1323
|
+
ok(`Virtual IP: ${ip}`);
|
|
1324
|
+
// 3. Dora connectivity — needed for auto-discovery of peers.
|
|
1325
|
+
const friends = d.friends ?? [];
|
|
1326
|
+
const ipamMap = new Map((d.ipam ?? []).map((p) => [p.carrierId ?? "", p]));
|
|
1327
|
+
const doraIds = new Set(DEFAULT_DORAS.map((x) => x.userid));
|
|
1328
|
+
const idOf = (f) => f.carrierId || f.pubkey || "";
|
|
1329
|
+
const nameOf = (f) => {
|
|
1330
|
+
const real = f.name && f.name !== "@decentnetwork/peer" ? f.name : undefined;
|
|
1331
|
+
const ix = ipamMap.get(idOf(f));
|
|
1332
|
+
const ipPart = ix?.virtualIp ? ` ${ix.virtualIp}` : "";
|
|
1333
|
+
return `${real || ix?.name || idOf(f).slice(0, 8) + "…"}${ipPart}`;
|
|
1334
|
+
};
|
|
1335
|
+
const doraOnline = friends.filter((f) => doraIds.has(idOf(f)) && f.status === "online");
|
|
1336
|
+
if (doraOnline.length > 0)
|
|
1337
|
+
ok(`Dora registry connected (${doraOnline.length} online) — peer auto-discovery active`);
|
|
1338
|
+
else
|
|
1339
|
+
bad("No dora registry online — can't auto-discover peers", "give it ~60s after start; check internet / that a dora is up");
|
|
1340
|
+
// 4. Friends — who's connected vs stuck connecting (and why).
|
|
1341
|
+
const online = friends.filter((f) => f.status === "online");
|
|
1342
|
+
const connecting = friends.filter((f) => f.status !== "online");
|
|
1343
|
+
info(`Peers: ${online.length} connected, ${connecting.length} connecting`);
|
|
1344
|
+
for (const f of online)
|
|
1345
|
+
ok(`${nameOf(f)} — connected`);
|
|
1346
|
+
for (const f of connecting)
|
|
1347
|
+
info(`${nameOf(f)} — connecting (other end offline, or upgraded-but-not-restarted: restart its daemon)`);
|
|
1348
|
+
console.log("\n Watch live: sudo tail -f /var/log/agentnet.log (\"Peers:\" line every 30s)");
|
|
1349
|
+
}
|
|
1270
1350
|
/**
|
|
1271
1351
|
* Enable dora integration. Accepts either `--address` (preferred — the
|
|
1272
1352
|
* full Carrier address of the dora server; we derive its userid and
|
package/dist/cli/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { hideBin } from "yargs/helpers";
|
|
|
10
10
|
// Belt-and-braces — also raise it here in case the CLI is run directly
|
|
11
11
|
// (e.g. `node dist/cli/index.js` rather than via dist/index.js).
|
|
12
12
|
EventEmitter.defaultMaxListeners = 100;
|
|
13
|
-
import { cmdInit, cmdIdentityShow, cmdPeersList, cmdIpamAssign, cmdGrant, cmdRevoke, cmdResolve, cmdStatus, cmdUp, cmdAuditLog, cmdFriendRequest, cmdFriendAccept, cmdFriendsList, cmdFriendsPending, cmdFriendsAccept, cmdFriendsReject, cmdProxyEnable, cmdProxyDisable, cmdProxyStatus, cmdProxyAllowHost, cmdProxyRevokeHost, cmdProxyListHosts, cmdProxyUse, cmdProxyRouter, cmdDoraEnable, cmdDoraDisable, cmdDoraStatus, cmdDoraAutofriend, cmdDiag, cmdDnsInstall, cmdDnsHosts, cmdServiceInstall, cmdRestart, cmdServiceStatus, } from "./commands.js";
|
|
13
|
+
import { cmdInit, cmdIdentityShow, cmdPeersList, cmdIpamAssign, cmdGrant, cmdRevoke, cmdResolve, cmdStatus, cmdUp, cmdAuditLog, cmdFriendRequest, cmdFriendAccept, cmdFriendsList, cmdFriendsPending, cmdFriendsAccept, cmdFriendsReject, cmdProxyEnable, cmdProxyDisable, cmdProxyStatus, cmdProxyAllowHost, cmdProxyRevokeHost, cmdProxyListHosts, cmdProxyUse, cmdProxyRouter, cmdDoraEnable, cmdDoraDisable, cmdDoraStatus, cmdDoraAutofriend, cmdDiag, cmdDoctor, cmdDnsInstall, cmdDnsHosts, cmdServiceInstall, cmdRestart, cmdServiceStatus, } from "./commands.js";
|
|
14
14
|
async function main() {
|
|
15
15
|
await yargs(hideBin(process.argv))
|
|
16
16
|
.scriptName("agentnet")
|
|
@@ -85,6 +85,9 @@ async function main() {
|
|
|
85
85
|
})
|
|
86
86
|
.command("diag", "Query the running daemon over IPC for a JSON snapshot of its runtime state (stats, friends, IPAM)", (y) => y.option("config-dir", { type: "string" }), async (argv) => {
|
|
87
87
|
await cmdDiag({ configDir: argv["config-dir"] });
|
|
88
|
+
})
|
|
89
|
+
.command("doctor", "Self-check: diagnoses config/daemon/dora/peer problems and prints the fix for each", (y) => y.option("config-dir", { type: "string" }), async (argv) => {
|
|
90
|
+
await cmdDoctor({ configDir: argv["config-dir"] });
|
|
88
91
|
})
|
|
89
92
|
.command("dns", "Manage OS-side DNS resolver wiring for the .decent zone", (y) => y
|
|
90
93
|
.command("install", "Route .decent queries to the local daemon (writes /etc/resolver on macOS or resolvectl on Linux)", (yy) => yy
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentnetwork/lan",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.53",
|
|
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",
|