@nordbyte/nordrelay 0.3.0 → 0.3.1
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/CHANGELOG.md +9 -0
- package/README.md +24 -18
- package/dist/bot.js +5 -2
- package/dist/codex-session.js +3 -1
- package/dist/context-key.js +23 -0
- package/dist/operations.js +1 -1
- package/dist/relay-runtime.js +436 -7
- package/dist/session-registry.js +3 -3
- package/dist/settings-service.js +46 -23
- package/dist/state-backend.js +17 -8
- package/dist/web-dashboard.js +159 -33
- package/dist/web-state.js +131 -0
- package/docker-compose.yml +1 -1
- package/package.json +1 -1
- package/plugins/nordrelay/scripts/nordrelay.mjs +42 -17
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ const SCRIPT_PATH = fileURLToPath(import.meta.url);
|
|
|
16
16
|
const PLUGIN_ROOT = path.resolve(path.dirname(SCRIPT_PATH), "..");
|
|
17
17
|
const DEFAULT_MARKETPLACE_ROOT = path.resolve(PLUGIN_ROOT, "../..");
|
|
18
18
|
const RUNTIME_ROOT = findRuntimeRoot();
|
|
19
|
-
const DEFAULT_HOME = path.join(os.homedir(), ".
|
|
19
|
+
const DEFAULT_HOME = path.join(os.homedir(), ".nordrelay");
|
|
20
20
|
|
|
21
21
|
function nowIso() {
|
|
22
22
|
return new Date().toISOString();
|
|
@@ -77,16 +77,11 @@ async function mkdirp(dir) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function loadEnvFiles(home) {
|
|
80
|
-
const
|
|
81
|
-
path.
|
|
82
|
-
path.join(
|
|
83
|
-
path.join(PLUGIN_ROOT, ".env"),
|
|
84
|
-
path.join(home, "nordrelay.env"),
|
|
85
|
-
];
|
|
80
|
+
const envPath = process.env.NORDRELAY_ENV_FILE
|
|
81
|
+
? path.resolve(process.env.NORDRELAY_ENV_FILE)
|
|
82
|
+
: path.join(home, "nordrelay.env");
|
|
86
83
|
|
|
87
|
-
|
|
88
|
-
loadEnvFile(envPath);
|
|
89
|
-
}
|
|
84
|
+
loadEnvFile(envPath);
|
|
90
85
|
|
|
91
86
|
normalizeEnvAliases();
|
|
92
87
|
}
|
|
@@ -207,7 +202,7 @@ async function commandStart(options) {
|
|
|
207
202
|
await fsp.rm(options.pidFile, { force: true });
|
|
208
203
|
}
|
|
209
204
|
console.log(`Startup failed. Log: ${options.logFile}`);
|
|
210
|
-
console.log(state.error || "Unknown error");
|
|
205
|
+
console.log(state.error || await readStartupError(options.logFile) || "Unknown error");
|
|
211
206
|
process.exitCode = 1;
|
|
212
207
|
return;
|
|
213
208
|
}
|
|
@@ -332,7 +327,8 @@ async function commandDoctor(options) {
|
|
|
332
327
|
checks.push(check("Codex CLI", Boolean(findExecutable(process.env.CODEX_CLI_PATH || "codex")), process.env.CODEX_CLI_PATH || findExecutable("codex") || "not found", process.env.NORDRELAY_CODEX_ENABLED === "false" ? "warn" : "fail"));
|
|
333
328
|
checks.push(check("Pi CLI", Boolean(findExecutable(process.env.PI_CLI_PATH || "pi")), process.env.PI_CLI_PATH || findExecutable("pi") || "not found", process.env.NORDRELAY_PI_ENABLED === "true" ? "fail" : "warn"));
|
|
334
329
|
checks.push(check("ffmpeg", Boolean(findExecutable("ffmpeg")), findExecutable("ffmpeg") || "not found", "warn"));
|
|
335
|
-
|
|
330
|
+
const stateBackendCheck = validateStateBackend();
|
|
331
|
+
checks.push(check("State backend", stateBackendCheck.ok, stateBackendCheck.detail));
|
|
336
332
|
checks.push(check("Runtime entry", Boolean(await resolveRuntimeEntry()), RUNTIME_ROOT));
|
|
337
333
|
|
|
338
334
|
for (const item of checks) {
|
|
@@ -439,12 +435,14 @@ async function commandForeground(options) {
|
|
|
439
435
|
child.once("exit", (code, signal) => resolve({ code, signal }));
|
|
440
436
|
});
|
|
441
437
|
|
|
438
|
+
const previousState = await readJson(options.stateFile, {});
|
|
442
439
|
await writeJsonAtomic(options.stateFile, {
|
|
443
440
|
status: exit.code === 0 ? "stopped" : "error",
|
|
444
441
|
pid: process.pid,
|
|
445
442
|
updatedAt: nowIso(),
|
|
446
443
|
exitCode: exit.code,
|
|
447
444
|
signal: exit.signal,
|
|
445
|
+
error: exit.code === 0 ? undefined : previousState.error,
|
|
448
446
|
logFile: options.logFile,
|
|
449
447
|
});
|
|
450
448
|
|
|
@@ -550,13 +548,40 @@ function findExecutable(command) {
|
|
|
550
548
|
|
|
551
549
|
function validateStateBackend() {
|
|
552
550
|
const backend = process.env.NORDRELAY_STATE_BACKEND || "json";
|
|
553
|
-
if (backend === "json") return true;
|
|
554
|
-
if (backend !== "sqlite") return false;
|
|
551
|
+
if (backend === "json") return { ok: true, detail: "NORDRELAY_STATE_BACKEND=json" };
|
|
552
|
+
if (backend !== "sqlite") return { ok: false, detail: `Invalid NORDRELAY_STATE_BACKEND=${backend}` };
|
|
555
553
|
try {
|
|
556
|
-
require("better-sqlite3");
|
|
557
|
-
|
|
554
|
+
const Database = require("better-sqlite3");
|
|
555
|
+
const filePath = path.join(process.cwd(), ".nordrelay", "state.sqlite");
|
|
556
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
557
|
+
const db = new Database(filePath);
|
|
558
|
+
db.exec([
|
|
559
|
+
"CREATE TABLE IF NOT EXISTS documents (",
|
|
560
|
+
"key TEXT PRIMARY KEY,",
|
|
561
|
+
"json TEXT NOT NULL,",
|
|
562
|
+
"updated_at TEXT NOT NULL",
|
|
563
|
+
")",
|
|
564
|
+
].join(" "));
|
|
565
|
+
db.close?.();
|
|
566
|
+
return { ok: true, detail: `NORDRELAY_STATE_BACKEND=sqlite (${filePath})` };
|
|
567
|
+
} catch (error) {
|
|
568
|
+
return {
|
|
569
|
+
ok: false,
|
|
570
|
+
detail: `NORDRELAY_STATE_BACKEND=sqlite failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
async function readStartupError(logFile) {
|
|
576
|
+
try {
|
|
577
|
+
const lines = (await fsp.readFile(logFile, "utf8")).split(/\r?\n/).filter(Boolean).slice(-80).reverse();
|
|
578
|
+
const startupLine = lines.find((line) => line.includes("Failed to start NordRelay:"));
|
|
579
|
+
if (startupLine) return startupLine.replace(/^.*Failed to start NordRelay:\s*/, "");
|
|
580
|
+
const errorLine = lines.find((line) => /\bERROR\b/i.test(line));
|
|
581
|
+
if (errorLine) return errorLine;
|
|
582
|
+
return lines[0] || null;
|
|
558
583
|
} catch {
|
|
559
|
-
return
|
|
584
|
+
return null;
|
|
560
585
|
}
|
|
561
586
|
}
|
|
562
587
|
|