remosidian 0.1.1 → 0.1.2
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/remosidian.mjs +382 -38
- package/package.json +1 -1
package/dist/remosidian.mjs
CHANGED
|
@@ -14380,7 +14380,11 @@ var __webpack_exports__ = {};
|
|
|
14380
14380
|
|
|
14381
14381
|
// EXPORTS
|
|
14382
14382
|
__nccwpck_require__.d(__webpack_exports__, {
|
|
14383
|
+
gu: () => (/* binding */ buildPairCode),
|
|
14384
|
+
ti: () => (/* binding */ buildPairDeepLink),
|
|
14383
14385
|
lz: () => (/* binding */ buildPairUri),
|
|
14386
|
+
jO: () => (/* binding */ buildServeArgs),
|
|
14387
|
+
YP: () => (/* binding */ createCompactPairingPayload),
|
|
14384
14388
|
wX: () => (/* binding */ expandVaultSpec),
|
|
14385
14389
|
iW: () => (/* binding */ main),
|
|
14386
14390
|
Zy: () => (/* binding */ parseArgs),
|
|
@@ -14388,6 +14392,8 @@ __nccwpck_require__.d(__webpack_exports__, {
|
|
|
14388
14392
|
t0: () => (/* binding */ resolveInvocation)
|
|
14389
14393
|
});
|
|
14390
14394
|
|
|
14395
|
+
;// CONCATENATED MODULE: external "node:child_process"
|
|
14396
|
+
const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:child_process");
|
|
14391
14397
|
;// CONCATENATED MODULE: external "node:fs"
|
|
14392
14398
|
const external_node_fs_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs");
|
|
14393
14399
|
;// CONCATENATED MODULE: external "node:os"
|
|
@@ -14713,8 +14719,6 @@ function loadOrCreateDaemonIdentity(port, identityPath) {
|
|
|
14713
14719
|
return identity;
|
|
14714
14720
|
}
|
|
14715
14721
|
//# sourceMappingURL=identity.js.map
|
|
14716
|
-
;// CONCATENATED MODULE: external "node:child_process"
|
|
14717
|
-
const external_node_child_process_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:child_process");
|
|
14718
14722
|
;// CONCATENATED MODULE: ../../packages/daemon-core/dist/advertised-hosts.js
|
|
14719
14723
|
|
|
14720
14724
|
|
|
@@ -19581,7 +19585,7 @@ function runFileBackedPluginTurn(input, prompt, options, onDelta) {
|
|
|
19581
19585
|
}
|
|
19582
19586
|
//# sourceMappingURL=chat-plugin-runtime.js.map
|
|
19583
19587
|
;// CONCATENATED MODULE: ../remosidian-server/dist/version.js
|
|
19584
|
-
const VERSION = '0.1.
|
|
19588
|
+
const VERSION = '0.1.2';
|
|
19585
19589
|
//# sourceMappingURL=version.js.map
|
|
19586
19590
|
;// CONCATENATED MODULE: ../remosidian-server/dist/chat-runtime.js
|
|
19587
19591
|
|
|
@@ -28063,6 +28067,7 @@ function startTunnel({ port, logDir, tunnelStatePath, resolveLaunchSpec = resolv
|
|
|
28063
28067
|
|
|
28064
28068
|
|
|
28065
28069
|
|
|
28070
|
+
|
|
28066
28071
|
const PROG = 'remosidian';
|
|
28067
28072
|
const PRIMARY_NPM_PACKAGE = '@remosidian/cli';
|
|
28068
28073
|
const ALIAS_NPM_PACKAGE = 'remosidian';
|
|
@@ -28081,9 +28086,11 @@ function helpText() {
|
|
|
28081
28086
|
` ${PROG} <command> [options]`,
|
|
28082
28087
|
'',
|
|
28083
28088
|
'Commands:',
|
|
28084
|
-
' start Start the Remosidian
|
|
28089
|
+
' start Start or reuse the Remosidian background daemon',
|
|
28090
|
+
' serve Internal foreground daemon entrypoint',
|
|
28085
28091
|
' pair Open a one-time pairing window and print a QR code',
|
|
28086
28092
|
' status Print the running daemon health snapshot',
|
|
28093
|
+
' stop Stop the background daemon',
|
|
28087
28094
|
' reset-pairings Revoke every paired device (local only)',
|
|
28088
28095
|
' init Create ~/.remosidian/config.json interactively',
|
|
28089
28096
|
' help Show this help',
|
|
@@ -28105,6 +28112,7 @@ function helpText() {
|
|
|
28105
28112
|
' --bind <address> Bind to this interface (default 0.0.0.0)',
|
|
28106
28113
|
' --agent <name> AI agent for /Ask: claude or codex (auto-detects)',
|
|
28107
28114
|
' --agent-path <path> Override the agent binary path',
|
|
28115
|
+
' --foreground Run the server in the foreground',
|
|
28108
28116
|
' --json Emit a single JSON line instead of human output',
|
|
28109
28117
|
' --no-qr Skip the pairing QR on startup',
|
|
28110
28118
|
].join('\n');
|
|
@@ -28211,6 +28219,69 @@ function resolvePaths(flags) {
|
|
|
28211
28219
|
return createRemosidianPaths(dataDir ?? process.env.REMOSIDIAN_HOME ?? '~/.remosidian');
|
|
28212
28220
|
}
|
|
28213
28221
|
|
|
28222
|
+
function createRuntimePaths(paths) {
|
|
28223
|
+
const runtimeDir = (0,external_node_path_namespaceObject.join)(paths.dataDir, 'runtime', 'current');
|
|
28224
|
+
const logDir = (0,external_node_path_namespaceObject.join)(paths.dataDir, 'logs');
|
|
28225
|
+
return {
|
|
28226
|
+
runtimeDir,
|
|
28227
|
+
runtimeEntryPath: (0,external_node_path_namespaceObject.join)(runtimeDir, 'dist', 'remosidian.mjs'),
|
|
28228
|
+
pidPath: (0,external_node_path_namespaceObject.join)(paths.dataDir, 'daemon.pid'),
|
|
28229
|
+
logDir,
|
|
28230
|
+
stdoutLogPath: (0,external_node_path_namespaceObject.join)(logDir, 'daemon.stdout.log'),
|
|
28231
|
+
stderrLogPath: (0,external_node_path_namespaceObject.join)(logDir, 'daemon.stderr.log'),
|
|
28232
|
+
pairingQrPath: (0,external_node_path_namespaceObject.join)(paths.dataDir, 'pairing-qr.png'),
|
|
28233
|
+
pairingCodePath: (0,external_node_path_namespaceObject.join)(paths.dataDir, 'pairing-code.txt'),
|
|
28234
|
+
};
|
|
28235
|
+
}
|
|
28236
|
+
|
|
28237
|
+
function readPidFile(pidPath) {
|
|
28238
|
+
try {
|
|
28239
|
+
const pid = Number((0,external_node_fs_namespaceObject.readFileSync)(pidPath, 'utf8').trim());
|
|
28240
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
28241
|
+
} catch {
|
|
28242
|
+
return null;
|
|
28243
|
+
}
|
|
28244
|
+
}
|
|
28245
|
+
|
|
28246
|
+
function writePidFile(pidPath, pid) {
|
|
28247
|
+
(0,external_node_fs_namespaceObject.mkdirSync)((0,external_node_path_namespaceObject.dirname)(pidPath), { recursive: true });
|
|
28248
|
+
(0,external_node_fs_namespaceObject.writeFileSync)(pidPath, `${pid}\n`, 'utf8');
|
|
28249
|
+
}
|
|
28250
|
+
|
|
28251
|
+
function removePidFile(pidPath) {
|
|
28252
|
+
(0,external_node_fs_namespaceObject.rmSync)(pidPath, { force: true });
|
|
28253
|
+
}
|
|
28254
|
+
|
|
28255
|
+
function remosidian_isProcessAlive(pid) {
|
|
28256
|
+
try {
|
|
28257
|
+
process.kill(pid, 0);
|
|
28258
|
+
return true;
|
|
28259
|
+
} catch {
|
|
28260
|
+
return false;
|
|
28261
|
+
}
|
|
28262
|
+
}
|
|
28263
|
+
|
|
28264
|
+
function currentEntrypointPath() {
|
|
28265
|
+
const entryPath = (0,external_node_url_namespaceObject.fileURLToPath)(import.meta.url);
|
|
28266
|
+
try {
|
|
28267
|
+
return (0,external_node_fs_namespaceObject.realpathSync)(entryPath);
|
|
28268
|
+
} catch {
|
|
28269
|
+
return entryPath;
|
|
28270
|
+
}
|
|
28271
|
+
}
|
|
28272
|
+
|
|
28273
|
+
function installRuntime(paths) {
|
|
28274
|
+
const runtime = createRuntimePaths(paths);
|
|
28275
|
+
(0,external_node_fs_namespaceObject.mkdirSync)((0,external_node_path_namespaceObject.dirname)(runtime.runtimeEntryPath), { recursive: true });
|
|
28276
|
+
(0,external_node_fs_namespaceObject.copyFileSync)(currentEntrypointPath(), runtime.runtimeEntryPath);
|
|
28277
|
+
(0,external_node_fs_namespaceObject.chmodSync)(runtime.runtimeEntryPath, 0o755);
|
|
28278
|
+
return runtime;
|
|
28279
|
+
}
|
|
28280
|
+
|
|
28281
|
+
function resolveRequestedPort(flags, paths) {
|
|
28282
|
+
return Number(flags.port) || (loadConfigOrNull(paths)?.server?.port ?? 41234);
|
|
28283
|
+
}
|
|
28284
|
+
|
|
28214
28285
|
function readCsvList(value) {
|
|
28215
28286
|
if (typeof value !== 'string') return [];
|
|
28216
28287
|
return value
|
|
@@ -28341,7 +28412,7 @@ async function resolveRelayForStart(flags, paths, port) {
|
|
|
28341
28412
|
|
|
28342
28413
|
function renderQrTerminal(payload) {
|
|
28343
28414
|
return new Promise((resolveTerm, rejectTerm) => {
|
|
28344
|
-
lib.toString(payload, { type: 'terminal', small: true }, (err, str) => {
|
|
28415
|
+
lib.toString(payload, { type: 'terminal', small: true, errorCorrectionLevel: 'M' }, (err, str) => {
|
|
28345
28416
|
if (err) {
|
|
28346
28417
|
rejectTerm(err);
|
|
28347
28418
|
return;
|
|
@@ -28353,7 +28424,7 @@ function renderQrTerminal(payload) {
|
|
|
28353
28424
|
|
|
28354
28425
|
async function writeQrPng(payload, filePath) {
|
|
28355
28426
|
(0,external_node_fs_namespaceObject.mkdirSync)((0,external_node_path_namespaceObject.dirname)(filePath), { recursive: true });
|
|
28356
|
-
await lib.toFile(filePath, payload, { type: 'png', margin: 1,
|
|
28427
|
+
await lib.toFile(filePath, payload, { type: 'png', errorCorrectionLevel: 'M', margin: 1, scale: 8 });
|
|
28357
28428
|
}
|
|
28358
28429
|
|
|
28359
28430
|
function printHumanHealth(health) {
|
|
@@ -28415,7 +28486,214 @@ function buildPairUri(payload) {
|
|
|
28415
28486
|
return `remosidian://pair?v=1&data=${encoded}`;
|
|
28416
28487
|
}
|
|
28417
28488
|
|
|
28418
|
-
|
|
28489
|
+
function normalizePairingConnections(payload) {
|
|
28490
|
+
const explicitConnections = Array.isArray(payload.connections)
|
|
28491
|
+
? payload.connections
|
|
28492
|
+
.filter(
|
|
28493
|
+
(target) =>
|
|
28494
|
+
target &&
|
|
28495
|
+
typeof target.host === 'string' &&
|
|
28496
|
+
Number.isFinite(target.port) &&
|
|
28497
|
+
typeof target.source === 'string' &&
|
|
28498
|
+
typeof target.stability === 'string',
|
|
28499
|
+
)
|
|
28500
|
+
.map((target) => ({
|
|
28501
|
+
kind: target.kind === 'relay' ? 'relay' : 'direct',
|
|
28502
|
+
host: target.host.trim(),
|
|
28503
|
+
port: Math.floor(Number(target.port)),
|
|
28504
|
+
...(target.secure === true ? { secure: true } : {}),
|
|
28505
|
+
source: target.source,
|
|
28506
|
+
stability: target.stability,
|
|
28507
|
+
}))
|
|
28508
|
+
.filter((target) => target.host && target.port > 0)
|
|
28509
|
+
: [];
|
|
28510
|
+
if (explicitConnections.length > 0) {
|
|
28511
|
+
return explicitConnections;
|
|
28512
|
+
}
|
|
28513
|
+
const fallbackHosts = Array.isArray(payload.fallbackHosts)
|
|
28514
|
+
? payload.fallbackHosts.filter((host) => typeof host === 'string' && host.trim()).map((host) => host.trim())
|
|
28515
|
+
: [];
|
|
28516
|
+
const port = Number.isFinite(payload.port) && payload.port > 0 ? Math.floor(payload.port) : 41234;
|
|
28517
|
+
return [
|
|
28518
|
+
{
|
|
28519
|
+
kind: 'direct',
|
|
28520
|
+
host: payload.canonicalHost,
|
|
28521
|
+
port,
|
|
28522
|
+
source: 'configured_host',
|
|
28523
|
+
stability: 'stable',
|
|
28524
|
+
},
|
|
28525
|
+
...fallbackHosts.map((host) => ({
|
|
28526
|
+
kind: 'direct',
|
|
28527
|
+
host,
|
|
28528
|
+
port,
|
|
28529
|
+
source: 'fallback',
|
|
28530
|
+
stability: 'stable',
|
|
28531
|
+
})),
|
|
28532
|
+
];
|
|
28533
|
+
}
|
|
28534
|
+
|
|
28535
|
+
function createCompactPairingPayload(payload) {
|
|
28536
|
+
const compact = {
|
|
28537
|
+
t: 'rp',
|
|
28538
|
+
d: payload.daemonId,
|
|
28539
|
+
n: payload.displayName,
|
|
28540
|
+
h: payload.canonicalHost,
|
|
28541
|
+
p: payload.port,
|
|
28542
|
+
c: payload.pairNonce,
|
|
28543
|
+
e: payload.expiresAt,
|
|
28544
|
+
};
|
|
28545
|
+
if (Array.isArray(payload.fallbackHosts) && payload.fallbackHosts.length > 0) {
|
|
28546
|
+
compact.f = payload.fallbackHosts;
|
|
28547
|
+
}
|
|
28548
|
+
const connections = normalizePairingConnections(payload);
|
|
28549
|
+
if (connections.length > 0) {
|
|
28550
|
+
compact.o = connections.map((target) => [
|
|
28551
|
+
target.kind,
|
|
28552
|
+
target.host,
|
|
28553
|
+
target.port,
|
|
28554
|
+
target.source,
|
|
28555
|
+
target.stability,
|
|
28556
|
+
target.secure === true,
|
|
28557
|
+
]);
|
|
28558
|
+
}
|
|
28559
|
+
if (payload.runtime) {
|
|
28560
|
+
compact.r = payload.runtime;
|
|
28561
|
+
}
|
|
28562
|
+
if (Array.isArray(payload.vaults) && payload.vaults.length > 0) {
|
|
28563
|
+
compact.v = payload.vaults;
|
|
28564
|
+
}
|
|
28565
|
+
return compact;
|
|
28566
|
+
}
|
|
28567
|
+
|
|
28568
|
+
function buildPairCode(payload) {
|
|
28569
|
+
return JSON.stringify(createCompactPairingPayload(payload));
|
|
28570
|
+
}
|
|
28571
|
+
|
|
28572
|
+
function buildPairDeepLink(pairingCode) {
|
|
28573
|
+
return `remosidian://pair?data=${encodeURIComponent(pairingCode)}`;
|
|
28574
|
+
}
|
|
28575
|
+
|
|
28576
|
+
function formatConnectionSummary(target) {
|
|
28577
|
+
const scheme = target.secure === true || target.port === 443 ? 'https' : 'http';
|
|
28578
|
+
return `${scheme}://${target.host}:${target.port} (${target.source}, ${target.stability})`;
|
|
28579
|
+
}
|
|
28580
|
+
|
|
28581
|
+
async function printPairingQr(pairingPayload, paths) {
|
|
28582
|
+
const runtime = createRuntimePaths(paths);
|
|
28583
|
+
const pairingCode = buildPairCode(pairingPayload);
|
|
28584
|
+
const deepLink = buildPairDeepLink(pairingCode);
|
|
28585
|
+
const qr = await renderQrTerminal(pairingCode);
|
|
28586
|
+
(0,external_node_fs_namespaceObject.writeFileSync)(runtime.pairingCodePath, `${pairingCode}\n`, 'utf8');
|
|
28587
|
+
await writeQrPng(pairingCode, runtime.pairingQrPath).catch(() => undefined);
|
|
28588
|
+
process.stdout.write(`\nScan this QR code with the Remosidian app:\n\n${qr}\n`);
|
|
28589
|
+
process.stdout.write(`If the terminal QR is hard to scan, open this PNG instead:\n${runtime.pairingQrPath}\n`);
|
|
28590
|
+
process.stdout.write(`If this device cannot scan, paste this pairing code in Remosidian:\n${pairingCode}\n`);
|
|
28591
|
+
process.stdout.write(`Pairing code saved to:\n${runtime.pairingCodePath}\n`);
|
|
28592
|
+
process.stdout.write(`Or open this deep link on a device with Remosidian installed:\n${deepLink}\n`);
|
|
28593
|
+
}
|
|
28594
|
+
|
|
28595
|
+
async function printPairingSummary(port, paths, health = null, flags = {}) {
|
|
28596
|
+
const healthPayload = health ?? (await waitForHealth(port));
|
|
28597
|
+
if (flags.json) {
|
|
28598
|
+
process.stdout.write(`${JSON.stringify({ ok: true, ...healthPayload })}\n`);
|
|
28599
|
+
return;
|
|
28600
|
+
}
|
|
28601
|
+
process.stdout.write(`Remosidian daemon is ready.\n\n`);
|
|
28602
|
+
process.stdout.write(`${printHumanHealth(healthPayload)}\n`);
|
|
28603
|
+
if (flags['no-qr']) {
|
|
28604
|
+
return;
|
|
28605
|
+
}
|
|
28606
|
+
const pairingPayload = await postJson(port, '/pair/open');
|
|
28607
|
+
const connections = normalizePairingConnections(pairingPayload);
|
|
28608
|
+
if (connections.length > 0) {
|
|
28609
|
+
process.stdout.write('\nPairing paths:\n');
|
|
28610
|
+
for (const target of connections) {
|
|
28611
|
+
process.stdout.write(` - ${formatConnectionSummary(target)}\n`);
|
|
28612
|
+
}
|
|
28613
|
+
}
|
|
28614
|
+
await printPairingQr(pairingPayload, paths);
|
|
28615
|
+
}
|
|
28616
|
+
|
|
28617
|
+
async function probeHealth(port, timeoutMs = 0) {
|
|
28618
|
+
const deadline = Date.now() + timeoutMs;
|
|
28619
|
+
do {
|
|
28620
|
+
try {
|
|
28621
|
+
const resp = await fetch(`http://127.0.0.1:${port}/health`, { signal: AbortSignal.timeout(2000) });
|
|
28622
|
+
if (resp.ok) {
|
|
28623
|
+
return await resp.json();
|
|
28624
|
+
}
|
|
28625
|
+
} catch {
|
|
28626
|
+
// Retry below until timeout.
|
|
28627
|
+
}
|
|
28628
|
+
if (timeoutMs <= 0) break;
|
|
28629
|
+
await new Promise((resolveProbe) => setTimeout(resolveProbe, 250));
|
|
28630
|
+
} while (Date.now() < deadline);
|
|
28631
|
+
return null;
|
|
28632
|
+
}
|
|
28633
|
+
|
|
28634
|
+
async function waitForHealth(port, timeoutMs = 30_000) {
|
|
28635
|
+
const health = await probeHealth(port, timeoutMs);
|
|
28636
|
+
if (health) {
|
|
28637
|
+
return health;
|
|
28638
|
+
}
|
|
28639
|
+
throw new Error(`Timed out waiting for Remosidian daemon on 127.0.0.1:${port}`);
|
|
28640
|
+
}
|
|
28641
|
+
|
|
28642
|
+
async function postJson(port, pathname, body = undefined) {
|
|
28643
|
+
const response = await fetch(`http://127.0.0.1:${port}${pathname}`, {
|
|
28644
|
+
method: 'POST',
|
|
28645
|
+
headers: body ? { 'content-type': 'application/json' } : undefined,
|
|
28646
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
28647
|
+
});
|
|
28648
|
+
const payload = await response.json().catch(() => ({}));
|
|
28649
|
+
if (!response.ok) {
|
|
28650
|
+
throw new Error(`${pathname} failed: ${response.status} ${JSON.stringify(payload)}`);
|
|
28651
|
+
}
|
|
28652
|
+
return payload;
|
|
28653
|
+
}
|
|
28654
|
+
|
|
28655
|
+
function buildServeArgs(flags) {
|
|
28656
|
+
const args = ['serve'];
|
|
28657
|
+
for (const vault of flags.__vaults ?? []) {
|
|
28658
|
+
args.push('--vault', vault);
|
|
28659
|
+
}
|
|
28660
|
+
const skipFlags = new Set(['__vaults', 'foreground', 'json']);
|
|
28661
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
28662
|
+
if (skipFlags.has(key)) continue;
|
|
28663
|
+
if (key === 'no-qr') continue;
|
|
28664
|
+
if (value === true) {
|
|
28665
|
+
args.push(`--${key}`);
|
|
28666
|
+
} else if (typeof value === 'string') {
|
|
28667
|
+
args.push(`--${key}`, value);
|
|
28668
|
+
}
|
|
28669
|
+
}
|
|
28670
|
+
args.push('--no-qr');
|
|
28671
|
+
return args;
|
|
28672
|
+
}
|
|
28673
|
+
|
|
28674
|
+
function startDetachedDaemon(paths, flags) {
|
|
28675
|
+
const runtime = installRuntime(paths);
|
|
28676
|
+
(0,external_node_fs_namespaceObject.mkdirSync)(runtime.logDir, { recursive: true });
|
|
28677
|
+
const stdoutFd = (0,external_node_fs_namespaceObject.openSync)(runtime.stdoutLogPath, 'a');
|
|
28678
|
+
const stderrFd = (0,external_node_fs_namespaceObject.openSync)(runtime.stderrLogPath, 'a');
|
|
28679
|
+
try {
|
|
28680
|
+
const child = (0,external_node_child_process_namespaceObject.spawn)(process.execPath, [runtime.runtimeEntryPath, ...buildServeArgs(flags)], {
|
|
28681
|
+
detached: true,
|
|
28682
|
+
stdio: ['ignore', stdoutFd, stderrFd],
|
|
28683
|
+
cwd: process.cwd(),
|
|
28684
|
+
env: { ...process.env },
|
|
28685
|
+
windowsHide: true,
|
|
28686
|
+
});
|
|
28687
|
+
child.unref();
|
|
28688
|
+
writePidFile(runtime.pidPath, child.pid);
|
|
28689
|
+
return child.pid;
|
|
28690
|
+
} finally {
|
|
28691
|
+
(0,external_node_fs_namespaceObject.closeSync)(stdoutFd);
|
|
28692
|
+
(0,external_node_fs_namespaceObject.closeSync)(stderrFd);
|
|
28693
|
+
}
|
|
28694
|
+
}
|
|
28695
|
+
|
|
28696
|
+
async function cmdServe(flags, paths) {
|
|
28419
28697
|
const config = loadConfigOrNull(paths);
|
|
28420
28698
|
const inlineVaults = flags.__vaults.map((spec) => expandVaultSpec(spec)).filter((vault) => Boolean(vault));
|
|
28421
28699
|
let finalConfig;
|
|
@@ -28497,16 +28775,7 @@ async function cmdStart(flags, paths) {
|
|
|
28497
28775
|
const openResp = await fetch(`http://127.0.0.1:${server.port}/pair/open`, { method: 'POST' });
|
|
28498
28776
|
if (openResp.ok) {
|
|
28499
28777
|
const payload = await openResp.json();
|
|
28500
|
-
|
|
28501
|
-
const qr = await renderQrTerminal(uri);
|
|
28502
|
-
process.stdout.write('\nScan to pair (one-time, expires in 5 min):\n');
|
|
28503
|
-
process.stdout.write(`${qr}\n`);
|
|
28504
|
-
process.stdout.write(`${uri}\n\n`);
|
|
28505
|
-
const qrPath = (0,external_node_path_namespaceObject.join)(paths.dataDir, 'pairing-qr.png');
|
|
28506
|
-
await writeQrPng(uri, qrPath).catch(() => {
|
|
28507
|
-
// PNG export is best-effort.
|
|
28508
|
-
});
|
|
28509
|
-
process.stdout.write(`Saved QR image: ${qrPath}\n`);
|
|
28778
|
+
await printPairingQr(payload, paths);
|
|
28510
28779
|
}
|
|
28511
28780
|
} catch (error) {
|
|
28512
28781
|
process.stderr.write(`[${PROG}] pair payload not available: ${error?.message ?? error}\n`);
|
|
@@ -28529,31 +28798,60 @@ async function cmdStart(flags, paths) {
|
|
|
28529
28798
|
process.on('SIGHUP', () => void shutdown('SIGHUP'));
|
|
28530
28799
|
}
|
|
28531
28800
|
|
|
28532
|
-
async function
|
|
28533
|
-
|
|
28534
|
-
|
|
28535
|
-
|
|
28536
|
-
|
|
28537
|
-
|
|
28801
|
+
async function cmdStart(flags, paths) {
|
|
28802
|
+
if (flags.foreground) {
|
|
28803
|
+
await cmdServe(flags, paths);
|
|
28804
|
+
return;
|
|
28805
|
+
}
|
|
28806
|
+
const port = resolveRequestedPort(flags, paths);
|
|
28807
|
+
const existing = await probeHealth(port, 1_000);
|
|
28808
|
+
if (existing) {
|
|
28809
|
+
if (!flags.json) {
|
|
28810
|
+
process.stdout.write('Remosidian daemon is already running. Reusing it.\n\n');
|
|
28811
|
+
}
|
|
28812
|
+
await printPairingSummary(port, paths, existing, flags);
|
|
28813
|
+
return;
|
|
28814
|
+
}
|
|
28815
|
+
|
|
28816
|
+
const runtime = createRuntimePaths(paths);
|
|
28817
|
+
const stalePid = readPidFile(runtime.pidPath);
|
|
28818
|
+
if (stalePid && !remosidian_isProcessAlive(stalePid)) {
|
|
28819
|
+
removePidFile(runtime.pidPath);
|
|
28820
|
+
}
|
|
28821
|
+
|
|
28822
|
+
const pid = startDetachedDaemon(paths, flags);
|
|
28823
|
+
const health = await waitForHealth(port);
|
|
28824
|
+
if (!flags.json) {
|
|
28825
|
+
process.stdout.write(`Started Remosidian daemon in the background (pid ${pid}).\n`);
|
|
28826
|
+
process.stdout.write(`Logs: ${runtime.stdoutLogPath} / ${runtime.stderrLogPath}\n\n`);
|
|
28538
28827
|
}
|
|
28539
|
-
|
|
28540
|
-
|
|
28828
|
+
await printPairingSummary(port, paths, health, flags);
|
|
28829
|
+
}
|
|
28830
|
+
|
|
28831
|
+
async function cmdPair(flags, paths) {
|
|
28832
|
+
const port = resolveRequestedPort(flags, paths);
|
|
28833
|
+
const payload = await postJson(port, '/pair/open');
|
|
28834
|
+
const pairingCode = buildPairCode(payload);
|
|
28835
|
+
const deepLink = buildPairDeepLink(pairingCode);
|
|
28541
28836
|
if (flags.json) {
|
|
28542
|
-
process.stdout.write(`${JSON.stringify({ ok: true, payload,
|
|
28837
|
+
process.stdout.write(`${JSON.stringify({ ok: true, payload, pairingCode, deepLink })}\n`);
|
|
28543
28838
|
return;
|
|
28544
28839
|
}
|
|
28545
|
-
const qr = await renderQrTerminal(
|
|
28840
|
+
const qr = await renderQrTerminal(pairingCode);
|
|
28546
28841
|
process.stdout.write(`${qr}\n`);
|
|
28547
|
-
process.stdout.write(`${
|
|
28842
|
+
process.stdout.write(`${pairingCode}\n`);
|
|
28843
|
+
process.stdout.write(`${deepLink}\n`);
|
|
28548
28844
|
process.stdout.write(`Daemon ${payload.daemonId} (${payload.displayName})\n`);
|
|
28549
28845
|
process.stdout.write(`Expires ${payload.expiresAt}\n`);
|
|
28550
|
-
const
|
|
28551
|
-
|
|
28552
|
-
|
|
28846
|
+
const runtime = createRuntimePaths(paths);
|
|
28847
|
+
(0,external_node_fs_namespaceObject.writeFileSync)(runtime.pairingCodePath, `${pairingCode}\n`, 'utf8');
|
|
28848
|
+
await writeQrPng(pairingCode, runtime.pairingQrPath).catch(() => undefined);
|
|
28849
|
+
process.stdout.write(`Saved QR ${runtime.pairingQrPath}\n`);
|
|
28850
|
+
process.stdout.write(`Saved code ${runtime.pairingCodePath}\n`);
|
|
28553
28851
|
}
|
|
28554
28852
|
|
|
28555
28853
|
async function cmdStatus(flags, paths) {
|
|
28556
|
-
const port =
|
|
28854
|
+
const port = resolveRequestedPort(flags, paths);
|
|
28557
28855
|
try {
|
|
28558
28856
|
const resp = await fetch(`http://127.0.0.1:${port}/health`);
|
|
28559
28857
|
if (!resp.ok) {
|
|
@@ -28572,13 +28870,49 @@ async function cmdStatus(flags, paths) {
|
|
|
28572
28870
|
}
|
|
28573
28871
|
}
|
|
28574
28872
|
|
|
28575
|
-
async function
|
|
28576
|
-
const
|
|
28577
|
-
|
|
28578
|
-
|
|
28579
|
-
|
|
28873
|
+
async function waitForDaemonExit(port, timeoutMs = 5_000) {
|
|
28874
|
+
const deadline = Date.now() + timeoutMs;
|
|
28875
|
+
while (Date.now() < deadline) {
|
|
28876
|
+
const health = await probeHealth(port, 0);
|
|
28877
|
+
if (!health) {
|
|
28878
|
+
return true;
|
|
28879
|
+
}
|
|
28880
|
+
await new Promise((resolveWait) => setTimeout(resolveWait, 200));
|
|
28881
|
+
}
|
|
28882
|
+
return false;
|
|
28883
|
+
}
|
|
28884
|
+
|
|
28885
|
+
async function cmdStop(flags, paths) {
|
|
28886
|
+
const port = resolveRequestedPort(flags, paths);
|
|
28887
|
+
const runtime = createRuntimePaths(paths);
|
|
28888
|
+
const pid = readPidFile(runtime.pidPath);
|
|
28889
|
+
if (pid && remosidian_isProcessAlive(pid)) {
|
|
28890
|
+
try {
|
|
28891
|
+
process.kill(pid, 'SIGTERM');
|
|
28892
|
+
} catch {
|
|
28893
|
+
// Process may have exited between the liveness check and kill.
|
|
28894
|
+
}
|
|
28895
|
+
await waitForDaemonExit(port);
|
|
28896
|
+
removePidFile(runtime.pidPath);
|
|
28897
|
+
stopTunnel({ tunnelStatePath: (0,external_node_path_namespaceObject.join)(paths.dataDir, 'tunnel.json') });
|
|
28898
|
+
process.stdout.write('Remosidian daemon stopped.\n');
|
|
28899
|
+
return;
|
|
28900
|
+
}
|
|
28901
|
+
removePidFile(runtime.pidPath);
|
|
28902
|
+
const health = await probeHealth(port, 500);
|
|
28903
|
+
if (health) {
|
|
28904
|
+
process.stderr.write(
|
|
28905
|
+
`[${PROG}] daemon is responding on 127.0.0.1:${port}, but no background PID file exists. Stop the foreground terminal process that started it.\n`,
|
|
28906
|
+
);
|
|
28580
28907
|
process.exit(1);
|
|
28581
28908
|
}
|
|
28909
|
+
stopTunnel({ tunnelStatePath: (0,external_node_path_namespaceObject.join)(paths.dataDir, 'tunnel.json') });
|
|
28910
|
+
process.stdout.write('Remosidian daemon is not running.\n');
|
|
28911
|
+
}
|
|
28912
|
+
|
|
28913
|
+
async function cmdResetPairings(flags, paths) {
|
|
28914
|
+
const port = resolveRequestedPort(flags, paths);
|
|
28915
|
+
await postJson(port, '/pair/reset');
|
|
28582
28916
|
process.stdout.write('All pairings revoked.\n');
|
|
28583
28917
|
}
|
|
28584
28918
|
|
|
@@ -28652,12 +28986,18 @@ async function main() {
|
|
|
28652
28986
|
case 'start':
|
|
28653
28987
|
await cmdStart(parsed.flags, paths);
|
|
28654
28988
|
return;
|
|
28989
|
+
case 'serve':
|
|
28990
|
+
await cmdServe(parsed.flags, paths);
|
|
28991
|
+
return;
|
|
28655
28992
|
case 'pair':
|
|
28656
28993
|
await cmdPair(parsed.flags, paths);
|
|
28657
28994
|
return;
|
|
28658
28995
|
case 'status':
|
|
28659
28996
|
await cmdStatus(parsed.flags, paths);
|
|
28660
28997
|
return;
|
|
28998
|
+
case 'stop':
|
|
28999
|
+
await cmdStop(parsed.flags, paths);
|
|
29000
|
+
return;
|
|
28661
29001
|
case 'reset-pairings':
|
|
28662
29002
|
await cmdResetPairings(parsed.flags, paths);
|
|
28663
29003
|
return;
|
|
@@ -28681,10 +29021,14 @@ if (entryHref && moduleHref === entryHref) {
|
|
|
28681
29021
|
|
|
28682
29022
|
|
|
28683
29023
|
|
|
29024
|
+
var __webpack_exports__buildPairCode = __webpack_exports__.gu;
|
|
29025
|
+
var __webpack_exports__buildPairDeepLink = __webpack_exports__.ti;
|
|
28684
29026
|
var __webpack_exports__buildPairUri = __webpack_exports__.lz;
|
|
29027
|
+
var __webpack_exports__buildServeArgs = __webpack_exports__.jO;
|
|
29028
|
+
var __webpack_exports__createCompactPairingPayload = __webpack_exports__.YP;
|
|
28685
29029
|
var __webpack_exports__expandVaultSpec = __webpack_exports__.wX;
|
|
28686
29030
|
var __webpack_exports__main = __webpack_exports__.iW;
|
|
28687
29031
|
var __webpack_exports__parseArgs = __webpack_exports__.Zy;
|
|
28688
29032
|
var __webpack_exports__resolveEntrypointHref = __webpack_exports__.Mf;
|
|
28689
29033
|
var __webpack_exports__resolveInvocation = __webpack_exports__.t0;
|
|
28690
|
-
export { __webpack_exports__buildPairUri as buildPairUri, __webpack_exports__expandVaultSpec as expandVaultSpec, __webpack_exports__main as main, __webpack_exports__parseArgs as parseArgs, __webpack_exports__resolveEntrypointHref as resolveEntrypointHref, __webpack_exports__resolveInvocation as resolveInvocation };
|
|
29034
|
+
export { __webpack_exports__buildPairCode as buildPairCode, __webpack_exports__buildPairDeepLink as buildPairDeepLink, __webpack_exports__buildPairUri as buildPairUri, __webpack_exports__buildServeArgs as buildServeArgs, __webpack_exports__createCompactPairingPayload as createCompactPairingPayload, __webpack_exports__expandVaultSpec as expandVaultSpec, __webpack_exports__main as main, __webpack_exports__parseArgs as parseArgs, __webpack_exports__resolveEntrypointHref as resolveEntrypointHref, __webpack_exports__resolveInvocation as resolveInvocation };
|