@remnic/cli 9.65.5 → 9.65.7
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/index.js +380 -333
- package/package.json +31 -31
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ async function persistEnrichmentCandidate(storage, entityName, candidate) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
import
|
|
21
|
+
import fs21 from "fs";
|
|
22
22
|
import os3 from "os";
|
|
23
23
|
import path18 from "path";
|
|
24
24
|
import { createHash as createHash4 } from "crypto";
|
|
@@ -27,11 +27,11 @@ import * as childProcess2 from "child_process";
|
|
|
27
27
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
28
28
|
import { gzipSync } from "zlib";
|
|
29
29
|
import {
|
|
30
|
-
parseConfig as
|
|
30
|
+
parseConfig as parseConfig12,
|
|
31
31
|
isOpenaiApiKeyDisabled,
|
|
32
32
|
resolveEnvVars,
|
|
33
|
-
resolveRemnicConfigRecord as
|
|
34
|
-
Orchestrator as
|
|
33
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord11,
|
|
34
|
+
Orchestrator as Orchestrator7,
|
|
35
35
|
EngramAccessService as EngramAccessService2,
|
|
36
36
|
initLogger as initLogger5,
|
|
37
37
|
onboard,
|
|
@@ -137,7 +137,6 @@ import {
|
|
|
137
137
|
expandTildePath,
|
|
138
138
|
forkCapsule,
|
|
139
139
|
readForkLineage,
|
|
140
|
-
runWearablesCliCommand,
|
|
141
140
|
OPERATION_NAMES,
|
|
142
141
|
validateCapabilitiesForMint
|
|
143
142
|
} from "@remnic/core";
|
|
@@ -193,18 +192,101 @@ async function runMeetingsBinaryCommand(rest) {
|
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
|
|
196
|
-
// src/commands/
|
|
195
|
+
// src/commands/wearables.ts
|
|
197
196
|
import fs2 from "fs";
|
|
198
|
-
import {
|
|
197
|
+
import {
|
|
198
|
+
Orchestrator as Orchestrator2,
|
|
199
|
+
parseConfig as parseConfig2,
|
|
200
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord2,
|
|
201
|
+
runWearablesCliCommand
|
|
202
|
+
} from "@remnic/core";
|
|
203
|
+
async function runWearablesBinaryCommand(rest) {
|
|
204
|
+
const wearablesArgs = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
205
|
+
let wearablesOrchestrator;
|
|
206
|
+
try {
|
|
207
|
+
let wearablesService;
|
|
208
|
+
try {
|
|
209
|
+
const configPath = resolveConfigPath();
|
|
210
|
+
const raw = fs2.existsSync(configPath) ? JSON.parse(fs2.readFileSync(configPath, "utf8")) : {};
|
|
211
|
+
const config = parseConfig2(resolveRemnicConfigRecord2(raw));
|
|
212
|
+
wearablesOrchestrator = new Orchestrator2(config);
|
|
213
|
+
await wearablesOrchestrator.initialize();
|
|
214
|
+
await wearablesOrchestrator.deferredReady;
|
|
215
|
+
wearablesService = wearablesOrchestrator.getWearablesService();
|
|
216
|
+
} catch {
|
|
217
|
+
console.error(
|
|
218
|
+
"wearables: failed to load the Remnic config or start the memory engine \u2014 run `remnic doctor` and check the config file for errors"
|
|
219
|
+
);
|
|
220
|
+
process.exitCode = 1;
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const code = await runWearablesCliCommand(wearablesService, wearablesArgs, {
|
|
224
|
+
stdout: process.stdout,
|
|
225
|
+
stderr: process.stderr
|
|
226
|
+
});
|
|
227
|
+
if (wearablesArgs[0] === "sync" && code === 0 && wearablesOrchestrator.config.meetings.enabled) {
|
|
228
|
+
await (await wearablesOrchestrator.getMeetingsService()).flushBuilds();
|
|
229
|
+
}
|
|
230
|
+
if (code !== 0) process.exitCode = code;
|
|
231
|
+
} catch (err) {
|
|
232
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
233
|
+
process.exitCode = 1;
|
|
234
|
+
} finally {
|
|
235
|
+
if (wearablesOrchestrator) {
|
|
236
|
+
const maybeShutdown = wearablesOrchestrator.shutdown;
|
|
237
|
+
if (typeof maybeShutdown === "function") {
|
|
238
|
+
try {
|
|
239
|
+
await maybeShutdown.call(wearablesOrchestrator);
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// src/commands/location.ts
|
|
248
|
+
import fs3 from "fs";
|
|
249
|
+
import { parseConfig as parseConfig3, resolveRemnicConfigRecord as resolveRemnicConfigRecord3 } from "@remnic/core";
|
|
250
|
+
import { runLocationCliCommand } from "@remnic/core/location";
|
|
251
|
+
async function runLocationBinaryCommand(rest) {
|
|
252
|
+
const locationArgs = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
253
|
+
try {
|
|
254
|
+
let config;
|
|
255
|
+
try {
|
|
256
|
+
const configPath = resolveConfigPath();
|
|
257
|
+
const raw = fs3.existsSync(configPath) ? JSON.parse(fs3.readFileSync(configPath, "utf8")) : {};
|
|
258
|
+
config = parseConfig3(resolveRemnicConfigRecord3(raw));
|
|
259
|
+
} catch {
|
|
260
|
+
console.error(
|
|
261
|
+
"location: failed to load the Remnic config \u2014 run `remnic doctor` and check the config file for errors"
|
|
262
|
+
);
|
|
263
|
+
process.exitCode = 1;
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const code = await runLocationCliCommand(
|
|
267
|
+
{ config: config.location, memoryDir: config.memoryDir },
|
|
268
|
+
locationArgs,
|
|
269
|
+
{ stdout: process.stdout, stderr: process.stderr }
|
|
270
|
+
);
|
|
271
|
+
if (code !== 0) process.exitCode = code;
|
|
272
|
+
} catch (err) {
|
|
273
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
274
|
+
process.exitCode = 1;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// src/commands/okf.ts
|
|
279
|
+
import fs4 from "fs";
|
|
280
|
+
import { Orchestrator as Orchestrator3, parseConfig as parseConfig4, resolveRemnicConfigRecord as resolveRemnicConfigRecord4, runOkfCliCommand } from "@remnic/core";
|
|
199
281
|
async function runOkfBinaryCommand(rest) {
|
|
200
282
|
const argv = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
201
283
|
let orchestrator;
|
|
202
284
|
try {
|
|
203
285
|
try {
|
|
204
286
|
const configPath = resolveConfigPath();
|
|
205
|
-
const raw =
|
|
206
|
-
const config2 =
|
|
207
|
-
orchestrator = new
|
|
287
|
+
const raw = fs4.existsSync(configPath) ? JSON.parse(fs4.readFileSync(configPath, "utf8")) : {};
|
|
288
|
+
const config2 = parseConfig4(resolveRemnicConfigRecord4(raw));
|
|
289
|
+
orchestrator = new Orchestrator3(config2);
|
|
208
290
|
await orchestrator.initialize();
|
|
209
291
|
await orchestrator.deferredReady;
|
|
210
292
|
} catch {
|
|
@@ -231,14 +313,14 @@ async function runOkfBinaryCommand(rest) {
|
|
|
231
313
|
}
|
|
232
314
|
|
|
233
315
|
// src/commands/external-wiki.ts
|
|
234
|
-
import
|
|
235
|
-
import { parseConfig as
|
|
316
|
+
import fs5 from "fs";
|
|
317
|
+
import { parseConfig as parseConfig5, resolveRemnicConfigRecord as resolveRemnicConfigRecord5, runExternalWikiCliCommand } from "@remnic/core";
|
|
236
318
|
async function runExternalWikiBinaryCommand(rest) {
|
|
237
319
|
let roots;
|
|
238
320
|
try {
|
|
239
321
|
const configPath = resolveConfigPath();
|
|
240
|
-
const raw =
|
|
241
|
-
roots =
|
|
322
|
+
const raw = fs5.existsSync(configPath) ? JSON.parse(fs5.readFileSync(configPath, "utf8")) : {};
|
|
323
|
+
roots = parseConfig5(resolveRemnicConfigRecord5(raw)).externalWikis;
|
|
242
324
|
} catch {
|
|
243
325
|
console.error(
|
|
244
326
|
"external-wiki: failed to load the Remnic config - run `remnic doctor` and check the config file for errors"
|
|
@@ -259,14 +341,14 @@ async function runExternalWikiBinaryCommand(rest) {
|
|
|
259
341
|
}
|
|
260
342
|
|
|
261
343
|
// src/commands/procedural.ts
|
|
262
|
-
import
|
|
344
|
+
import fs6 from "fs";
|
|
263
345
|
import {
|
|
264
346
|
StorageManager,
|
|
265
347
|
computeProcedureStats,
|
|
266
348
|
formatProcedureStatsText,
|
|
267
349
|
initLogger,
|
|
268
|
-
parseConfig as
|
|
269
|
-
resolveRemnicConfigRecord as
|
|
350
|
+
parseConfig as parseConfig6,
|
|
351
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord6,
|
|
270
352
|
runProcedureLibraryMaintenance
|
|
271
353
|
} from "@remnic/core";
|
|
272
354
|
|
|
@@ -397,8 +479,8 @@ Shared with:
|
|
|
397
479
|
process.exit(1);
|
|
398
480
|
}
|
|
399
481
|
const configPath = resolveConfigPath();
|
|
400
|
-
const raw =
|
|
401
|
-
const config =
|
|
482
|
+
const raw = fs6.existsSync(configPath) ? JSON.parse(fs6.readFileSync(configPath, "utf8")) : {};
|
|
483
|
+
const config = parseConfig6(resolveRemnicConfigRecord6(raw));
|
|
402
484
|
const memoryDir = expandTilde(
|
|
403
485
|
typeof memoryDirOverride === "string" && memoryDirOverride.length > 0 ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
|
|
404
486
|
);
|
|
@@ -453,12 +535,12 @@ function formatProcedureMaintenanceText(report) {
|
|
|
453
535
|
}
|
|
454
536
|
|
|
455
537
|
// src/commands/drift.ts
|
|
456
|
-
import
|
|
538
|
+
import fs7 from "fs";
|
|
457
539
|
import {
|
|
458
|
-
Orchestrator as
|
|
540
|
+
Orchestrator as Orchestrator4,
|
|
459
541
|
initLogger as initLogger2,
|
|
460
|
-
parseConfig as
|
|
461
|
-
resolveRemnicConfigRecord as
|
|
542
|
+
parseConfig as parseConfig7,
|
|
543
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord7,
|
|
462
544
|
runPreferenceDriftScan
|
|
463
545
|
} from "@remnic/core";
|
|
464
546
|
async function runDriftBinaryCommand(rest) {
|
|
@@ -518,13 +600,13 @@ Resolve a drifted item with the existing review surface:
|
|
|
518
600
|
process.exit(1);
|
|
519
601
|
}
|
|
520
602
|
const configPath = resolveConfigPath();
|
|
521
|
-
const raw =
|
|
522
|
-
const config =
|
|
603
|
+
const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
|
|
604
|
+
const config = parseConfig7(resolveRemnicConfigRecord7(raw));
|
|
523
605
|
const memoryDirOverridden = typeof memoryDirOverride === "string" && memoryDirOverride.length > 0;
|
|
524
606
|
const memoryDir = expandTilde(
|
|
525
607
|
memoryDirOverridden ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
|
|
526
608
|
);
|
|
527
|
-
const orchestrator = new
|
|
609
|
+
const orchestrator = new Orchestrator4(
|
|
528
610
|
memoryDirOverridden ? { ...config, memoryDir } : config
|
|
529
611
|
);
|
|
530
612
|
await orchestrator.initialize();
|
|
@@ -632,13 +714,13 @@ async function loadWecloneExportModule() {
|
|
|
632
714
|
}
|
|
633
715
|
|
|
634
716
|
// src/converge.ts
|
|
635
|
-
import * as
|
|
717
|
+
import * as fs9 from "fs";
|
|
636
718
|
import { createHash as createHash3 } from "crypto";
|
|
637
719
|
import * as path2 from "path";
|
|
638
720
|
import {
|
|
639
721
|
CONVERGE_CONFLICT_POLICIES,
|
|
640
722
|
DEFAULT_CONVERGE_CONFLICT_POLICY,
|
|
641
|
-
parseConfig as
|
|
723
|
+
parseConfig as parseConfig8,
|
|
642
724
|
buildOfflineSyncSnapshotFromBase,
|
|
643
725
|
applyOfflineSyncFileContentChunk,
|
|
644
726
|
isInternalRemnicStatePath as isInternalRemnicStatePath3,
|
|
@@ -664,7 +746,7 @@ import {
|
|
|
664
746
|
|
|
665
747
|
// src/offline-storage-io.ts
|
|
666
748
|
import { createDecipheriv, createHash } from "crypto";
|
|
667
|
-
import
|
|
749
|
+
import fs8 from "fs";
|
|
668
750
|
import { lstat, mkdtemp, readdir, rm } from "fs/promises";
|
|
669
751
|
import path from "path";
|
|
670
752
|
import {
|
|
@@ -826,7 +908,7 @@ async function* readOfflineSyncFileChunks(options) {
|
|
|
826
908
|
});
|
|
827
909
|
}
|
|
828
910
|
async function readFilePrefix(filePath, length) {
|
|
829
|
-
const handle = await
|
|
911
|
+
const handle = await fs8.promises.open(filePath, "r");
|
|
830
912
|
try {
|
|
831
913
|
const out = Buffer.alloc(length);
|
|
832
914
|
const { bytesRead } = await handle.read(out, 0, length, 0);
|
|
@@ -836,7 +918,7 @@ async function readFilePrefix(filePath, length) {
|
|
|
836
918
|
}
|
|
837
919
|
}
|
|
838
920
|
async function* readPlainOfflineFileChunks(filePath, chunkSize) {
|
|
839
|
-
const stream =
|
|
921
|
+
const stream = fs8.createReadStream(filePath, { highWaterMark: chunkSize });
|
|
840
922
|
for await (const chunk of stream) {
|
|
841
923
|
yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
842
924
|
}
|
|
@@ -873,9 +955,9 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
873
955
|
});
|
|
874
956
|
decipher.setAuthTag(authTag);
|
|
875
957
|
decipher.setAAD(Buffer.concat([secureStoreEnvelopeHeaderAad(salt), aad]));
|
|
876
|
-
const output =
|
|
958
|
+
const output = fs8.createWriteStream(tempPath, { mode: 384 });
|
|
877
959
|
try {
|
|
878
|
-
const stream =
|
|
960
|
+
const stream = fs8.createReadStream(options.filePath, {
|
|
879
961
|
start: MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE,
|
|
880
962
|
highWaterMark: options.chunkSize
|
|
881
963
|
});
|
|
@@ -1485,7 +1567,7 @@ async function readLocalTombstoneEvidence(rootDir) {
|
|
|
1485
1567
|
for (const relativePath of TOMBSTONE_PATHS) {
|
|
1486
1568
|
let content;
|
|
1487
1569
|
try {
|
|
1488
|
-
content = await
|
|
1570
|
+
content = await fs9.promises.readFile(path2.join(rootDir, relativePath), "utf-8");
|
|
1489
1571
|
} catch (error) {
|
|
1490
1572
|
if (error.code === "ENOENT") continue;
|
|
1491
1573
|
throw error;
|
|
@@ -1500,7 +1582,7 @@ async function discoverCursorNamespaces(memoryDir, peerUrl) {
|
|
|
1500
1582
|
const cursorDir = path2.join(path2.resolve(memoryDir), ".remnic", "state", "converge-cursors");
|
|
1501
1583
|
let entries;
|
|
1502
1584
|
try {
|
|
1503
|
-
entries = await
|
|
1585
|
+
entries = await fs9.promises.readdir(cursorDir, { withFileTypes: true });
|
|
1504
1586
|
} catch (error) {
|
|
1505
1587
|
if (error.code === "ENOENT") return [];
|
|
1506
1588
|
throw error;
|
|
@@ -1576,7 +1658,7 @@ async function computeConvergePlan(options = {}) {
|
|
|
1576
1658
|
let config = options.config;
|
|
1577
1659
|
if (!config) {
|
|
1578
1660
|
try {
|
|
1579
|
-
config =
|
|
1661
|
+
config = parseConfig8({});
|
|
1580
1662
|
} catch {
|
|
1581
1663
|
}
|
|
1582
1664
|
}
|
|
@@ -1827,7 +1909,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
1827
1909
|
let config = options.config;
|
|
1828
1910
|
if (!config) {
|
|
1829
1911
|
try {
|
|
1830
|
-
config =
|
|
1912
|
+
config = parseConfig8({});
|
|
1831
1913
|
} catch {
|
|
1832
1914
|
}
|
|
1833
1915
|
}
|
|
@@ -1990,7 +2072,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
1990
2072
|
if (current.sha256 !== entry.localSha256) {
|
|
1991
2073
|
throw new Error(`local file changed during push: ${localPath}`);
|
|
1992
2074
|
}
|
|
1993
|
-
const stat2 = await
|
|
2075
|
+
const stat2 = await fs9.promises.stat(filePath);
|
|
1994
2076
|
let chunks;
|
|
1995
2077
|
let chunkOffset = 0;
|
|
1996
2078
|
const resetChunks = async () => {
|
|
@@ -2267,7 +2349,7 @@ function formatConvergeApplyReport(result) {
|
|
|
2267
2349
|
lines.push(formatConvergeReport(result.plan));
|
|
2268
2350
|
return lines.join("\n");
|
|
2269
2351
|
}
|
|
2270
|
-
async function cmdConverge(action, rest, json, config =
|
|
2352
|
+
async function cmdConverge(action, rest, json, config = parseConfig8({})) {
|
|
2271
2353
|
if (action === "help" || action === "--help" || action === "-h" || rest.includes("--help") || rest.includes("-h")) {
|
|
2272
2354
|
console.log(`Usage: remnic converge <plan|apply> [options]
|
|
2273
2355
|
|
|
@@ -2473,8 +2555,8 @@ function renderReplayResult(result, targetNamespace, format) {
|
|
|
2473
2555
|
}
|
|
2474
2556
|
|
|
2475
2557
|
// src/quarantine-replay.ts
|
|
2476
|
-
import * as
|
|
2477
|
-
import { EngramAccessService, Orchestrator as
|
|
2558
|
+
import * as fs10 from "fs";
|
|
2559
|
+
import { EngramAccessService, Orchestrator as Orchestrator5, initLogger as initLogger3, parseConfig as parseConfig9, resolveRemnicConfigRecord as resolveRemnicConfigRecord8 } from "@remnic/core";
|
|
2478
2560
|
import { WriteQuarantineStore } from "@remnic/core/write-quarantine.js";
|
|
2479
2561
|
function valueFlag(args, flag) {
|
|
2480
2562
|
const occurrences = args.filter((a) => a === flag).length;
|
|
@@ -2522,9 +2604,9 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
|
|
|
2522
2604
|
let orchestrator;
|
|
2523
2605
|
try {
|
|
2524
2606
|
const configPath = resolveConfigPath2();
|
|
2525
|
-
const raw =
|
|
2526
|
-
const config =
|
|
2527
|
-
orchestrator = new
|
|
2607
|
+
const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
|
|
2608
|
+
const config = parseConfig9(resolveRemnicConfigRecord8(raw));
|
|
2609
|
+
orchestrator = new Orchestrator5(config);
|
|
2528
2610
|
await orchestrator.initialize();
|
|
2529
2611
|
await orchestrator.deferredReady;
|
|
2530
2612
|
const service = new EngramAccessService(orchestrator);
|
|
@@ -2554,15 +2636,15 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
|
|
|
2554
2636
|
}
|
|
2555
2637
|
|
|
2556
2638
|
// src/offline-impression-rotation.ts
|
|
2557
|
-
import
|
|
2558
|
-
import { parseConfig as
|
|
2639
|
+
import fs11 from "fs";
|
|
2640
|
+
import { parseConfig as parseConfig10, resolveRemnicConfigRecord as resolveRemnicConfigRecord9, drainPendingImpressionsForOfflineSync } from "@remnic/core";
|
|
2559
2641
|
import { LastRecallStore } from "@remnic/core/recall-state";
|
|
2560
2642
|
function parseConfigQuietly(raw) {
|
|
2561
2643
|
const originalWarn = console.warn;
|
|
2562
2644
|
console.warn = () => {
|
|
2563
2645
|
};
|
|
2564
2646
|
try {
|
|
2565
|
-
return
|
|
2647
|
+
return parseConfig10(resolveRemnicConfigRecord9(raw));
|
|
2566
2648
|
} finally {
|
|
2567
2649
|
console.warn = originalWarn;
|
|
2568
2650
|
}
|
|
@@ -2576,7 +2658,7 @@ var OFFLINE_CONFIG_KEYS = [
|
|
|
2576
2658
|
function pickOfflineConfigRecord(raw) {
|
|
2577
2659
|
let resolved;
|
|
2578
2660
|
try {
|
|
2579
|
-
resolved =
|
|
2661
|
+
resolved = resolveRemnicConfigRecord9(raw);
|
|
2580
2662
|
} catch {
|
|
2581
2663
|
resolved = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
2582
2664
|
}
|
|
@@ -2589,7 +2671,7 @@ function pickOfflineConfigRecord(raw) {
|
|
|
2589
2671
|
function resolveOfflineImpressionRotation(configPath) {
|
|
2590
2672
|
let raw;
|
|
2591
2673
|
try {
|
|
2592
|
-
raw =
|
|
2674
|
+
raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
|
|
2593
2675
|
} catch {
|
|
2594
2676
|
throw new Error(
|
|
2595
2677
|
`cannot read recall-impression rotation from ${configPath}: config file could not be read as JSON`
|
|
@@ -2847,12 +2929,12 @@ function assertBenchModuleFreshForDevelopment() {
|
|
|
2847
2929
|
}
|
|
2848
2930
|
|
|
2849
2931
|
// src/cmd-security.ts
|
|
2850
|
-
import
|
|
2932
|
+
import fs12 from "fs";
|
|
2851
2933
|
import {
|
|
2852
|
-
Orchestrator as
|
|
2853
|
-
parseConfig as
|
|
2934
|
+
Orchestrator as Orchestrator6,
|
|
2935
|
+
parseConfig as parseConfig11,
|
|
2854
2936
|
initLogger as initLogger4,
|
|
2855
|
-
resolveRemnicConfigRecord as
|
|
2937
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord10,
|
|
2856
2938
|
runAuditMemoryCliCommand,
|
|
2857
2939
|
formatAuditMemoryReport
|
|
2858
2940
|
} from "@remnic/core";
|
|
@@ -2867,9 +2949,9 @@ async function cmdSecurity(rest) {
|
|
|
2867
2949
|
}
|
|
2868
2950
|
initLogger4();
|
|
2869
2951
|
const configPath = resolveConfigPath();
|
|
2870
|
-
const raw =
|
|
2871
|
-
const config =
|
|
2872
|
-
const orchestrator = new
|
|
2952
|
+
const raw = fs12.existsSync(configPath) ? JSON.parse(fs12.readFileSync(configPath, "utf8")) : {};
|
|
2953
|
+
const config = parseConfig11(resolveRemnicConfigRecord10(raw));
|
|
2954
|
+
const orchestrator = new Orchestrator6(config);
|
|
2873
2955
|
await orchestrator.initialize();
|
|
2874
2956
|
try {
|
|
2875
2957
|
const sinceFlag = rest.indexOf("--since");
|
|
@@ -2892,7 +2974,7 @@ async function cmdSecurity(rest) {
|
|
|
2892
2974
|
}
|
|
2893
2975
|
|
|
2894
2976
|
// src/daemon-service-candidates.ts
|
|
2895
|
-
import
|
|
2977
|
+
import fs13 from "fs";
|
|
2896
2978
|
import path5 from "path";
|
|
2897
2979
|
var LAUNCHD_LABEL = "ai.remnic.daemon";
|
|
2898
2980
|
var LEGACY_REMNIC_SERVER_LAUNCHD_LABEL = "ai.remnic.server";
|
|
@@ -2914,7 +2996,7 @@ function systemdUnitPaths(homeDir) {
|
|
|
2914
2996
|
function anyFileExists(paths) {
|
|
2915
2997
|
return paths.some((candidate) => {
|
|
2916
2998
|
try {
|
|
2917
|
-
return
|
|
2999
|
+
return fs13.statSync(candidate).isFile();
|
|
2918
3000
|
} catch {
|
|
2919
3001
|
return false;
|
|
2920
3002
|
}
|
|
@@ -2926,7 +3008,7 @@ function commandNames(command) {
|
|
|
2926
3008
|
}
|
|
2927
3009
|
function isRunnableNodeScript(filePath) {
|
|
2928
3010
|
try {
|
|
2929
|
-
const text =
|
|
3011
|
+
const text = fs13.readFileSync(filePath, "utf8").slice(0, 4096);
|
|
2930
3012
|
const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
|
|
2931
3013
|
if (/^#!.*\bnode\b/.test(firstLine)) return true;
|
|
2932
3014
|
if (firstLine.startsWith("#!")) return false;
|
|
@@ -2939,7 +3021,7 @@ function isRunnableNodeScript(filePath) {
|
|
|
2939
3021
|
function resolveShimNodeScript(filePath) {
|
|
2940
3022
|
let text;
|
|
2941
3023
|
try {
|
|
2942
|
-
text =
|
|
3024
|
+
text = fs13.readFileSync(filePath, "utf8").slice(0, 16384);
|
|
2943
3025
|
} catch {
|
|
2944
3026
|
return void 0;
|
|
2945
3027
|
}
|
|
@@ -2951,8 +3033,8 @@ function resolveShimNodeScript(filePath) {
|
|
|
2951
3033
|
const candidate = raw.replaceAll("${basedir}", basedir).replaceAll("$basedir", basedir).replaceAll("\\ ", " ");
|
|
2952
3034
|
const resolved = path5.isAbsolute(candidate) ? candidate : path5.resolve(basedir, candidate);
|
|
2953
3035
|
try {
|
|
2954
|
-
if (
|
|
2955
|
-
return
|
|
3036
|
+
if (fs13.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
|
|
3037
|
+
return fs13.realpathSync(resolved);
|
|
2956
3038
|
}
|
|
2957
3039
|
} catch {
|
|
2958
3040
|
}
|
|
@@ -2960,7 +3042,7 @@ function resolveShimNodeScript(filePath) {
|
|
|
2960
3042
|
return void 0;
|
|
2961
3043
|
}
|
|
2962
3044
|
function resolveRunnableNodeScript(filePath) {
|
|
2963
|
-
const realPath =
|
|
3045
|
+
const realPath = fs13.realpathSync(filePath);
|
|
2964
3046
|
if (isRunnableNodeScript(realPath)) return realPath;
|
|
2965
3047
|
return resolveShimNodeScript(realPath);
|
|
2966
3048
|
}
|
|
@@ -2970,9 +3052,9 @@ function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
|
|
|
2970
3052
|
for (const name of commandNames(command)) {
|
|
2971
3053
|
const candidate = path5.join(dir, name);
|
|
2972
3054
|
try {
|
|
2973
|
-
const stat2 =
|
|
3055
|
+
const stat2 = fs13.statSync(candidate);
|
|
2974
3056
|
if (!stat2.isFile()) continue;
|
|
2975
|
-
if (process.platform !== "win32")
|
|
3057
|
+
if (process.platform !== "win32") fs13.accessSync(candidate, fs13.constants.X_OK);
|
|
2976
3058
|
const runnable = resolveRunnableNodeScript(candidate);
|
|
2977
3059
|
if (runnable) return runnable;
|
|
2978
3060
|
} catch {
|
|
@@ -4445,7 +4527,7 @@ function finalizeBenchStatus(filePath) {
|
|
|
4445
4527
|
}
|
|
4446
4528
|
|
|
4447
4529
|
// src/bench-fallback.ts
|
|
4448
|
-
import
|
|
4530
|
+
import fs14 from "fs";
|
|
4449
4531
|
import path9 from "path";
|
|
4450
4532
|
var FALLBACK_RESULTS_DIRNAME = "fallback-runs";
|
|
4451
4533
|
function buildBenchRunnerArgs(parsed, benchmarkId, outputDir) {
|
|
@@ -4517,7 +4599,7 @@ function createFallbackBenchOutputDir(resultsDir, benchmarkId, pid, startedAtMs
|
|
|
4517
4599
|
);
|
|
4518
4600
|
}
|
|
4519
4601
|
function resolveFallbackBenchResultPath(outputDir) {
|
|
4520
|
-
const entries =
|
|
4602
|
+
const entries = fs14.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
|
|
4521
4603
|
if (entries.length === 0) {
|
|
4522
4604
|
throw new Error(`Fallback benchmark runner did not write a JSON result artifact in ${outputDir}`);
|
|
4523
4605
|
}
|
|
@@ -4525,7 +4607,7 @@ function resolveFallbackBenchResultPath(outputDir) {
|
|
|
4525
4607
|
}
|
|
4526
4608
|
|
|
4527
4609
|
// src/openclaw-upgrade-swap.ts
|
|
4528
|
-
import
|
|
4610
|
+
import fs15 from "fs";
|
|
4529
4611
|
import path10 from "path";
|
|
4530
4612
|
function describeError(error) {
|
|
4531
4613
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -4537,7 +4619,7 @@ function createSiblingTempFilePath(targetPath, label) {
|
|
|
4537
4619
|
function resolveAtomicWriteMode(targetPath, explicitMode) {
|
|
4538
4620
|
if (explicitMode !== void 0) return explicitMode;
|
|
4539
4621
|
try {
|
|
4540
|
-
return
|
|
4622
|
+
return fs15.statSync(targetPath).mode & 4095;
|
|
4541
4623
|
} catch (error) {
|
|
4542
4624
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
4543
4625
|
return 384;
|
|
@@ -4547,8 +4629,8 @@ function resolveAtomicWriteMode(targetPath, explicitMode) {
|
|
|
4547
4629
|
}
|
|
4548
4630
|
function resolveAtomicReplacementPath(targetPath) {
|
|
4549
4631
|
try {
|
|
4550
|
-
if (
|
|
4551
|
-
return
|
|
4632
|
+
if (fs15.lstatSync(targetPath).isSymbolicLink()) {
|
|
4633
|
+
return fs15.realpathSync(targetPath);
|
|
4552
4634
|
}
|
|
4553
4635
|
} catch (error) {
|
|
4554
4636
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -4565,7 +4647,7 @@ function createSiblingSwapPath(targetDir, label) {
|
|
|
4565
4647
|
function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
|
|
4566
4648
|
if (!displacedDir) return void 0;
|
|
4567
4649
|
try {
|
|
4568
|
-
|
|
4650
|
+
fs15.rmSync(displacedDir, { recursive: true, force: true });
|
|
4569
4651
|
return void 0;
|
|
4570
4652
|
} catch (error) {
|
|
4571
4653
|
return `Warning: ${context}, but failed to remove the displaced plugin copy at ${displacedDir}: ${describeError(error)}`;
|
|
@@ -4573,43 +4655,43 @@ function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
|
|
|
4573
4655
|
}
|
|
4574
4656
|
function atomicWriteFileSync(targetPath, data, options = {}) {
|
|
4575
4657
|
const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
|
|
4576
|
-
|
|
4658
|
+
fs15.mkdirSync(path10.dirname(resolvedTargetPath), { recursive: true });
|
|
4577
4659
|
const tempPath = createSiblingTempFilePath(resolvedTargetPath, "write");
|
|
4578
4660
|
const mode = resolveAtomicWriteMode(resolvedTargetPath, options.mode);
|
|
4579
4661
|
try {
|
|
4580
4662
|
if (options.hooks?.writeTempFileSync) {
|
|
4581
4663
|
options.hooks.writeTempFileSync(tempPath);
|
|
4582
4664
|
} else {
|
|
4583
|
-
|
|
4665
|
+
fs15.writeFileSync(tempPath, data, { mode });
|
|
4584
4666
|
}
|
|
4585
|
-
|
|
4586
|
-
const renameTempFileSync = options.hooks?.renameTempFileSync ??
|
|
4667
|
+
fs15.chmodSync(tempPath, mode);
|
|
4668
|
+
const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs15.renameSync;
|
|
4587
4669
|
renameTempFileSync(tempPath, resolvedTargetPath);
|
|
4588
4670
|
} catch (error) {
|
|
4589
|
-
|
|
4671
|
+
fs15.rmSync(tempPath, { force: true });
|
|
4590
4672
|
throw error;
|
|
4591
4673
|
}
|
|
4592
4674
|
}
|
|
4593
4675
|
function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
|
|
4594
|
-
if (!
|
|
4676
|
+
if (!fs15.existsSync(sourcePath)) return;
|
|
4595
4677
|
const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
|
|
4596
|
-
|
|
4678
|
+
fs15.mkdirSync(path10.dirname(resolvedTargetPath), { recursive: true });
|
|
4597
4679
|
const tempPath = createSiblingTempFilePath(resolvedTargetPath, "copy");
|
|
4598
|
-
const mode =
|
|
4680
|
+
const mode = fs15.statSync(sourcePath).mode & 4095;
|
|
4599
4681
|
try {
|
|
4600
|
-
const copyTempFileSync = options.hooks?.copyTempFileSync ??
|
|
4682
|
+
const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs15.copyFileSync;
|
|
4601
4683
|
copyTempFileSync(sourcePath, tempPath);
|
|
4602
|
-
|
|
4603
|
-
const renameTempFileSync = options.hooks?.renameTempFileSync ??
|
|
4684
|
+
fs15.chmodSync(tempPath, mode);
|
|
4685
|
+
const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs15.renameSync;
|
|
4604
4686
|
renameTempFileSync(tempPath, resolvedTargetPath);
|
|
4605
4687
|
} catch (error) {
|
|
4606
|
-
|
|
4688
|
+
fs15.rmSync(tempPath, { force: true });
|
|
4607
4689
|
throw error;
|
|
4608
4690
|
}
|
|
4609
4691
|
}
|
|
4610
4692
|
function cleanupRollbackDirectory(rollbackDir) {
|
|
4611
4693
|
if (!rollbackDir) return;
|
|
4612
|
-
|
|
4694
|
+
fs15.rmSync(rollbackDir, { recursive: true, force: true });
|
|
4613
4695
|
}
|
|
4614
4696
|
function cleanupRollbackDirectoryBestEffort(rollbackDir) {
|
|
4615
4697
|
if (!rollbackDir) return void 0;
|
|
@@ -4621,20 +4703,20 @@ function cleanupRollbackDirectoryBestEffort(rollbackDir) {
|
|
|
4621
4703
|
}
|
|
4622
4704
|
}
|
|
4623
4705
|
function restoreDirectoryFromRollback(targetDir, rollbackDir) {
|
|
4624
|
-
if (!
|
|
4706
|
+
if (!fs15.existsSync(rollbackDir)) {
|
|
4625
4707
|
throw new Error(`Rollback directory is missing: ${rollbackDir}`);
|
|
4626
4708
|
}
|
|
4627
|
-
|
|
4628
|
-
const displacedDir =
|
|
4709
|
+
fs15.mkdirSync(path10.dirname(targetDir), { recursive: true });
|
|
4710
|
+
const displacedDir = fs15.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
|
|
4629
4711
|
if (displacedDir) {
|
|
4630
|
-
|
|
4712
|
+
fs15.renameSync(targetDir, displacedDir);
|
|
4631
4713
|
}
|
|
4632
4714
|
try {
|
|
4633
|
-
|
|
4715
|
+
fs15.renameSync(rollbackDir, targetDir);
|
|
4634
4716
|
} catch (restoreError) {
|
|
4635
|
-
if (displacedDir &&
|
|
4717
|
+
if (displacedDir && fs15.existsSync(displacedDir)) {
|
|
4636
4718
|
try {
|
|
4637
|
-
|
|
4719
|
+
fs15.renameSync(displacedDir, targetDir);
|
|
4638
4720
|
} catch (revertError) {
|
|
4639
4721
|
throw new AggregateError(
|
|
4640
4722
|
[restoreError, revertError],
|
|
@@ -4650,23 +4732,23 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
|
|
|
4650
4732
|
return cleanupDisplacedDirectoryBestEffort(displacedDir, `restored the previous plugin copy into ${targetDir}`);
|
|
4651
4733
|
}
|
|
4652
4734
|
function restoreDirectoryFromBackup(targetDir, backupDir) {
|
|
4653
|
-
if (!
|
|
4735
|
+
if (!fs15.existsSync(backupDir)) {
|
|
4654
4736
|
throw new Error(`Plugin backup directory is missing: ${backupDir}`);
|
|
4655
4737
|
}
|
|
4656
|
-
|
|
4738
|
+
fs15.mkdirSync(path10.dirname(targetDir), { recursive: true });
|
|
4657
4739
|
const stagedDir = createSiblingSwapPath(targetDir, "backup-restore");
|
|
4658
|
-
const displacedDir =
|
|
4659
|
-
|
|
4740
|
+
const displacedDir = fs15.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
|
|
4741
|
+
fs15.cpSync(backupDir, stagedDir, { recursive: true });
|
|
4660
4742
|
if (displacedDir) {
|
|
4661
|
-
|
|
4743
|
+
fs15.renameSync(targetDir, displacedDir);
|
|
4662
4744
|
}
|
|
4663
4745
|
try {
|
|
4664
|
-
|
|
4746
|
+
fs15.renameSync(stagedDir, targetDir);
|
|
4665
4747
|
} catch (restoreError) {
|
|
4666
|
-
|
|
4667
|
-
if (displacedDir &&
|
|
4748
|
+
fs15.rmSync(targetDir, { recursive: true, force: true });
|
|
4749
|
+
if (displacedDir && fs15.existsSync(displacedDir)) {
|
|
4668
4750
|
try {
|
|
4669
|
-
|
|
4751
|
+
fs15.renameSync(displacedDir, targetDir);
|
|
4670
4752
|
} catch (revertError) {
|
|
4671
4753
|
throw new AggregateError(
|
|
4672
4754
|
[restoreError, revertError],
|
|
@@ -4674,7 +4756,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
|
|
|
4674
4756
|
);
|
|
4675
4757
|
}
|
|
4676
4758
|
}
|
|
4677
|
-
|
|
4759
|
+
fs15.rmSync(stagedDir, { recursive: true, force: true });
|
|
4678
4760
|
throw new Error(
|
|
4679
4761
|
`Failed to restore the plugin backup into ${targetDir}. The durable backup remains preserved at ${backupDir}.`,
|
|
4680
4762
|
{ cause: restoreError }
|
|
@@ -4699,7 +4781,7 @@ function rollbackOpenclawUpgrade({
|
|
|
4699
4781
|
let configRemovalAttempted = false;
|
|
4700
4782
|
let pluginRestored = false;
|
|
4701
4783
|
try {
|
|
4702
|
-
if (rollbackDir &&
|
|
4784
|
+
if (rollbackDir && fs15.existsSync(rollbackDir)) {
|
|
4703
4785
|
const cleanupWarning = restoreDirectoryFromRollback(pluginDir, rollbackDir);
|
|
4704
4786
|
notes.push(`Restored previous plugin from rollback copy at ${rollbackDir}`);
|
|
4705
4787
|
if (cleanupWarning) notes.push(cleanupWarning);
|
|
@@ -4709,7 +4791,7 @@ function rollbackOpenclawUpgrade({
|
|
|
4709
4791
|
rollbackRestoreError = error instanceof Error ? error.message : String(error);
|
|
4710
4792
|
}
|
|
4711
4793
|
try {
|
|
4712
|
-
if (!pluginRestored && pluginBackupDir &&
|
|
4794
|
+
if (!pluginRestored && pluginBackupDir && fs15.existsSync(pluginBackupDir)) {
|
|
4713
4795
|
const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
|
|
4714
4796
|
if (rollbackRestoreError) {
|
|
4715
4797
|
notes.push(`Rollback copy restore failed; restored previous plugin from durable backup at ${pluginBackupDir}`);
|
|
@@ -4734,12 +4816,12 @@ function rollbackOpenclawUpgrade({
|
|
|
4734
4816
|
notes.push("No previous plugin copy was available for automatic restore");
|
|
4735
4817
|
}
|
|
4736
4818
|
try {
|
|
4737
|
-
if (configBackupPath &&
|
|
4819
|
+
if (configBackupPath && fs15.existsSync(configBackupPath)) {
|
|
4738
4820
|
restoreFileFromBackup(configPath, configBackupPath);
|
|
4739
4821
|
notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
|
|
4740
|
-
} else if (removeConfigIfUnbacked &&
|
|
4822
|
+
} else if (removeConfigIfUnbacked && fs15.existsSync(configPath)) {
|
|
4741
4823
|
configRemovalAttempted = true;
|
|
4742
|
-
|
|
4824
|
+
fs15.rmSync(configPath, { force: true });
|
|
4743
4825
|
notes.push("Removed OpenClaw config created during the failed upgrade");
|
|
4744
4826
|
}
|
|
4745
4827
|
} catch (error) {
|
|
@@ -4792,7 +4874,7 @@ Run this manually when you're ready:
|
|
|
4792
4874
|
|
|
4793
4875
|
// src/openclaw-managed-upgrade-loader.ts
|
|
4794
4876
|
import { execFileSync } from "child_process";
|
|
4795
|
-
import
|
|
4877
|
+
import fs16 from "fs";
|
|
4796
4878
|
import os from "os";
|
|
4797
4879
|
import path11 from "path";
|
|
4798
4880
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -4868,7 +4950,7 @@ function buildOpenclawManagedUpgradePackageSpec(version = "latest") {
|
|
|
4868
4950
|
function readCliAdapterRange() {
|
|
4869
4951
|
const moduleDir = path11.dirname(fileURLToPath3(import.meta.url));
|
|
4870
4952
|
const manifestPath = path11.resolve(moduleDir, "../package.json");
|
|
4871
|
-
const manifest = JSON.parse(
|
|
4953
|
+
const manifest = JSON.parse(fs16.readFileSync(manifestPath, "utf8"));
|
|
4872
4954
|
if (manifest.name !== "@remnic/cli") {
|
|
4873
4955
|
throw new Error(`Invalid @remnic/cli package manifest at ${manifestPath}.`);
|
|
4874
4956
|
}
|
|
@@ -4912,7 +4994,7 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
4912
4994
|
const adapterMissing = isSpecifierNotFoundError(error, OPENCLAW_PLUGIN_PACKAGE) || isSpecifierNotFoundError(error, MANAGED_UPGRADE_SPECIFIER) || isManagedUpgradeSubpathMissing(error);
|
|
4913
4995
|
if (!adapterMissing) throw error;
|
|
4914
4996
|
}
|
|
4915
|
-
const temporaryRoot =
|
|
4997
|
+
const temporaryRoot = fs16.mkdtempSync(path11.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
|
|
4916
4998
|
try {
|
|
4917
4999
|
const toolingPackageSpec = `${OPENCLAW_PLUGIN_PACKAGE}@${readCliAdapterRange()}`;
|
|
4918
5000
|
const installArgs = [
|
|
@@ -4927,12 +5009,12 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
4927
5009
|
];
|
|
4928
5010
|
(hooks.runNpmInstall ?? runNpmInstall)(installArgs);
|
|
4929
5011
|
const resolverPath = path11.join(temporaryRoot, "load-managed-upgrade.mjs");
|
|
4930
|
-
|
|
5012
|
+
fs16.writeFileSync(resolverPath, `export * from ${JSON.stringify(MANAGED_UPGRADE_SPECIFIER)};
|
|
4931
5013
|
`, "utf8");
|
|
4932
5014
|
return await importModule(pathToFileURL2(resolverPath).href);
|
|
4933
5015
|
} finally {
|
|
4934
5016
|
try {
|
|
4935
|
-
|
|
5017
|
+
fs16.rmSync(temporaryRoot, { recursive: true, force: true });
|
|
4936
5018
|
} catch (error) {
|
|
4937
5019
|
const detail = error instanceof Error ? error.message : String(error);
|
|
4938
5020
|
console.warn(`Could not remove temporary managed upgrade project at ${temporaryRoot}: ${detail}`);
|
|
@@ -4941,13 +5023,13 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
4941
5023
|
}
|
|
4942
5024
|
|
|
4943
5025
|
// src/remote-daemon.ts
|
|
4944
|
-
import
|
|
5026
|
+
import fs17 from "fs";
|
|
4945
5027
|
function readCompatEnv(primary, legacy) {
|
|
4946
5028
|
return process.env[primary] ?? process.env[legacy];
|
|
4947
5029
|
}
|
|
4948
5030
|
function readRemnicConfigRecord(configPath) {
|
|
4949
5031
|
try {
|
|
4950
|
-
const parsed = JSON.parse(
|
|
5032
|
+
const parsed = JSON.parse(fs17.readFileSync(configPath, "utf8"));
|
|
4951
5033
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
4952
5034
|
return parsed;
|
|
4953
5035
|
}
|
|
@@ -5176,7 +5258,7 @@ async function remoteRecallXray(daemon, request) {
|
|
|
5176
5258
|
}
|
|
5177
5259
|
|
|
5178
5260
|
// src/daemon-service.ts
|
|
5179
|
-
import
|
|
5261
|
+
import fs18 from "fs";
|
|
5180
5262
|
import path12 from "path";
|
|
5181
5263
|
import * as childProcess from "child_process";
|
|
5182
5264
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
@@ -5188,7 +5270,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
|
|
|
5188
5270
|
processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
|
|
5189
5271
|
}
|
|
5190
5272
|
function resolveServerBinDetails(options = {}) {
|
|
5191
|
-
const existsSync4 = options.existsSync ??
|
|
5273
|
+
const existsSync4 = options.existsSync ?? fs18.existsSync;
|
|
5192
5274
|
const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
|
|
5193
5275
|
const moduleDir = options.moduleDir ?? thisModuleDir;
|
|
5194
5276
|
const packageResolve = options.packageResolve ?? resolveImportSpecifier;
|
|
@@ -5247,8 +5329,8 @@ function resolveServerBin(options = {}) {
|
|
|
5247
5329
|
return resolveServerBinDetails(options).path;
|
|
5248
5330
|
}
|
|
5249
5331
|
function readVerifiedDaemonPid(options) {
|
|
5250
|
-
const readFileSync4 = options.readFileSync ??
|
|
5251
|
-
const unlinkSync = options.unlinkSync ??
|
|
5332
|
+
const readFileSync4 = options.readFileSync ?? fs18.readFileSync;
|
|
5333
|
+
const unlinkSync = options.unlinkSync ?? fs18.unlinkSync;
|
|
5252
5334
|
const processKill = options.processKill ?? process.kill;
|
|
5253
5335
|
const platform = options.platform ?? process.platform;
|
|
5254
5336
|
const execFileSync4 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
|
|
@@ -5348,8 +5430,8 @@ function removePidFileBestEffort(file, unlinkSync) {
|
|
|
5348
5430
|
}
|
|
5349
5431
|
}
|
|
5350
5432
|
function inspectLaunchdPlist(plistPath, options = {}) {
|
|
5351
|
-
const existsSync4 = options.existsSync ??
|
|
5352
|
-
const readFileSync4 = options.readFileSync ??
|
|
5433
|
+
const existsSync4 = options.existsSync ?? fs18.existsSync;
|
|
5434
|
+
const readFileSync4 = options.readFileSync ?? fs18.readFileSync;
|
|
5353
5435
|
if (!existsSync4(plistPath)) {
|
|
5354
5436
|
return {
|
|
5355
5437
|
installed: false,
|
|
@@ -5527,7 +5609,7 @@ function stripConfigArgv(args) {
|
|
|
5527
5609
|
}
|
|
5528
5610
|
|
|
5529
5611
|
// src/import-dispatch.ts
|
|
5530
|
-
import
|
|
5612
|
+
import fs19 from "fs";
|
|
5531
5613
|
import {
|
|
5532
5614
|
runImporter,
|
|
5533
5615
|
validateImportBatchSize,
|
|
@@ -6041,7 +6123,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
|
|
|
6041
6123
|
let materializedTarget;
|
|
6042
6124
|
let materializePromise;
|
|
6043
6125
|
const io = {
|
|
6044
|
-
readFile: ioOverrides.readFile ?? (async (p) =>
|
|
6126
|
+
readFile: ioOverrides.readFile ?? (async (p) => fs19.promises.readFile(p, "utf-8")),
|
|
6045
6127
|
loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
|
|
6046
6128
|
runImporter: ioOverrides.runImporter ?? runImporter,
|
|
6047
6129
|
getWriteTarget: async () => {
|
|
@@ -6154,7 +6236,7 @@ async function cmdCapture(rest, io) {
|
|
|
6154
6236
|
}
|
|
6155
6237
|
|
|
6156
6238
|
// src/import-lossless-claw-cmd.ts
|
|
6157
|
-
import
|
|
6239
|
+
import fs20 from "fs";
|
|
6158
6240
|
import path14 from "path";
|
|
6159
6241
|
import {
|
|
6160
6242
|
applyLcmSchema,
|
|
@@ -6266,15 +6348,15 @@ async function loadImportLosslessClawModule() {
|
|
|
6266
6348
|
|
|
6267
6349
|
// src/import-lossless-claw-cmd.ts
|
|
6268
6350
|
function assertDirectoryOrAbsent(p, label) {
|
|
6269
|
-
if (
|
|
6351
|
+
if (fs20.existsSync(p) && !fs20.statSync(p).isDirectory()) {
|
|
6270
6352
|
throw new Error(`${label} is not a directory: ${p}`);
|
|
6271
6353
|
}
|
|
6272
6354
|
}
|
|
6273
6355
|
function assertFile(p, label) {
|
|
6274
|
-
if (!
|
|
6356
|
+
if (!fs20.existsSync(p)) {
|
|
6275
6357
|
throw new Error(`${label} does not exist: ${p}`);
|
|
6276
6358
|
}
|
|
6277
|
-
if (!
|
|
6359
|
+
if (!fs20.statSync(p).isFile()) {
|
|
6278
6360
|
throw new Error(`${label} is not a file: ${p}`);
|
|
6279
6361
|
}
|
|
6280
6362
|
}
|
|
@@ -6306,7 +6388,7 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
|
|
|
6306
6388
|
try {
|
|
6307
6389
|
if (parsed.dryRun) {
|
|
6308
6390
|
const lcmPath = path14.join(memoryDir, "state", "lcm.sqlite");
|
|
6309
|
-
if (
|
|
6391
|
+
if (fs20.existsSync(lcmPath)) {
|
|
6310
6392
|
destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
|
|
6311
6393
|
} else {
|
|
6312
6394
|
destDb = mod.openInMemoryDestinationDatabase();
|
|
@@ -7658,7 +7740,7 @@ async function resolveAllBenchmarks() {
|
|
|
7658
7740
|
if (packageBenchmarks) {
|
|
7659
7741
|
return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
|
|
7660
7742
|
}
|
|
7661
|
-
if (!
|
|
7743
|
+
if (!fs21.existsSync(EVAL_RUNNER_PATH)) {
|
|
7662
7744
|
return [];
|
|
7663
7745
|
}
|
|
7664
7746
|
return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
|
|
@@ -7706,7 +7788,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
|
|
|
7706
7788
|
`Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
|
|
7707
7789
|
);
|
|
7708
7790
|
}
|
|
7709
|
-
if (!
|
|
7791
|
+
if (!fs21.existsSync(EVAL_RUNNER_PATH)) {
|
|
7710
7792
|
console.error(
|
|
7711
7793
|
"Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
|
|
7712
7794
|
);
|
|
@@ -7716,7 +7798,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
|
|
|
7716
7798
|
path18.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
|
|
7717
7799
|
path18.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
|
|
7718
7800
|
];
|
|
7719
|
-
const tsxCmd = tsxCandidates.find((candidate) =>
|
|
7801
|
+
const tsxCmd = tsxCandidates.find((candidate) => fs21.existsSync(candidate)) ?? "tsx";
|
|
7720
7802
|
const fallbackOutputDir = createFallbackBenchOutputDir(
|
|
7721
7803
|
parsed.resultsDir ?? resolveBenchOutputDir(),
|
|
7722
7804
|
benchmarkId,
|
|
@@ -7861,9 +7943,9 @@ var PERSONAMEM_COMPLETION_MARKER = path18.join(
|
|
|
7861
7943
|
);
|
|
7862
7944
|
function resolveRealpathWithinDataset(datasetPath, relativePath) {
|
|
7863
7945
|
try {
|
|
7864
|
-
const datasetRoot =
|
|
7946
|
+
const datasetRoot = fs21.realpathSync(datasetPath);
|
|
7865
7947
|
const candidatePath = path18.resolve(datasetRoot, relativePath);
|
|
7866
|
-
const candidateRealPath =
|
|
7948
|
+
const candidateRealPath = fs21.realpathSync(candidatePath);
|
|
7867
7949
|
const relativeToRoot = path18.relative(datasetRoot, candidateRealPath);
|
|
7868
7950
|
if (relativeToRoot.startsWith("..") || path18.isAbsolute(relativeToRoot)) {
|
|
7869
7951
|
return null;
|
|
@@ -7922,14 +8004,14 @@ function parseCsvRows(raw) {
|
|
|
7922
8004
|
function isPersonaMemDatasetComplete(datasetPath) {
|
|
7923
8005
|
try {
|
|
7924
8006
|
const completionMarkerPath = path18.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
|
|
7925
|
-
if (
|
|
8007
|
+
if (fs21.statSync(completionMarkerPath).isFile()) {
|
|
7926
8008
|
return true;
|
|
7927
8009
|
}
|
|
7928
8010
|
} catch {
|
|
7929
8011
|
}
|
|
7930
8012
|
const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
|
|
7931
8013
|
try {
|
|
7932
|
-
return
|
|
8014
|
+
return fs21.statSync(path18.join(datasetPath, candidate)).isFile();
|
|
7933
8015
|
} catch {
|
|
7934
8016
|
return false;
|
|
7935
8017
|
}
|
|
@@ -7938,7 +8020,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
7938
8020
|
return false;
|
|
7939
8021
|
}
|
|
7940
8022
|
try {
|
|
7941
|
-
const rows = parseCsvRows(
|
|
8023
|
+
const rows = parseCsvRows(fs21.readFileSync(path18.join(datasetPath, datasetFile), "utf8"));
|
|
7942
8024
|
if (rows.length < 2) {
|
|
7943
8025
|
return false;
|
|
7944
8026
|
}
|
|
@@ -7953,7 +8035,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
7953
8035
|
}
|
|
7954
8036
|
return historyPaths.every((relativePath) => {
|
|
7955
8037
|
const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
|
|
7956
|
-
return resolvedPath !== null &&
|
|
8038
|
+
return resolvedPath !== null && fs21.statSync(resolvedPath).isFile();
|
|
7957
8039
|
});
|
|
7958
8040
|
} catch {
|
|
7959
8041
|
return false;
|
|
@@ -7961,7 +8043,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
7961
8043
|
}
|
|
7962
8044
|
function hasDatasetFile(datasetPath, relativePath) {
|
|
7963
8045
|
try {
|
|
7964
|
-
return
|
|
8046
|
+
return fs21.statSync(path18.join(datasetPath, relativePath)).isFile();
|
|
7965
8047
|
} catch {
|
|
7966
8048
|
return false;
|
|
7967
8049
|
}
|
|
@@ -7981,10 +8063,10 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
|
|
|
7981
8063
|
return candidateFilenames.some((filename) => {
|
|
7982
8064
|
const filePath = path18.join(datasetPath, filename);
|
|
7983
8065
|
try {
|
|
7984
|
-
if (!
|
|
8066
|
+
if (!fs21.statSync(filePath).isFile()) {
|
|
7985
8067
|
return false;
|
|
7986
8068
|
}
|
|
7987
|
-
const raw =
|
|
8069
|
+
const raw = fs21.readFileSync(filePath, "utf8");
|
|
7988
8070
|
return /"source"\s*:\s*"recsys[_-]/i.test(raw);
|
|
7989
8071
|
} catch {
|
|
7990
8072
|
return false;
|
|
@@ -8000,7 +8082,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
|
|
|
8000
8082
|
function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
8001
8083
|
let stats;
|
|
8002
8084
|
try {
|
|
8003
|
-
stats =
|
|
8085
|
+
stats = fs21.statSync(datasetPath);
|
|
8004
8086
|
} catch {
|
|
8005
8087
|
return false;
|
|
8006
8088
|
}
|
|
@@ -8010,7 +8092,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8010
8092
|
const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
|
|
8011
8093
|
if (!marker) {
|
|
8012
8094
|
try {
|
|
8013
|
-
return
|
|
8095
|
+
return fs21.readdirSync(datasetPath).length > 0;
|
|
8014
8096
|
} catch {
|
|
8015
8097
|
return false;
|
|
8016
8098
|
}
|
|
@@ -8018,7 +8100,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8018
8100
|
if (marker.allOf) {
|
|
8019
8101
|
const hasAllRequiredFiles = marker.allOf.every((name) => {
|
|
8020
8102
|
try {
|
|
8021
|
-
return
|
|
8103
|
+
return fs21.statSync(path18.join(datasetPath, name)).isFile();
|
|
8022
8104
|
} catch {
|
|
8023
8105
|
return false;
|
|
8024
8106
|
}
|
|
@@ -8030,7 +8112,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8030
8112
|
if (marker.anyOf) {
|
|
8031
8113
|
const hasMarkerFile = marker.anyOf.some((name) => {
|
|
8032
8114
|
try {
|
|
8033
|
-
return
|
|
8115
|
+
return fs21.statSync(path18.join(datasetPath, name)).isFile();
|
|
8034
8116
|
} catch {
|
|
8035
8117
|
return false;
|
|
8036
8118
|
}
|
|
@@ -8048,7 +8130,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8048
8130
|
}
|
|
8049
8131
|
if (marker.ext) {
|
|
8050
8132
|
try {
|
|
8051
|
-
return
|
|
8133
|
+
return fs21.readdirSync(datasetPath).some(
|
|
8052
8134
|
(name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
|
|
8053
8135
|
);
|
|
8054
8136
|
} catch {
|
|
@@ -8060,7 +8142,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8060
8142
|
async function launchBenchUi(resultsDir) {
|
|
8061
8143
|
const benchUiDir = path18.join(CLI_REPO_ROOT, "packages", "bench-ui");
|
|
8062
8144
|
const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
8063
|
-
if (!
|
|
8145
|
+
if (!fs21.existsSync(path18.join(benchUiDir, "package.json"))) {
|
|
8064
8146
|
console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
|
|
8065
8147
|
process.exit(1);
|
|
8066
8148
|
}
|
|
@@ -8098,13 +8180,13 @@ function listDownloadableBenchmarks() {
|
|
|
8098
8180
|
}
|
|
8099
8181
|
function resolveDatasetDownloadScriptPath() {
|
|
8100
8182
|
const bundled = path18.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
|
|
8101
|
-
if (
|
|
8183
|
+
if (fs21.existsSync(bundled)) {
|
|
8102
8184
|
return bundled;
|
|
8103
8185
|
}
|
|
8104
8186
|
return path18.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
|
|
8105
8187
|
}
|
|
8106
8188
|
function isRepoCheckout() {
|
|
8107
|
-
return
|
|
8189
|
+
return fs21.existsSync(path18.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs21.existsSync(path18.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
|
|
8108
8190
|
}
|
|
8109
8191
|
function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
|
|
8110
8192
|
const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
|
|
@@ -8417,8 +8499,8 @@ async function exportBenchPackageResult(parsed) {
|
|
|
8417
8499
|
...reportCardProvenance ? { reportCardProvenance } : {}
|
|
8418
8500
|
});
|
|
8419
8501
|
if (parsed.output) {
|
|
8420
|
-
|
|
8421
|
-
|
|
8502
|
+
fs21.mkdirSync(path18.dirname(parsed.output), { recursive: true });
|
|
8503
|
+
fs21.writeFileSync(parsed.output, rendered);
|
|
8422
8504
|
console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
|
|
8423
8505
|
return;
|
|
8424
8506
|
}
|
|
@@ -8463,7 +8545,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8463
8545
|
process.exit(1);
|
|
8464
8546
|
}
|
|
8465
8547
|
const scriptPath = resolveDatasetDownloadScriptPath();
|
|
8466
|
-
if (!
|
|
8548
|
+
if (!fs21.existsSync(scriptPath)) {
|
|
8467
8549
|
console.error(`ERROR: dataset download script not found: ${scriptPath}`);
|
|
8468
8550
|
process.exit(1);
|
|
8469
8551
|
}
|
|
@@ -8663,7 +8745,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
8663
8745
|
);
|
|
8664
8746
|
process.exit(1);
|
|
8665
8747
|
}
|
|
8666
|
-
const sourceResultSha256 = createHash4("sha256").update(
|
|
8748
|
+
const sourceResultSha256 = createHash4("sha256").update(fs21.readFileSync(latest.path)).digest("hex");
|
|
8667
8749
|
const expandedManifestPath = expandTilde(manifestPath);
|
|
8668
8750
|
if (!bench.resolveLocalLabJudgeProviderConfig) {
|
|
8669
8751
|
console.error(
|
|
@@ -9078,7 +9160,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
|
|
|
9078
9160
|
}
|
|
9079
9161
|
let decoded;
|
|
9080
9162
|
try {
|
|
9081
|
-
decoded = JSON.parse(
|
|
9163
|
+
decoded = JSON.parse(fs21.readFileSync(parsed.taskIdsFile, "utf8"));
|
|
9082
9164
|
} catch (error) {
|
|
9083
9165
|
throw new Error(
|
|
9084
9166
|
`Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -9753,7 +9835,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
|
|
|
9753
9835
|
return void 0;
|
|
9754
9836
|
}
|
|
9755
9837
|
try {
|
|
9756
|
-
return
|
|
9838
|
+
return fs21.realpathSync(datasetDir);
|
|
9757
9839
|
} catch {
|
|
9758
9840
|
return datasetDir;
|
|
9759
9841
|
}
|
|
@@ -9807,13 +9889,13 @@ async function writeBenchReproManifestForPackageRun(args) {
|
|
|
9807
9889
|
}
|
|
9808
9890
|
function loadStandaloneConvergeCommandConfig() {
|
|
9809
9891
|
const configPath = resolveConfigPath();
|
|
9810
|
-
const raw =
|
|
9811
|
-
return
|
|
9892
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
9893
|
+
return parseConfig12(resolveRemnicConfigRecord11(raw));
|
|
9812
9894
|
}
|
|
9813
9895
|
function parseConvergePluginConfig(value) {
|
|
9814
9896
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9815
9897
|
if (Object.keys(value).length === 0) return void 0;
|
|
9816
|
-
return
|
|
9898
|
+
return parseConfig12(resolveRemnicConfigRecord11(value));
|
|
9817
9899
|
}
|
|
9818
9900
|
function loadConvergeCommandConfig() {
|
|
9819
9901
|
if (readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH")) {
|
|
@@ -9836,13 +9918,13 @@ function resolveConfigPath(cliPath) {
|
|
|
9836
9918
|
path18.join(resolveHomeDir(), ".config", "engram", "config.json")
|
|
9837
9919
|
];
|
|
9838
9920
|
for (const candidate of candidates) {
|
|
9839
|
-
if (
|
|
9921
|
+
if (fs21.existsSync(candidate)) return candidate;
|
|
9840
9922
|
}
|
|
9841
9923
|
return path18.join(resolveHomeDir(), ".config", "remnic", "config.json");
|
|
9842
9924
|
}
|
|
9843
9925
|
function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
9844
9926
|
const configPath = resolveConfigPath(cliPath);
|
|
9845
|
-
if (
|
|
9927
|
+
if (fs21.existsSync(configPath)) {
|
|
9846
9928
|
return configPath;
|
|
9847
9929
|
}
|
|
9848
9930
|
if (cliPath) {
|
|
@@ -9852,7 +9934,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
|
9852
9934
|
}
|
|
9853
9935
|
function resolveExistingBenchOpenclawConfigPath(cliPath) {
|
|
9854
9936
|
const configPath = resolveOpenclawConfigPath(cliPath);
|
|
9855
|
-
if (
|
|
9937
|
+
if (fs21.existsSync(configPath)) {
|
|
9856
9938
|
return configPath;
|
|
9857
9939
|
}
|
|
9858
9940
|
if (cliPath) {
|
|
@@ -9959,8 +10041,8 @@ function resolveMemoryDir() {
|
|
|
9959
10041
|
const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
|
|
9960
10042
|
if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
|
|
9961
10043
|
const configPath = resolveConfigPath();
|
|
9962
|
-
const raw =
|
|
9963
|
-
const remnicCfg =
|
|
10044
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
10045
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
9964
10046
|
if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
|
|
9965
10047
|
return normalizeMemoryDirPath(remnicCfg.memoryDir);
|
|
9966
10048
|
}
|
|
@@ -9968,18 +10050,18 @@ function resolveMemoryDir() {
|
|
|
9968
10050
|
const standalonePath = path18.join(home, ".remnic", "memory");
|
|
9969
10051
|
const legacyStandalonePath = path18.join(home, ".engram", "memory");
|
|
9970
10052
|
const openclawPath = path18.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
9971
|
-
if (
|
|
9972
|
-
if (
|
|
10053
|
+
if (fs21.existsSync(standalonePath)) return standalonePath;
|
|
10054
|
+
if (fs21.existsSync(legacyStandalonePath)) return legacyStandalonePath;
|
|
9973
10055
|
return openclawPath;
|
|
9974
10056
|
})();
|
|
9975
10057
|
const manifestPath = getManifestPath();
|
|
9976
|
-
if (
|
|
10058
|
+
if (fs21.existsSync(manifestPath)) {
|
|
9977
10059
|
try {
|
|
9978
10060
|
const active = getActiveSpace();
|
|
9979
10061
|
if (active?.memoryDir) {
|
|
9980
10062
|
const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
|
|
9981
|
-
if (!
|
|
9982
|
-
|
|
10063
|
+
if (!fs21.existsSync(activeMemoryDir)) {
|
|
10064
|
+
fs21.mkdirSync(activeMemoryDir, { recursive: true });
|
|
9983
10065
|
}
|
|
9984
10066
|
return activeMemoryDir;
|
|
9985
10067
|
}
|
|
@@ -10028,13 +10110,13 @@ function resolveOpenclawConfigPath(cliPath) {
|
|
|
10028
10110
|
const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
|
|
10029
10111
|
if (envPath) return path18.resolve(expandTilde(envPath));
|
|
10030
10112
|
for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
|
|
10031
|
-
if (
|
|
10113
|
+
if (fs21.existsSync(candidate)) return candidate;
|
|
10032
10114
|
}
|
|
10033
10115
|
return path18.join(resolveOpenclawStateDir(), "openclaw.json");
|
|
10034
10116
|
}
|
|
10035
10117
|
function readOpenclawConfig(configPath) {
|
|
10036
|
-
if (!
|
|
10037
|
-
const raw =
|
|
10118
|
+
if (!fs21.existsSync(configPath)) return {};
|
|
10119
|
+
const raw = fs21.readFileSync(configPath, "utf-8");
|
|
10038
10120
|
let parsed;
|
|
10039
10121
|
try {
|
|
10040
10122
|
parsed = JSON.parse(raw);
|
|
@@ -10136,9 +10218,9 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
|
|
|
10136
10218
|
return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
|
|
10137
10219
|
}
|
|
10138
10220
|
function backupPathIfPresent(sourcePath, backupPath) {
|
|
10139
|
-
if (!
|
|
10140
|
-
|
|
10141
|
-
|
|
10221
|
+
if (!fs21.existsSync(sourcePath)) return false;
|
|
10222
|
+
fs21.mkdirSync(path18.dirname(backupPath), { recursive: true });
|
|
10223
|
+
fs21.cpSync(sourcePath, backupPath, { recursive: true });
|
|
10142
10224
|
return true;
|
|
10143
10225
|
}
|
|
10144
10226
|
function restartOpenclawGateway() {
|
|
@@ -10157,7 +10239,7 @@ function restartOpenclawGateway() {
|
|
|
10157
10239
|
}
|
|
10158
10240
|
function cmdInit() {
|
|
10159
10241
|
const configPath = path18.join(process.cwd(), "remnic.config.json");
|
|
10160
|
-
if (
|
|
10242
|
+
if (fs21.existsSync(configPath)) {
|
|
10161
10243
|
console.log(`Config already exists: ${configPath}`);
|
|
10162
10244
|
return;
|
|
10163
10245
|
}
|
|
@@ -10173,7 +10255,7 @@ function cmdInit() {
|
|
|
10173
10255
|
authToken: "${REMNIC_AUTH_TOKEN}"
|
|
10174
10256
|
}
|
|
10175
10257
|
};
|
|
10176
|
-
|
|
10258
|
+
fs21.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
|
|
10177
10259
|
console.log(`Created ${configPath}`);
|
|
10178
10260
|
console.log("\nSet these environment variables:");
|
|
10179
10261
|
console.log(" export OPENAI_API_KEY=sk-...");
|
|
@@ -10595,10 +10677,10 @@ async function cmdQuery(queryText, json, explain) {
|
|
|
10595
10677
|
}
|
|
10596
10678
|
initLogger5();
|
|
10597
10679
|
const configPath = resolveConfigPath();
|
|
10598
|
-
const raw =
|
|
10599
|
-
const remnicCfg =
|
|
10600
|
-
const config =
|
|
10601
|
-
const orchestrator = new
|
|
10680
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
10681
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
10682
|
+
const config = parseConfig12(remnicCfg);
|
|
10683
|
+
const orchestrator = new Orchestrator7(config);
|
|
10602
10684
|
await orchestrator.initialize();
|
|
10603
10685
|
const service = new EngramAccessService2(orchestrator);
|
|
10604
10686
|
const recallRequest = buildQueryRecallRequest(queryText);
|
|
@@ -10775,10 +10857,10 @@ async function cmdXray(rest) {
|
|
|
10775
10857
|
}
|
|
10776
10858
|
initLogger5();
|
|
10777
10859
|
const configPath = resolveConfigPath();
|
|
10778
|
-
const raw =
|
|
10779
|
-
const remnicCfg =
|
|
10780
|
-
const config =
|
|
10781
|
-
const orchestrator = new
|
|
10860
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
10861
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
10862
|
+
const config = parseConfig12(remnicCfg);
|
|
10863
|
+
const orchestrator = new Orchestrator7(config);
|
|
10782
10864
|
await orchestrator.initialize();
|
|
10783
10865
|
await orchestrator.deferredReady;
|
|
10784
10866
|
const service = new EngramAccessService2(orchestrator);
|
|
@@ -10808,8 +10890,8 @@ async function runWhoKnowsCommand(rest, io) {
|
|
|
10808
10890
|
async function withLocalService(fn) {
|
|
10809
10891
|
initLogger5();
|
|
10810
10892
|
const configPath = resolveConfigPath();
|
|
10811
|
-
const raw =
|
|
10812
|
-
const orchestrator = new
|
|
10893
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
10894
|
+
const orchestrator = new Orchestrator7(parseConfig12(resolveRemnicConfigRecord11(raw)));
|
|
10813
10895
|
await orchestrator.initialize();
|
|
10814
10896
|
await orchestrator.deferredReady;
|
|
10815
10897
|
const service = new EngramAccessService2(orchestrator);
|
|
@@ -10841,9 +10923,9 @@ async function cmdPromotionCandidates(rest) {
|
|
|
10841
10923
|
async function cmdVersions(rest) {
|
|
10842
10924
|
initLogger5();
|
|
10843
10925
|
const configPath = resolveConfigPath();
|
|
10844
|
-
const raw =
|
|
10845
|
-
const remnicCfg =
|
|
10846
|
-
const config =
|
|
10926
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
10927
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
10928
|
+
const config = parseConfig12(remnicCfg);
|
|
10847
10929
|
if (!config.versioningEnabled) {
|
|
10848
10930
|
console.error("Page versioning is disabled (versioningEnabled = false).");
|
|
10849
10931
|
process.exit(1);
|
|
@@ -10957,9 +11039,9 @@ Options:
|
|
|
10957
11039
|
async function cmdEnrich(rest) {
|
|
10958
11040
|
initLogger5();
|
|
10959
11041
|
const configPath = resolveConfigPath();
|
|
10960
|
-
const raw =
|
|
10961
|
-
const remnicCfg =
|
|
10962
|
-
const config =
|
|
11042
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
11043
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
11044
|
+
const config = parseConfig12(remnicCfg);
|
|
10963
11045
|
const subcommand = rest[0];
|
|
10964
11046
|
if (subcommand === "audit") {
|
|
10965
11047
|
const memoryDir2 = expandTilde(config.memoryDir);
|
|
@@ -10987,7 +11069,7 @@ async function cmdEnrich(rest) {
|
|
|
10987
11069
|
pipelineConfig2.providers = [
|
|
10988
11070
|
{ id: "web-search", enabled: true, costTier: "cheap" }
|
|
10989
11071
|
];
|
|
10990
|
-
const orchestrator2 = new
|
|
11072
|
+
const orchestrator2 = new Orchestrator7(config);
|
|
10991
11073
|
await orchestrator2.initialize();
|
|
10992
11074
|
await orchestrator2.deferredReady;
|
|
10993
11075
|
const searchBackend2 = orchestrator2.qmd;
|
|
@@ -11023,7 +11105,7 @@ Registered providers:`);
|
|
|
11023
11105
|
console.error("Usage: remnic enrich <entity-name> | --all | --dry-run | audit | providers");
|
|
11024
11106
|
process.exit(1);
|
|
11025
11107
|
}
|
|
11026
|
-
const orchestrator = new
|
|
11108
|
+
const orchestrator = new Orchestrator7(config);
|
|
11027
11109
|
await orchestrator.initialize();
|
|
11028
11110
|
await orchestrator.deferredReady;
|
|
11029
11111
|
const storage = await orchestrator.getStorage(config.defaultNamespace);
|
|
@@ -11151,9 +11233,9 @@ Registered providers:`);
|
|
|
11151
11233
|
async function cmdExtensions(action, rest) {
|
|
11152
11234
|
initLogger5();
|
|
11153
11235
|
const configPath = resolveConfigPath();
|
|
11154
|
-
const raw =
|
|
11155
|
-
const remnicCfg =
|
|
11156
|
-
const config =
|
|
11236
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
11237
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
11238
|
+
const config = parseConfig12(remnicCfg);
|
|
11157
11239
|
const root = resolveExtensionsRoot(config);
|
|
11158
11240
|
const noopLog = { warn: () => {
|
|
11159
11241
|
}, debug: () => {
|
|
@@ -11202,7 +11284,7 @@ Root: ${root}`);
|
|
|
11202
11284
|
const extensions = await discoverMemoryExtensions(root, warnLog);
|
|
11203
11285
|
let entries = [];
|
|
11204
11286
|
try {
|
|
11205
|
-
entries =
|
|
11287
|
+
entries = fs21.readdirSync(root);
|
|
11206
11288
|
} catch {
|
|
11207
11289
|
console.log(`Extensions root does not exist: ${root}`);
|
|
11208
11290
|
process.exitCode = 0;
|
|
@@ -11213,7 +11295,7 @@ Root: ${root}`);
|
|
|
11213
11295
|
for (const entry of entries) {
|
|
11214
11296
|
const entryPath = path18.join(root, entry);
|
|
11215
11297
|
try {
|
|
11216
|
-
if (!
|
|
11298
|
+
if (!fs21.statSync(entryPath).isDirectory()) continue;
|
|
11217
11299
|
} catch {
|
|
11218
11300
|
continue;
|
|
11219
11301
|
}
|
|
@@ -11245,9 +11327,9 @@ Root: ${root}`);
|
|
|
11245
11327
|
async function cmdBriefing(rest) {
|
|
11246
11328
|
initLogger5();
|
|
11247
11329
|
const configPath = resolveConfigPath();
|
|
11248
|
-
const raw =
|
|
11249
|
-
const remnicCfg =
|
|
11250
|
-
const config =
|
|
11330
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
11331
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
11332
|
+
const config = parseConfig12(remnicCfg);
|
|
11251
11333
|
if (!config.briefing.enabled) {
|
|
11252
11334
|
console.error("Briefing is disabled in config (briefing.enabled = false).");
|
|
11253
11335
|
process.exit(1);
|
|
@@ -11300,7 +11382,7 @@ async function cmdBriefing(rest) {
|
|
|
11300
11382
|
process.exit(1);
|
|
11301
11383
|
}
|
|
11302
11384
|
const format = effectiveFormatFlag === "json" ? "json" : effectiveFormatFlag === "markdown" ? "markdown" : config.briefing.defaultFormat;
|
|
11303
|
-
const orchestrator = new
|
|
11385
|
+
const orchestrator = new Orchestrator7(config);
|
|
11304
11386
|
await orchestrator.initialize();
|
|
11305
11387
|
const storage = await orchestrator.getStorage(config.defaultNamespace);
|
|
11306
11388
|
const calendarSource = config.briefing.calendarSource ? new FileCalendarSource(config.briefing.calendarSource) : void 0;
|
|
@@ -11325,10 +11407,10 @@ async function cmdBriefing(rest) {
|
|
|
11325
11407
|
if (save) {
|
|
11326
11408
|
try {
|
|
11327
11409
|
const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
|
|
11328
|
-
|
|
11410
|
+
fs21.mkdirSync(saveDir, { recursive: true });
|
|
11329
11411
|
const filename = briefingFilename(new Date(result.window.to), format);
|
|
11330
11412
|
const filePath = path18.join(saveDir, filename);
|
|
11331
|
-
|
|
11413
|
+
fs21.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
|
|
11332
11414
|
console.error(`Saved briefing: ${filePath}`);
|
|
11333
11415
|
} catch (err) {
|
|
11334
11416
|
console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -11346,7 +11428,7 @@ async function cmdDoctor() {
|
|
|
11346
11428
|
detail: `${nodeVersion} (requires >= 22.12.0)`
|
|
11347
11429
|
});
|
|
11348
11430
|
const configPath = resolveConfigPath();
|
|
11349
|
-
const configExists =
|
|
11431
|
+
const configExists = fs21.existsSync(configPath);
|
|
11350
11432
|
checks.push({ name: "Config file", ok: configExists, detail: configPath });
|
|
11351
11433
|
let standaloneConfig;
|
|
11352
11434
|
let standaloneConfigError;
|
|
@@ -11354,11 +11436,11 @@ async function cmdDoctor() {
|
|
|
11354
11436
|
let configuredNs = { invalid: false };
|
|
11355
11437
|
if (configExists) {
|
|
11356
11438
|
try {
|
|
11357
|
-
const raw = JSON.parse(
|
|
11358
|
-
const remnicCfg =
|
|
11439
|
+
const raw = JSON.parse(fs21.readFileSync(configPath, "utf8"));
|
|
11440
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
11359
11441
|
standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
|
|
11360
11442
|
configuredNs = readConfiguredNamespace(remnicCfg);
|
|
11361
|
-
standaloneConfig =
|
|
11443
|
+
standaloneConfig = parseConfig12(remnicCfg);
|
|
11362
11444
|
} catch (err) {
|
|
11363
11445
|
standaloneConfigError = err instanceof Error ? err.message : String(err);
|
|
11364
11446
|
}
|
|
@@ -11367,10 +11449,10 @@ async function cmdDoctor() {
|
|
|
11367
11449
|
try {
|
|
11368
11450
|
memoryDir = resolveMemoryDir();
|
|
11369
11451
|
} catch {
|
|
11370
|
-
memoryDir =
|
|
11452
|
+
memoryDir = parseConfig12({}).memoryDir;
|
|
11371
11453
|
}
|
|
11372
11454
|
try {
|
|
11373
|
-
|
|
11455
|
+
fs21.mkdirSync(memoryDir, { recursive: true });
|
|
11374
11456
|
checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
|
|
11375
11457
|
} catch {
|
|
11376
11458
|
checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
|
|
@@ -11399,7 +11481,7 @@ async function cmdDoctor() {
|
|
|
11399
11481
|
});
|
|
11400
11482
|
if (nsPolicyCheck) checks.push(nsPolicyCheck);
|
|
11401
11483
|
const openclawConfigPath = resolveOpenclawConfigPath();
|
|
11402
|
-
const openclawConfigExists =
|
|
11484
|
+
const openclawConfigExists = fs21.existsSync(openclawConfigPath);
|
|
11403
11485
|
let openclawConfig = {};
|
|
11404
11486
|
let openclawConfigValid = false;
|
|
11405
11487
|
let openclawPluginModeConfigured = false;
|
|
@@ -11407,7 +11489,7 @@ async function cmdDoctor() {
|
|
|
11407
11489
|
let activeOpenclawEntryConfig = null;
|
|
11408
11490
|
if (openclawConfigExists) {
|
|
11409
11491
|
try {
|
|
11410
|
-
const parsed = JSON.parse(
|
|
11492
|
+
const parsed = JSON.parse(fs21.readFileSync(openclawConfigPath, "utf-8"));
|
|
11411
11493
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
11412
11494
|
openclawConfig = parsed;
|
|
11413
11495
|
openclawConfigValid = true;
|
|
@@ -11487,9 +11569,9 @@ async function cmdDoctor() {
|
|
|
11487
11569
|
let memDirOk = false;
|
|
11488
11570
|
let memDirDetail = `${resolvedMemDir} (not found)`;
|
|
11489
11571
|
let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
|
|
11490
|
-
if (
|
|
11572
|
+
if (fs21.existsSync(resolvedMemDir)) {
|
|
11491
11573
|
try {
|
|
11492
|
-
const stat2 =
|
|
11574
|
+
const stat2 = fs21.statSync(resolvedMemDir);
|
|
11493
11575
|
if (stat2.isDirectory()) {
|
|
11494
11576
|
memDirOk = true;
|
|
11495
11577
|
memDirDetail = resolvedMemDir;
|
|
@@ -11644,12 +11726,12 @@ async function cmdDoctor() {
|
|
|
11644
11726
|
}
|
|
11645
11727
|
function cmdConfig() {
|
|
11646
11728
|
const configPath = resolveConfigPath();
|
|
11647
|
-
if (!
|
|
11729
|
+
if (!fs21.existsSync(configPath)) {
|
|
11648
11730
|
console.log("No config file found. Run `remnic init` to create one.");
|
|
11649
11731
|
return;
|
|
11650
11732
|
}
|
|
11651
11733
|
console.log(`Config: ${configPath}`);
|
|
11652
|
-
const rawConfig =
|
|
11734
|
+
const rawConfig = fs21.readFileSync(configPath, "utf8");
|
|
11653
11735
|
const redacted = rawConfig.replace(
|
|
11654
11736
|
/("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
|
|
11655
11737
|
"$1[REDACTED]$3"
|
|
@@ -11757,9 +11839,9 @@ async function cmdReview(action, rest) {
|
|
|
11757
11839
|
const configPath = resolveConfigPath();
|
|
11758
11840
|
let tombstonesConfig = null;
|
|
11759
11841
|
try {
|
|
11760
|
-
const rawCfg =
|
|
11761
|
-
const remnicCfg =
|
|
11762
|
-
const config =
|
|
11842
|
+
const rawCfg = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
11843
|
+
const remnicCfg = resolveRemnicConfigRecord11(rawCfg);
|
|
11844
|
+
const config = parseConfig12(remnicCfg);
|
|
11763
11845
|
tombstonesConfig = {
|
|
11764
11846
|
enabled: config.tombstonesEnabled,
|
|
11765
11847
|
semanticMatch: config.tombstonesSemanticMatch,
|
|
@@ -12501,7 +12583,7 @@ async function pushOfflineFileContent(args) {
|
|
|
12501
12583
|
}
|
|
12502
12584
|
async function pushOfflineFileContentFromChunkReader(args) {
|
|
12503
12585
|
const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
|
|
12504
|
-
const stat2 =
|
|
12586
|
+
const stat2 = fs21.statSync(filePath);
|
|
12505
12587
|
if (stat2.mtimeMs !== args.file.mtimeMs) {
|
|
12506
12588
|
throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
|
|
12507
12589
|
}
|
|
@@ -12992,7 +13074,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
|
|
|
12992
13074
|
return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
12993
13075
|
}
|
|
12994
13076
|
async function runOfflineSyncOnce(options) {
|
|
12995
|
-
|
|
13077
|
+
fs21.mkdirSync(options.memoryDir, { recursive: true });
|
|
12996
13078
|
let activeStatePath = options.statePath;
|
|
12997
13079
|
let priorState = await readOfflineSyncState(activeStatePath);
|
|
12998
13080
|
let syncNamespace = options.namespace ?? priorState?.namespace;
|
|
@@ -13625,7 +13707,7 @@ Environment fallbacks:
|
|
|
13625
13707
|
const configPath = resolveConfigPath();
|
|
13626
13708
|
let config;
|
|
13627
13709
|
try {
|
|
13628
|
-
const rawConfig =
|
|
13710
|
+
const rawConfig = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
13629
13711
|
config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
|
|
13630
13712
|
} catch {
|
|
13631
13713
|
throw new Error(
|
|
@@ -13640,7 +13722,7 @@ Environment fallbacks:
|
|
|
13640
13722
|
const statePath = statePathExplicit ? path18.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
|
|
13641
13723
|
if (action === "prepare") {
|
|
13642
13724
|
if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
|
|
13643
|
-
|
|
13725
|
+
fs21.mkdirSync(memoryDir, { recursive: true });
|
|
13644
13726
|
const remoteSnapshot = await fetchOfflineSnapshot({
|
|
13645
13727
|
remoteUrl,
|
|
13646
13728
|
token,
|
|
@@ -13739,7 +13821,7 @@ Environment fallbacks:
|
|
|
13739
13821
|
return;
|
|
13740
13822
|
}
|
|
13741
13823
|
if (action === "status") {
|
|
13742
|
-
|
|
13824
|
+
fs21.mkdirSync(memoryDir, { recursive: true });
|
|
13743
13825
|
const state = statePath ? await readOfflineSyncState(statePath) : null;
|
|
13744
13826
|
if (state && remoteUrl && statePath) {
|
|
13745
13827
|
assertOfflineStateMatches({
|
|
@@ -13877,7 +13959,7 @@ function cmdDedup(json) {
|
|
|
13877
13959
|
function readInstalledConnectorConfig(configPath, fallback) {
|
|
13878
13960
|
if (!configPath) return fallback;
|
|
13879
13961
|
try {
|
|
13880
|
-
const parsed = JSON.parse(
|
|
13962
|
+
const parsed = JSON.parse(fs21.readFileSync(configPath, "utf8"));
|
|
13881
13963
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
|
|
13882
13964
|
const { token: _token, ...config } = parsed;
|
|
13883
13965
|
return config;
|
|
@@ -14055,7 +14137,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14055
14137
|
const pub = factory();
|
|
14056
14138
|
const available = await pub.isHostAvailable();
|
|
14057
14139
|
const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
|
|
14058
|
-
const extensionExists = available && extRoot ?
|
|
14140
|
+
const extensionExists = available && extRoot ? fs21.existsSync(extRoot) : false;
|
|
14059
14141
|
publisherChecks.push({
|
|
14060
14142
|
name: `Publisher: ${targetHostId}`,
|
|
14061
14143
|
ok: !available || extensionExists,
|
|
@@ -14129,7 +14211,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14129
14211
|
let connectorsCfg;
|
|
14130
14212
|
const configPath = resolveConfigPath();
|
|
14131
14213
|
try {
|
|
14132
|
-
const raw =
|
|
14214
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
14133
14215
|
connectorsCfg = parseConfigQuietly(raw).connectors;
|
|
14134
14216
|
} catch {
|
|
14135
14217
|
process.stderr.write(
|
|
@@ -14205,10 +14287,10 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14205
14287
|
}
|
|
14206
14288
|
initLogger5();
|
|
14207
14289
|
const configPath = resolveConfigPath();
|
|
14208
|
-
const raw =
|
|
14209
|
-
const remnicCfg =
|
|
14210
|
-
const config =
|
|
14211
|
-
const orchestrator = new
|
|
14290
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
14291
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
14292
|
+
const config = parseConfig12(remnicCfg);
|
|
14293
|
+
const orchestrator = new Orchestrator7(config);
|
|
14212
14294
|
try {
|
|
14213
14295
|
await orchestrator.initialize();
|
|
14214
14296
|
await orchestrator.deferredReady;
|
|
@@ -14330,9 +14412,9 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
|
|
|
14330
14412
|
console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
|
|
14331
14413
|
process.exit(1);
|
|
14332
14414
|
}
|
|
14333
|
-
const rawConfig =
|
|
14334
|
-
const pluginConfig =
|
|
14335
|
-
const config =
|
|
14415
|
+
const rawConfig = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
14416
|
+
const pluginConfig = resolveRemnicConfigRecord11(rawConfig);
|
|
14417
|
+
const config = parseConfig12(pluginConfig);
|
|
14336
14418
|
if (subAction === "generate") {
|
|
14337
14419
|
let outputDir;
|
|
14338
14420
|
try {
|
|
@@ -14352,13 +14434,13 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
|
|
|
14352
14434
|
} else if (subAction === "validate") {
|
|
14353
14435
|
const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path18.join(process.cwd(), "marketplace.json");
|
|
14354
14436
|
const resolved = path18.resolve(targetPath);
|
|
14355
|
-
if (!
|
|
14437
|
+
if (!fs21.existsSync(resolved)) {
|
|
14356
14438
|
console.error(`File not found: ${resolved}`);
|
|
14357
14439
|
process.exit(1);
|
|
14358
14440
|
}
|
|
14359
14441
|
let parsed;
|
|
14360
14442
|
try {
|
|
14361
|
-
parsed = JSON.parse(
|
|
14443
|
+
parsed = JSON.parse(fs21.readFileSync(resolved, "utf8"));
|
|
14362
14444
|
} catch {
|
|
14363
14445
|
console.error(`Invalid JSON in ${resolved}`);
|
|
14364
14446
|
process.exit(1);
|
|
@@ -14561,10 +14643,10 @@ async function cmdSpace(action, rest, json) {
|
|
|
14561
14643
|
async function cmdLegacyBenchmark(action, rest, json) {
|
|
14562
14644
|
initLogger5();
|
|
14563
14645
|
const configPath = resolveConfigPath();
|
|
14564
|
-
const raw =
|
|
14565
|
-
const remnicCfg =
|
|
14566
|
-
const config =
|
|
14567
|
-
const orchestrator = new
|
|
14646
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
14647
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
14648
|
+
const config = parseConfig12(remnicCfg);
|
|
14649
|
+
const orchestrator = new Orchestrator7(config);
|
|
14568
14650
|
const service = new EngramAccessService2(orchestrator);
|
|
14569
14651
|
const { runBenchSuite, loadBaseline, checkRegression } = await loadBenchModule();
|
|
14570
14652
|
const benchConfig = {
|
|
@@ -14966,7 +15048,7 @@ function readPid() {
|
|
|
14966
15048
|
function inferPort() {
|
|
14967
15049
|
try {
|
|
14968
15050
|
const configPath = resolveConfigPath();
|
|
14969
|
-
const raw = JSON.parse(
|
|
15051
|
+
const raw = JSON.parse(fs21.readFileSync(configPath, "utf8"));
|
|
14970
15052
|
return raw.server?.port ?? 4318;
|
|
14971
15053
|
} catch {
|
|
14972
15054
|
return 4318;
|
|
@@ -15061,13 +15143,13 @@ function daemonInstall() {
|
|
|
15061
15143
|
process.exit(1);
|
|
15062
15144
|
}
|
|
15063
15145
|
const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
|
|
15064
|
-
|
|
15146
|
+
fs21.mkdirSync(LOGS_DIR, { recursive: true });
|
|
15065
15147
|
if (isMacOS()) {
|
|
15066
15148
|
const templatePath = path18.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
|
|
15067
|
-
const template =
|
|
15149
|
+
const template = fs21.readFileSync(templatePath, "utf8");
|
|
15068
15150
|
const plist = renderTemplate(template, vars);
|
|
15069
|
-
|
|
15070
|
-
|
|
15151
|
+
fs21.mkdirSync(path18.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
|
|
15152
|
+
fs21.writeFileSync(LAUNCHD_PLIST_PATH, plist);
|
|
15071
15153
|
try {
|
|
15072
15154
|
launchdLoadPlist(LAUNCHD_PLIST_PATH);
|
|
15073
15155
|
} catch (err) {
|
|
@@ -15084,10 +15166,10 @@ function daemonInstall() {
|
|
|
15084
15166
|
console.log(` Logs: ${LOGS_DIR}/daemon.log`);
|
|
15085
15167
|
} else if (isLinux()) {
|
|
15086
15168
|
const templatePath = path18.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
|
|
15087
|
-
const template =
|
|
15169
|
+
const template = fs21.readFileSync(templatePath, "utf8");
|
|
15088
15170
|
const unit = renderTemplate(template, vars);
|
|
15089
|
-
|
|
15090
|
-
|
|
15171
|
+
fs21.mkdirSync(path18.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
|
|
15172
|
+
fs21.writeFileSync(SYSTEMD_UNIT_PATH, unit);
|
|
15091
15173
|
try {
|
|
15092
15174
|
childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
15093
15175
|
} catch (err) {
|
|
@@ -15123,7 +15205,7 @@ function daemonUninstall() {
|
|
|
15123
15205
|
} catch {
|
|
15124
15206
|
}
|
|
15125
15207
|
try {
|
|
15126
|
-
|
|
15208
|
+
fs21.unlinkSync(plistPath);
|
|
15127
15209
|
removed = true;
|
|
15128
15210
|
console.log(`Removed launchd service: ${plistPath}`);
|
|
15129
15211
|
} catch {
|
|
@@ -15143,7 +15225,7 @@ function daemonUninstall() {
|
|
|
15143
15225
|
let removed = false;
|
|
15144
15226
|
for (const unitPath of SYSTEMD_UNIT_PATHS) {
|
|
15145
15227
|
try {
|
|
15146
|
-
|
|
15228
|
+
fs21.unlinkSync(unitPath);
|
|
15147
15229
|
removed = true;
|
|
15148
15230
|
console.log(`Removed systemd service: ${unitPath}`);
|
|
15149
15231
|
} catch {
|
|
@@ -15210,13 +15292,13 @@ async function daemonStatus() {
|
|
|
15210
15292
|
console.log(` Port: ${port}`);
|
|
15211
15293
|
console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
|
|
15212
15294
|
console.log(` Platform: ${process.platform}`);
|
|
15213
|
-
console.log(` PID file: ${
|
|
15214
|
-
console.log(` Log file: ${
|
|
15295
|
+
console.log(` PID file: ${fs21.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
|
|
15296
|
+
console.log(` Log file: ${fs21.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
|
|
15215
15297
|
try {
|
|
15216
15298
|
const configPath = resolveConfigPath();
|
|
15217
|
-
const raw =
|
|
15218
|
-
const remnicCfg =
|
|
15219
|
-
const config =
|
|
15299
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
15300
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
15301
|
+
const config = parseConfig12(remnicCfg);
|
|
15220
15302
|
const extRoot = resolveExtensionsRoot(config);
|
|
15221
15303
|
const noopLog = { warn: () => {
|
|
15222
15304
|
}, debug: () => {
|
|
@@ -15255,9 +15337,9 @@ function daemonStart() {
|
|
|
15255
15337
|
return;
|
|
15256
15338
|
}
|
|
15257
15339
|
}
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
const logStream =
|
|
15340
|
+
fs21.mkdirSync(PID_DIR, { recursive: true });
|
|
15341
|
+
fs21.mkdirSync(LOGS_DIR, { recursive: true });
|
|
15342
|
+
const logStream = fs21.openSync(LOG_FILE, "a");
|
|
15261
15343
|
const serverBin = resolveServerBin();
|
|
15262
15344
|
const isSource = serverBin.endsWith(".ts");
|
|
15263
15345
|
let cmd;
|
|
@@ -15279,7 +15361,7 @@ function daemonStart() {
|
|
|
15279
15361
|
}
|
|
15280
15362
|
});
|
|
15281
15363
|
child.unref();
|
|
15282
|
-
|
|
15364
|
+
fs21.writeFileSync(PID_FILE, String(child.pid));
|
|
15283
15365
|
console.log(`Started remnic server (pid ${child.pid})`);
|
|
15284
15366
|
console.log(` Log: ${LOG_FILE}`);
|
|
15285
15367
|
}
|
|
@@ -15313,11 +15395,11 @@ function daemonStop() {
|
|
|
15313
15395
|
console.log("Process not found (cleaning up PID file)");
|
|
15314
15396
|
}
|
|
15315
15397
|
try {
|
|
15316
|
-
|
|
15398
|
+
fs21.unlinkSync(PID_FILE);
|
|
15317
15399
|
} catch {
|
|
15318
15400
|
}
|
|
15319
15401
|
try {
|
|
15320
|
-
|
|
15402
|
+
fs21.unlinkSync(LEGACY_PID_FILE);
|
|
15321
15403
|
} catch {
|
|
15322
15404
|
}
|
|
15323
15405
|
}
|
|
@@ -15445,9 +15527,9 @@ async function promptYesNo(question, defaultYes = true) {
|
|
|
15445
15527
|
async function cmdBinary(rest) {
|
|
15446
15528
|
initLogger5();
|
|
15447
15529
|
const configPath = resolveConfigPath();
|
|
15448
|
-
const raw =
|
|
15449
|
-
const remnicCfg =
|
|
15450
|
-
const config =
|
|
15530
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
15531
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
15532
|
+
const config = parseConfig12(remnicCfg);
|
|
15451
15533
|
const memoryDir = resolveMemoryDir();
|
|
15452
15534
|
const blConfig = {
|
|
15453
15535
|
enabled: config.binaryLifecycleEnabled,
|
|
@@ -15636,7 +15718,7 @@ async function cmdOpenclawInstall(opts) {
|
|
|
15636
15718
|
} else if (slotIsActiveLegacy) {
|
|
15637
15719
|
changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
|
|
15638
15720
|
}
|
|
15639
|
-
if (!
|
|
15721
|
+
if (!fs21.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
|
|
15640
15722
|
if (hasLegacy && migrateLegacy) {
|
|
15641
15723
|
changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
|
|
15642
15724
|
}
|
|
@@ -15656,8 +15738,8 @@ async function cmdOpenclawInstall(opts) {
|
|
|
15656
15738
|
Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
|
|
15657
15739
|
return;
|
|
15658
15740
|
}
|
|
15659
|
-
if (
|
|
15660
|
-
const st =
|
|
15741
|
+
if (fs21.existsSync(memoryDir)) {
|
|
15742
|
+
const st = fs21.statSync(memoryDir);
|
|
15661
15743
|
if (!st.isDirectory()) {
|
|
15662
15744
|
throw new Error(
|
|
15663
15745
|
`Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
|
|
@@ -15665,12 +15747,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
|
|
|
15665
15747
|
);
|
|
15666
15748
|
}
|
|
15667
15749
|
} else {
|
|
15668
|
-
|
|
15750
|
+
fs21.mkdirSync(memoryDir, { recursive: true });
|
|
15669
15751
|
console.log(`Created memory directory: ${memoryDir}`);
|
|
15670
15752
|
}
|
|
15671
15753
|
const configDir = path18.dirname(configPath);
|
|
15672
|
-
if (!
|
|
15673
|
-
|
|
15754
|
+
if (!fs21.existsSync(configDir)) {
|
|
15755
|
+
fs21.mkdirSync(configDir, { recursive: true });
|
|
15674
15756
|
}
|
|
15675
15757
|
atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
|
|
15676
15758
|
console.log("\nDone! Summary of changes:");
|
|
@@ -15699,7 +15781,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15699
15781
|
const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
|
|
15700
15782
|
const fallbackMemoryDir = path18.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
15701
15783
|
const packageSpec = buildOpenclawManagedUpgradePackageSpec(opts.version);
|
|
15702
|
-
const configExistedBefore =
|
|
15784
|
+
const configExistedBefore = fs21.existsSync(configPath);
|
|
15703
15785
|
const existingConfig = readOpenclawConfig(configPath);
|
|
15704
15786
|
const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
|
|
15705
15787
|
const preservedMemoryDir = opts.memoryDir ? path18.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
|
|
@@ -15924,15 +16006,15 @@ async function cmdOpenclawMigrateEngram(opts) {
|
|
|
15924
16006
|
}
|
|
15925
16007
|
function createOpenclawUpgradeBackupDir() {
|
|
15926
16008
|
const backupsRoot = path18.join(resolveOpenclawStateDir(), "backups");
|
|
15927
|
-
|
|
15928
|
-
return
|
|
16009
|
+
fs21.mkdirSync(backupsRoot, { recursive: true });
|
|
16010
|
+
return fs21.mkdtempSync(path18.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
|
|
15929
16011
|
}
|
|
15930
16012
|
async function cmdTaxonomy(rest) {
|
|
15931
16013
|
initLogger5();
|
|
15932
16014
|
const configPath = resolveConfigPath();
|
|
15933
|
-
const raw =
|
|
15934
|
-
const remnicCfg =
|
|
15935
|
-
const config =
|
|
16015
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
16016
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
16017
|
+
const config = parseConfig12(remnicCfg);
|
|
15936
16018
|
if (!config.taxonomyEnabled) {
|
|
15937
16019
|
console.error(
|
|
15938
16020
|
"Taxonomy is disabled in config (taxonomyEnabled = false). Enable it to use taxonomy commands."
|
|
@@ -15968,8 +16050,8 @@ async function cmdTaxonomy(rest) {
|
|
|
15968
16050
|
console.log(doc);
|
|
15969
16051
|
if (config.taxonomyAutoGenResolver) {
|
|
15970
16052
|
const resolverPath = path18.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
15971
|
-
|
|
15972
|
-
|
|
16053
|
+
fs21.mkdirSync(path18.dirname(resolverPath), { recursive: true });
|
|
16054
|
+
fs21.writeFileSync(resolverPath, doc);
|
|
15973
16055
|
console.error(`Written: ${resolverPath}`);
|
|
15974
16056
|
}
|
|
15975
16057
|
break;
|
|
@@ -16015,7 +16097,7 @@ async function cmdTaxonomy(rest) {
|
|
|
16015
16097
|
if (config.taxonomyAutoGenResolver) {
|
|
16016
16098
|
const doc = generateResolverDocument(taxonomy);
|
|
16017
16099
|
const resolverPath = path18.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16018
|
-
|
|
16100
|
+
fs21.writeFileSync(resolverPath, doc);
|
|
16019
16101
|
console.error(`Regenerated: ${resolverPath}`);
|
|
16020
16102
|
}
|
|
16021
16103
|
break;
|
|
@@ -16046,7 +16128,7 @@ async function cmdTaxonomy(rest) {
|
|
|
16046
16128
|
if (config.taxonomyAutoGenResolver) {
|
|
16047
16129
|
const doc = generateResolverDocument(taxonomy);
|
|
16048
16130
|
const resolverPath = path18.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16049
|
-
|
|
16131
|
+
fs21.writeFileSync(resolverPath, doc);
|
|
16050
16132
|
console.error(`Regenerated: ${resolverPath}`);
|
|
16051
16133
|
}
|
|
16052
16134
|
break;
|
|
@@ -16237,12 +16319,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
|
|
|
16237
16319
|
`Unknown training-export format "${args.format}". ${validList}`
|
|
16238
16320
|
);
|
|
16239
16321
|
}
|
|
16240
|
-
if (!
|
|
16322
|
+
if (!fs21.existsSync(args.memoryDir)) {
|
|
16241
16323
|
throw new Error(
|
|
16242
16324
|
`--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
|
|
16243
16325
|
);
|
|
16244
16326
|
}
|
|
16245
|
-
if (!
|
|
16327
|
+
if (!fs21.statSync(args.memoryDir).isDirectory()) {
|
|
16246
16328
|
throw new Error(
|
|
16247
16329
|
`--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
|
|
16248
16330
|
);
|
|
@@ -16328,10 +16410,10 @@ async function runTrainingExport(args, stdout = process.stdout) {
|
|
|
16328
16410
|
}
|
|
16329
16411
|
const formatted = adapter.formatRecords(records);
|
|
16330
16412
|
const outDir = path18.dirname(args.output);
|
|
16331
|
-
|
|
16413
|
+
fs21.mkdirSync(outDir, { recursive: true });
|
|
16332
16414
|
const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
|
|
16333
|
-
|
|
16334
|
-
|
|
16415
|
+
fs21.writeFileSync(tmpPath, formatted, "utf-8");
|
|
16416
|
+
fs21.renameSync(tmpPath, args.output);
|
|
16335
16417
|
stdout.write(
|
|
16336
16418
|
`Exported ${records.length} records to ${args.output} (${adapter.name} format)
|
|
16337
16419
|
`
|
|
@@ -16509,7 +16591,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16509
16591
|
}
|
|
16510
16592
|
}, 500);
|
|
16511
16593
|
};
|
|
16512
|
-
|
|
16594
|
+
fs21.watch(memoryDir, { recursive: true }, (_event, filename) => {
|
|
16513
16595
|
if (filename && filename.startsWith(".")) return;
|
|
16514
16596
|
rebuild();
|
|
16515
16597
|
});
|
|
@@ -16517,12 +16599,12 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16517
16599
|
});
|
|
16518
16600
|
} else if (subAction === "validate") {
|
|
16519
16601
|
const treeDir = outputDir;
|
|
16520
|
-
if (!
|
|
16602
|
+
if (!fs21.existsSync(treeDir)) {
|
|
16521
16603
|
console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
|
|
16522
16604
|
process.exit(1);
|
|
16523
16605
|
}
|
|
16524
16606
|
const indexPath = path18.join(treeDir, "INDEX.md");
|
|
16525
|
-
if (!
|
|
16607
|
+
if (!fs21.existsSync(indexPath)) {
|
|
16526
16608
|
console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
|
|
16527
16609
|
process.exit(1);
|
|
16528
16610
|
}
|
|
@@ -16702,54 +16784,16 @@ Other:
|
|
|
16702
16784
|
break;
|
|
16703
16785
|
}
|
|
16704
16786
|
case "wearables": {
|
|
16705
|
-
|
|
16706
|
-
let wearablesOrchestrator;
|
|
16707
|
-
try {
|
|
16708
|
-
let wearablesService;
|
|
16709
|
-
try {
|
|
16710
|
-
const configPath = resolveConfigPath();
|
|
16711
|
-
const raw = fs19.existsSync(configPath) ? JSON.parse(fs19.readFileSync(configPath, "utf8")) : {};
|
|
16712
|
-
const remnicCfg = resolveRemnicConfigRecord9(raw);
|
|
16713
|
-
const config = parseConfig10(remnicCfg);
|
|
16714
|
-
wearablesOrchestrator = new Orchestrator6(config);
|
|
16715
|
-
await wearablesOrchestrator.initialize();
|
|
16716
|
-
await wearablesOrchestrator.deferredReady;
|
|
16717
|
-
wearablesService = wearablesOrchestrator.getWearablesService();
|
|
16718
|
-
} catch {
|
|
16719
|
-
console.error(
|
|
16720
|
-
"wearables: failed to load the Remnic config or start the memory engine \u2014 run `remnic doctor` and check the config file for errors"
|
|
16721
|
-
);
|
|
16722
|
-
process.exitCode = 1;
|
|
16723
|
-
break;
|
|
16724
|
-
}
|
|
16725
|
-
const code = await runWearablesCliCommand(wearablesService, wearablesArgs, {
|
|
16726
|
-
stdout: process.stdout,
|
|
16727
|
-
stderr: process.stderr
|
|
16728
|
-
});
|
|
16729
|
-
if (wearablesArgs[0] === "sync" && code === 0 && wearablesOrchestrator.config.meetings.enabled) {
|
|
16730
|
-
await (await wearablesOrchestrator.getMeetingsService()).flushBuilds();
|
|
16731
|
-
}
|
|
16732
|
-
if (code !== 0) process.exitCode = code;
|
|
16733
|
-
} catch (err) {
|
|
16734
|
-
console.error(err instanceof Error ? err.message : String(err));
|
|
16735
|
-
process.exitCode = 1;
|
|
16736
|
-
} finally {
|
|
16737
|
-
if (wearablesOrchestrator) {
|
|
16738
|
-
const maybeShutdown = wearablesOrchestrator.shutdown;
|
|
16739
|
-
if (typeof maybeShutdown === "function") {
|
|
16740
|
-
try {
|
|
16741
|
-
await maybeShutdown.call(wearablesOrchestrator);
|
|
16742
|
-
} catch {
|
|
16743
|
-
}
|
|
16744
|
-
}
|
|
16745
|
-
}
|
|
16746
|
-
}
|
|
16787
|
+
await runWearablesBinaryCommand(rest);
|
|
16747
16788
|
break;
|
|
16748
16789
|
}
|
|
16749
16790
|
case "meetings": {
|
|
16750
16791
|
await runMeetingsBinaryCommand(rest);
|
|
16751
16792
|
break;
|
|
16752
16793
|
}
|
|
16794
|
+
case "location":
|
|
16795
|
+
await runLocationBinaryCommand(rest);
|
|
16796
|
+
break;
|
|
16753
16797
|
case "okf":
|
|
16754
16798
|
await runOkfBinaryCommand(rest);
|
|
16755
16799
|
break;
|
|
@@ -16766,10 +16810,10 @@ Other:
|
|
|
16766
16810
|
const targetFactory = async () => {
|
|
16767
16811
|
if (!orchestratorSingleton) {
|
|
16768
16812
|
const configPath = resolveConfigPath();
|
|
16769
|
-
const raw =
|
|
16770
|
-
const remnicCfg =
|
|
16771
|
-
const config =
|
|
16772
|
-
orchestratorSingleton = new
|
|
16813
|
+
const raw = fs21.existsSync(configPath) ? JSON.parse(fs21.readFileSync(configPath, "utf8")) : {};
|
|
16814
|
+
const remnicCfg = resolveRemnicConfigRecord11(raw);
|
|
16815
|
+
const config = parseConfig12(remnicCfg);
|
|
16816
|
+
orchestratorSingleton = new Orchestrator7(config);
|
|
16773
16817
|
await orchestratorSingleton.initialize();
|
|
16774
16818
|
await orchestratorSingleton.deferredReady;
|
|
16775
16819
|
}
|
|
@@ -16964,6 +17008,9 @@ Usage:
|
|
|
16964
17008
|
remnic meetings <list|show|build>
|
|
16965
17009
|
Retrospective meetings: list, show, or build a day's meetings.
|
|
16966
17010
|
Run "remnic meetings help" for details.
|
|
17011
|
+
remnic location <status|check|sync|backfill|day>
|
|
17012
|
+
Location day sync from registered providers (e.g. Reitti, issue #2047).
|
|
17013
|
+
Run "remnic location help" for details.
|
|
16967
17014
|
remnic okf <lint|sweep> [--json]
|
|
16968
17015
|
OKF v0.1 conformance: lint reports missing frontmatter/type findings,
|
|
16969
17016
|
sweep backfills missing type values (okf.sweepEnabled).
|