@remnic/cli 9.65.8 → 9.66.0
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 +728 -546
- package/package.json +35 -31
package/dist/index.js
CHANGED
|
@@ -18,20 +18,20 @@ async function persistEnrichmentCandidate(storage, entityName, candidate) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
import
|
|
21
|
+
import fs24 from "fs";
|
|
22
22
|
import os3 from "os";
|
|
23
|
-
import
|
|
23
|
+
import path19 from "path";
|
|
24
24
|
import { createHash as createHash4 } from "crypto";
|
|
25
25
|
import { writeFile as fsWriteFile } from "fs/promises";
|
|
26
26
|
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 parseConfig15,
|
|
31
31
|
isOpenaiApiKeyDisabled,
|
|
32
32
|
resolveEnvVars,
|
|
33
|
-
resolveRemnicConfigRecord as
|
|
34
|
-
Orchestrator as
|
|
33
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord14,
|
|
34
|
+
Orchestrator as Orchestrator10,
|
|
35
35
|
EngramAccessService as EngramAccessService2,
|
|
36
36
|
initLogger as initLogger5,
|
|
37
37
|
onboard,
|
|
@@ -247,7 +247,7 @@ async function runWearablesBinaryCommand(rest) {
|
|
|
247
247
|
// src/commands/location.ts
|
|
248
248
|
import fs3 from "fs";
|
|
249
249
|
import { parseConfig as parseConfig3, resolveRemnicConfigRecord as resolveRemnicConfigRecord3 } from "@remnic/core";
|
|
250
|
-
import { runLocationCliCommand } from "@remnic/core/location";
|
|
250
|
+
import { backfillMemoryStorage, runLocationCliCommand } from "@remnic/core/location";
|
|
251
251
|
async function runLocationBinaryCommand(rest) {
|
|
252
252
|
const locationArgs = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
|
|
253
253
|
try {
|
|
@@ -264,7 +264,11 @@ async function runLocationBinaryCommand(rest) {
|
|
|
264
264
|
return;
|
|
265
265
|
}
|
|
266
266
|
const code = await runLocationCliCommand(
|
|
267
|
-
{
|
|
267
|
+
{
|
|
268
|
+
config: config.location,
|
|
269
|
+
memoryDir: config.memoryDir,
|
|
270
|
+
getMemoryStorage: () => backfillMemoryStorage(config)
|
|
271
|
+
},
|
|
268
272
|
locationArgs,
|
|
269
273
|
{ stdout: process.stdout, stderr: process.stderr }
|
|
270
274
|
);
|
|
@@ -300,7 +304,8 @@ async function runOkfBinaryCommand(rest) {
|
|
|
300
304
|
const code = await runOkfCliCommand(argv, { stdout: process.stdout, stderr: process.stderr }, {
|
|
301
305
|
memoryDir: config.memoryDir,
|
|
302
306
|
conformanceEnabled: config.okf.conformanceEnabled,
|
|
303
|
-
sweepEnabled: config.okf.sweepEnabled
|
|
307
|
+
sweepEnabled: config.okf.sweepEnabled,
|
|
308
|
+
indexFilesEnabled: config.okf.indexFilesEnabled
|
|
304
309
|
});
|
|
305
310
|
if (code !== 0) process.exitCode = code;
|
|
306
311
|
} catch (err) {
|
|
@@ -312,15 +317,173 @@ async function runOkfBinaryCommand(rest) {
|
|
|
312
317
|
}
|
|
313
318
|
}
|
|
314
319
|
|
|
315
|
-
// src/commands/
|
|
320
|
+
// src/commands/export-okf.ts
|
|
316
321
|
import fs5 from "fs";
|
|
317
|
-
import
|
|
322
|
+
import path from "path";
|
|
323
|
+
import { Orchestrator as Orchestrator4, parseConfig as parseConfig5, resolveRemnicConfigRecord as resolveRemnicConfigRecord5 } from "@remnic/core";
|
|
324
|
+
import { exportOkfBundle, parseIncludeStatus } from "@remnic/core/export-okf";
|
|
325
|
+
function takeFlag(rest, name) {
|
|
326
|
+
const index = rest.indexOf(name);
|
|
327
|
+
if (index < 0) return void 0;
|
|
328
|
+
const value = rest[index + 1];
|
|
329
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
330
|
+
throw new Error(`${name} requires a value`);
|
|
331
|
+
}
|
|
332
|
+
return value;
|
|
333
|
+
}
|
|
334
|
+
async function runExportOkfBinaryCommand(rest) {
|
|
335
|
+
if (rest[0] === "--help" || rest[0] === "-h" || rest.length === 0) {
|
|
336
|
+
console.log("Usage: remnic export okf --out <dir> [--force] [--include-profile] [--log]");
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (rest[0] !== "okf") {
|
|
340
|
+
console.error("Usage: remnic export okf --out <dir>");
|
|
341
|
+
process.exitCode = 1;
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const args = rest.slice(1);
|
|
345
|
+
let orchestrator;
|
|
346
|
+
try {
|
|
347
|
+
const out = takeFlag(args, "--out");
|
|
348
|
+
if (!out) throw new Error("Missing --out");
|
|
349
|
+
const namespace = takeFlag(args, "--namespace") ?? "";
|
|
350
|
+
const configPath = resolveConfigPath();
|
|
351
|
+
const raw = fs5.existsSync(configPath) ? JSON.parse(fs5.readFileSync(configPath, "utf8")) : {};
|
|
352
|
+
const config = parseConfig5(resolveRemnicConfigRecord5(raw));
|
|
353
|
+
orchestrator = new Orchestrator4(config);
|
|
354
|
+
await orchestrator.initialize();
|
|
355
|
+
await orchestrator.deferredReady;
|
|
356
|
+
const memoryDir = namespace ? path.join(orchestrator.config.memoryDir, "namespaces", namespace) : orchestrator.config.memoryDir;
|
|
357
|
+
const result = await exportOkfBundle({
|
|
358
|
+
memoryDir,
|
|
359
|
+
outDir: out,
|
|
360
|
+
includeStatus: parseIncludeStatus(takeFlag(args, "--include-status")),
|
|
361
|
+
includeCategories: takeFlag(args, "--include-categories")?.split(","),
|
|
362
|
+
excludeTags: takeFlag(args, "--exclude-tags")?.split(","),
|
|
363
|
+
includeProfile: args.includes("--include-profile"),
|
|
364
|
+
includeWearables: args.includes("--include-wearables"),
|
|
365
|
+
includeLog: args.includes("--log"),
|
|
366
|
+
force: args.includes("--force")
|
|
367
|
+
});
|
|
368
|
+
if (result.plaintextWarning) console.log("PLAINTEXT EXPORT: the OKF bundle is unencrypted.");
|
|
369
|
+
console.log(`OKF export: ${result.exported} concepts, ${result.excluded} excluded`);
|
|
370
|
+
} catch (err) {
|
|
371
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
372
|
+
process.exitCode = 1;
|
|
373
|
+
} finally {
|
|
374
|
+
orchestrator?.abortDeferredInit();
|
|
375
|
+
await orchestrator?.destroy();
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// src/commands/codegraph.ts
|
|
380
|
+
import fs6 from "fs";
|
|
381
|
+
import { Orchestrator as Orchestrator5, parseConfig as parseConfig6, resolveRemnicConfigRecord as resolveRemnicConfigRecord6 } from "@remnic/core";
|
|
382
|
+
import {
|
|
383
|
+
exportCodegraphOkfBundle,
|
|
384
|
+
parseOkfCodegraphSymbolFilter
|
|
385
|
+
} from "@remnic/core/export-okf-codegraph";
|
|
386
|
+
function takeFlag2(rest, name) {
|
|
387
|
+
const index = rest.indexOf(name);
|
|
388
|
+
if (index < 0) return void 0;
|
|
389
|
+
const value = rest[index + 1];
|
|
390
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
391
|
+
throw new Error(`${name} requires a value`);
|
|
392
|
+
}
|
|
393
|
+
return value;
|
|
394
|
+
}
|
|
395
|
+
async function runCodegraphBinaryCommand(rest) {
|
|
396
|
+
if (rest[0] === "--help" || rest[0] === "-h" || rest.length === 0) {
|
|
397
|
+
console.log(
|
|
398
|
+
"Usage: remnic codegraph export-okf --project <id> --out <dir> [--max-module-concepts <n>] [--symbols none|exported|all] [--force]"
|
|
399
|
+
);
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
if (rest[0] !== "export-okf") {
|
|
403
|
+
console.error("Usage: remnic codegraph export-okf --project <id> --out <dir>");
|
|
404
|
+
process.exitCode = 1;
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
const args = rest.slice(1);
|
|
408
|
+
let orchestrator;
|
|
409
|
+
try {
|
|
410
|
+
const project = takeFlag2(args, "--project");
|
|
411
|
+
const out = takeFlag2(args, "--out");
|
|
412
|
+
if (!project) throw new Error("Missing --project");
|
|
413
|
+
if (!out) throw new Error("Missing --out");
|
|
414
|
+
const configPath = resolveConfigPath();
|
|
415
|
+
const raw = fs6.existsSync(configPath) ? JSON.parse(fs6.readFileSync(configPath, "utf8")) : {};
|
|
416
|
+
const config = parseConfig6(resolveRemnicConfigRecord6(raw));
|
|
417
|
+
orchestrator = new Orchestrator5(config);
|
|
418
|
+
await orchestrator.initialize();
|
|
419
|
+
await orchestrator.deferredReady;
|
|
420
|
+
const maxRaw = takeFlag2(args, "--max-module-concepts");
|
|
421
|
+
const result = await exportCodegraphOkfBundle({
|
|
422
|
+
config: orchestrator.config,
|
|
423
|
+
memoryDir: orchestrator.config.memoryDir,
|
|
424
|
+
projectId: project,
|
|
425
|
+
outDir: out,
|
|
426
|
+
force: args.includes("--force"),
|
|
427
|
+
includeAdrs: !args.includes("--no-include-adrs"),
|
|
428
|
+
symbols: parseOkfCodegraphSymbolFilter(takeFlag2(args, "--symbols")),
|
|
429
|
+
...maxRaw !== void 0 ? { maxModuleConcepts: Number(maxRaw) } : {}
|
|
430
|
+
});
|
|
431
|
+
console.log(
|
|
432
|
+
`OKF codegraph export: ${result.moduleConcepts} modules, ${result.decisions} decisions` + (result.truncated ? " (truncated)" : "")
|
|
433
|
+
);
|
|
434
|
+
} catch (err) {
|
|
435
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
436
|
+
process.exitCode = 1;
|
|
437
|
+
} finally {
|
|
438
|
+
orchestrator?.abortDeferredInit();
|
|
439
|
+
await orchestrator?.destroy();
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/commands/standup.ts
|
|
444
|
+
import fs7 from "fs";
|
|
445
|
+
import { Orchestrator as Orchestrator6, parseConfig as parseConfig7, resolveRemnicConfigRecord as resolveRemnicConfigRecord7 } from "@remnic/core";
|
|
446
|
+
import { buildStandup, parseStandupDate, standupHelp } from "@remnic/core/standup";
|
|
447
|
+
function takeFlag3(rest, name) {
|
|
448
|
+
const index = rest.indexOf(name);
|
|
449
|
+
if (index < 0) return void 0;
|
|
450
|
+
const value = rest[index + 1];
|
|
451
|
+
if (value === void 0 || value.startsWith("-")) throw new Error(`${name} requires a value`);
|
|
452
|
+
return value;
|
|
453
|
+
}
|
|
454
|
+
async function runStandupBinaryCommand(rest) {
|
|
455
|
+
if (rest[0] === "--help" || rest[0] === "-h") {
|
|
456
|
+
console.log(standupHelp());
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
let orchestrator;
|
|
460
|
+
try {
|
|
461
|
+
const configPath = resolveConfigPath();
|
|
462
|
+
const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
|
|
463
|
+
const config = parseConfig7(resolveRemnicConfigRecord7(raw));
|
|
464
|
+
orchestrator = new Orchestrator6(config);
|
|
465
|
+
await orchestrator.initialize();
|
|
466
|
+
await orchestrator.deferredReady;
|
|
467
|
+
const brief = buildStandup(orchestrator.config.memoryDir, parseStandupDate(takeFlag3(rest, "--date")));
|
|
468
|
+
console.log(brief.markdown);
|
|
469
|
+
} catch (err) {
|
|
470
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
471
|
+
process.exitCode = 1;
|
|
472
|
+
} finally {
|
|
473
|
+
orchestrator?.abortDeferredInit();
|
|
474
|
+
await orchestrator?.destroy();
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// src/commands/external-wiki.ts
|
|
479
|
+
import fs8 from "fs";
|
|
480
|
+
import { parseConfig as parseConfig8, resolveRemnicConfigRecord as resolveRemnicConfigRecord8, runExternalWikiCliCommand } from "@remnic/core";
|
|
318
481
|
async function runExternalWikiBinaryCommand(rest) {
|
|
319
482
|
let roots;
|
|
320
483
|
try {
|
|
321
484
|
const configPath = resolveConfigPath();
|
|
322
|
-
const raw =
|
|
323
|
-
roots =
|
|
485
|
+
const raw = fs8.existsSync(configPath) ? JSON.parse(fs8.readFileSync(configPath, "utf8")) : {};
|
|
486
|
+
roots = parseConfig8(resolveRemnicConfigRecord8(raw)).externalWikis;
|
|
324
487
|
} catch {
|
|
325
488
|
console.error(
|
|
326
489
|
"external-wiki: failed to load the Remnic config - run `remnic doctor` and check the config file for errors"
|
|
@@ -341,14 +504,14 @@ async function runExternalWikiBinaryCommand(rest) {
|
|
|
341
504
|
}
|
|
342
505
|
|
|
343
506
|
// src/commands/procedural.ts
|
|
344
|
-
import
|
|
507
|
+
import fs9 from "fs";
|
|
345
508
|
import {
|
|
346
509
|
StorageManager,
|
|
347
510
|
computeProcedureStats,
|
|
348
511
|
formatProcedureStatsText,
|
|
349
512
|
initLogger,
|
|
350
|
-
parseConfig as
|
|
351
|
-
resolveRemnicConfigRecord as
|
|
513
|
+
parseConfig as parseConfig9,
|
|
514
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord9,
|
|
352
515
|
runProcedureLibraryMaintenance
|
|
353
516
|
} from "@remnic/core";
|
|
354
517
|
|
|
@@ -479,8 +642,8 @@ Shared with:
|
|
|
479
642
|
process.exit(1);
|
|
480
643
|
}
|
|
481
644
|
const configPath = resolveConfigPath();
|
|
482
|
-
const raw =
|
|
483
|
-
const config =
|
|
645
|
+
const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
|
|
646
|
+
const config = parseConfig9(resolveRemnicConfigRecord9(raw));
|
|
484
647
|
const memoryDir = expandTilde(
|
|
485
648
|
typeof memoryDirOverride === "string" && memoryDirOverride.length > 0 ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
|
|
486
649
|
);
|
|
@@ -535,12 +698,12 @@ function formatProcedureMaintenanceText(report) {
|
|
|
535
698
|
}
|
|
536
699
|
|
|
537
700
|
// src/commands/drift.ts
|
|
538
|
-
import
|
|
701
|
+
import fs10 from "fs";
|
|
539
702
|
import {
|
|
540
|
-
Orchestrator as
|
|
703
|
+
Orchestrator as Orchestrator7,
|
|
541
704
|
initLogger as initLogger2,
|
|
542
|
-
parseConfig as
|
|
543
|
-
resolveRemnicConfigRecord as
|
|
705
|
+
parseConfig as parseConfig10,
|
|
706
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord10,
|
|
544
707
|
runPreferenceDriftScan
|
|
545
708
|
} from "@remnic/core";
|
|
546
709
|
async function runDriftBinaryCommand(rest) {
|
|
@@ -600,13 +763,13 @@ Resolve a drifted item with the existing review surface:
|
|
|
600
763
|
process.exit(1);
|
|
601
764
|
}
|
|
602
765
|
const configPath = resolveConfigPath();
|
|
603
|
-
const raw =
|
|
604
|
-
const config =
|
|
766
|
+
const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
|
|
767
|
+
const config = parseConfig10(resolveRemnicConfigRecord10(raw));
|
|
605
768
|
const memoryDirOverridden = typeof memoryDirOverride === "string" && memoryDirOverride.length > 0;
|
|
606
769
|
const memoryDir = expandTilde(
|
|
607
770
|
memoryDirOverridden ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
|
|
608
771
|
);
|
|
609
|
-
const orchestrator = new
|
|
772
|
+
const orchestrator = new Orchestrator7(
|
|
610
773
|
memoryDirOverridden ? { ...config, memoryDir } : config
|
|
611
774
|
);
|
|
612
775
|
await orchestrator.initialize();
|
|
@@ -714,13 +877,13 @@ async function loadWecloneExportModule() {
|
|
|
714
877
|
}
|
|
715
878
|
|
|
716
879
|
// src/converge.ts
|
|
717
|
-
import * as
|
|
880
|
+
import * as fs12 from "fs";
|
|
718
881
|
import { createHash as createHash3 } from "crypto";
|
|
719
|
-
import * as
|
|
882
|
+
import * as path3 from "path";
|
|
720
883
|
import {
|
|
721
884
|
CONVERGE_CONFLICT_POLICIES,
|
|
722
885
|
DEFAULT_CONVERGE_CONFLICT_POLICY,
|
|
723
|
-
parseConfig as
|
|
886
|
+
parseConfig as parseConfig11,
|
|
724
887
|
buildOfflineSyncSnapshotFromBase,
|
|
725
888
|
applyOfflineSyncFileContentChunk,
|
|
726
889
|
isInternalRemnicStatePath as isInternalRemnicStatePath3,
|
|
@@ -746,9 +909,9 @@ import {
|
|
|
746
909
|
|
|
747
910
|
// src/offline-storage-io.ts
|
|
748
911
|
import { createDecipheriv, createHash } from "crypto";
|
|
749
|
-
import
|
|
912
|
+
import fs11 from "fs";
|
|
750
913
|
import { lstat, mkdtemp, readdir, rm } from "fs/promises";
|
|
751
|
-
import
|
|
914
|
+
import path2 from "path";
|
|
752
915
|
import {
|
|
753
916
|
OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES,
|
|
754
917
|
StorageManager as StorageManager2,
|
|
@@ -775,10 +938,10 @@ import {
|
|
|
775
938
|
} from "@remnic/core/secure-store";
|
|
776
939
|
var OFFLINE_SYNC_EXCLUSION_CONCURRENCY = 16;
|
|
777
940
|
function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
|
|
778
|
-
const base =
|
|
779
|
-
const target =
|
|
780
|
-
const relative =
|
|
781
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
941
|
+
const base = path2.resolve(memoryDir);
|
|
942
|
+
const target = path2.resolve(base, relPath);
|
|
943
|
+
const relative = path2.relative(base, target);
|
|
944
|
+
if (relative === "" || relative === ".." || relative.startsWith(`..${path2.sep}`) || path2.isAbsolute(relative)) {
|
|
782
945
|
throw new Error(`offline sync direct hydration path escapes memory dir: ${relPath}`);
|
|
783
946
|
}
|
|
784
947
|
return target;
|
|
@@ -812,13 +975,13 @@ async function createConfiguredOfflineStorage(memoryDir, secureStoreEncryptOnWri
|
|
|
812
975
|
return { storage, secureStoreKey, secureStoreRequired };
|
|
813
976
|
}
|
|
814
977
|
async function createOfflineStorageForPath(memoryDir, filePath, configured, secureStoreEncryptOnWrite) {
|
|
815
|
-
const memoryRoot =
|
|
816
|
-
const stateDir =
|
|
817
|
-
if (
|
|
978
|
+
const memoryRoot = path2.resolve(memoryDir);
|
|
979
|
+
const stateDir = path2.dirname(filePath);
|
|
980
|
+
if (path2.basename(stateDir) !== "state" || path2.basename(filePath) !== "memory-lifecycle-ledger.jsonl") {
|
|
818
981
|
throw new Error(`invalid lifecycle ledger path: ${filePath}`);
|
|
819
982
|
}
|
|
820
|
-
const storageRoot =
|
|
821
|
-
if (storageRoot !== memoryRoot && !storageRoot.startsWith(`${memoryRoot}${
|
|
983
|
+
const storageRoot = path2.resolve(path2.dirname(stateDir));
|
|
984
|
+
if (storageRoot !== memoryRoot && !storageRoot.startsWith(`${memoryRoot}${path2.sep}`)) {
|
|
822
985
|
throw new Error(`lifecycle ledger path is outside the offline memory directory: ${filePath}`);
|
|
823
986
|
}
|
|
824
987
|
const storage = new StorageManager2(storageRoot);
|
|
@@ -879,7 +1042,7 @@ async function cleanupOrphanedOfflineDecryptStaging(memoryDir) {
|
|
|
879
1042
|
const now = Date.now();
|
|
880
1043
|
for (const name of entries) {
|
|
881
1044
|
if (!name.startsWith(OFFLINE_DECRYPT_STAGING_DIR_PREFIX)) continue;
|
|
882
|
-
const dir =
|
|
1045
|
+
const dir = path2.join(memoryDir, name);
|
|
883
1046
|
try {
|
|
884
1047
|
const info = await lstat(dir);
|
|
885
1048
|
if (!info.isDirectory() || info.isSymbolicLink()) continue;
|
|
@@ -908,7 +1071,7 @@ async function* readOfflineSyncFileChunks(options) {
|
|
|
908
1071
|
});
|
|
909
1072
|
}
|
|
910
1073
|
async function readFilePrefix(filePath, length) {
|
|
911
|
-
const handle = await
|
|
1074
|
+
const handle = await fs11.promises.open(filePath, "r");
|
|
912
1075
|
try {
|
|
913
1076
|
const out = Buffer.alloc(length);
|
|
914
1077
|
const { bytesRead } = await handle.read(out, 0, length, 0);
|
|
@@ -918,7 +1081,7 @@ async function readFilePrefix(filePath, length) {
|
|
|
918
1081
|
}
|
|
919
1082
|
}
|
|
920
1083
|
async function* readPlainOfflineFileChunks(filePath, chunkSize) {
|
|
921
|
-
const stream =
|
|
1084
|
+
const stream = fs11.createReadStream(filePath, { highWaterMark: chunkSize });
|
|
922
1085
|
for await (const chunk of stream) {
|
|
923
1086
|
yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
924
1087
|
}
|
|
@@ -947,17 +1110,17 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
947
1110
|
const aadCandidates = offlineFileAadCandidates(options.filePath, options.memoryDir);
|
|
948
1111
|
let lastError;
|
|
949
1112
|
for (const aad of aadCandidates) {
|
|
950
|
-
const tempDir = await mkdtemp(
|
|
951
|
-
const tempPath =
|
|
1113
|
+
const tempDir = await mkdtemp(path2.join(options.memoryDir, OFFLINE_DECRYPT_STAGING_DIR_PREFIX));
|
|
1114
|
+
const tempPath = path2.join(tempDir, "content");
|
|
952
1115
|
try {
|
|
953
1116
|
const decipher = createDecipheriv("aes-256-gcm", options.key, iv, {
|
|
954
1117
|
authTagLength: AUTH_TAG_LENGTH
|
|
955
1118
|
});
|
|
956
1119
|
decipher.setAuthTag(authTag);
|
|
957
1120
|
decipher.setAAD(Buffer.concat([secureStoreEnvelopeHeaderAad(salt), aad]));
|
|
958
|
-
const output =
|
|
1121
|
+
const output = fs11.createWriteStream(tempPath, { mode: 384 });
|
|
959
1122
|
try {
|
|
960
|
-
const stream =
|
|
1123
|
+
const stream = fs11.createReadStream(options.filePath, {
|
|
961
1124
|
start: MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE,
|
|
962
1125
|
highWaterMark: options.chunkSize
|
|
963
1126
|
});
|
|
@@ -992,17 +1155,17 @@ async function* readEncryptedOfflineFileChunks(options) {
|
|
|
992
1155
|
}
|
|
993
1156
|
function offlineFileAadCandidates(filePath, memoryDir) {
|
|
994
1157
|
const candidates = [filePathAad(filePath, memoryDir)];
|
|
995
|
-
const relative =
|
|
996
|
-
if (!relative || relative.startsWith("..") ||
|
|
997
|
-
const parts = relative.split(
|
|
1158
|
+
const relative = path2.relative(memoryDir, filePath);
|
|
1159
|
+
if (!relative || relative.startsWith("..") || path2.isAbsolute(relative)) return candidates;
|
|
1160
|
+
const parts = relative.split(path2.sep);
|
|
998
1161
|
if (parts[0] === "namespaces" && parts.length >= 3 && parts[1]) {
|
|
999
|
-
candidates.push(filePathAad(filePath,
|
|
1162
|
+
candidates.push(filePathAad(filePath, path2.join(memoryDir, "namespaces", parts[1])));
|
|
1000
1163
|
}
|
|
1001
|
-
const memoryParts =
|
|
1164
|
+
const memoryParts = path2.resolve(memoryDir).split(path2.sep);
|
|
1002
1165
|
if (memoryParts.length >= 3 && memoryParts.at(-2) === "namespaces" && memoryParts.at(-1)) {
|
|
1003
|
-
const topLevelRoot = memoryParts.slice(0, -2).join(
|
|
1004
|
-
const topRelative =
|
|
1005
|
-
if (topRelative && !topRelative.startsWith("..") && !
|
|
1166
|
+
const topLevelRoot = memoryParts.slice(0, -2).join(path2.sep) || path2.sep;
|
|
1167
|
+
const topRelative = path2.relative(topLevelRoot, filePath);
|
|
1168
|
+
if (topRelative && !topRelative.startsWith("..") && !path2.isAbsolute(topRelative) && topRelative.split(path2.sep)[0] === "namespaces" && topRelative.split(path2.sep)[1] === memoryParts.at(-1)) {
|
|
1006
1169
|
candidates.push(filePathAad(filePath, topLevelRoot));
|
|
1007
1170
|
}
|
|
1008
1171
|
}
|
|
@@ -1567,7 +1730,7 @@ async function readLocalTombstoneEvidence(rootDir) {
|
|
|
1567
1730
|
for (const relativePath of TOMBSTONE_PATHS) {
|
|
1568
1731
|
let content;
|
|
1569
1732
|
try {
|
|
1570
|
-
content = await
|
|
1733
|
+
content = await fs12.promises.readFile(path3.join(rootDir, relativePath), "utf-8");
|
|
1571
1734
|
} catch (error) {
|
|
1572
1735
|
if (error.code === "ENOENT") continue;
|
|
1573
1736
|
throw error;
|
|
@@ -1579,10 +1742,10 @@ async function readLocalTombstoneEvidence(rootDir) {
|
|
|
1579
1742
|
return merged;
|
|
1580
1743
|
}
|
|
1581
1744
|
async function discoverCursorNamespaces(memoryDir, peerUrl) {
|
|
1582
|
-
const cursorDir =
|
|
1745
|
+
const cursorDir = path3.join(path3.resolve(memoryDir), ".remnic", "state", "converge-cursors");
|
|
1583
1746
|
let entries;
|
|
1584
1747
|
try {
|
|
1585
|
-
entries = await
|
|
1748
|
+
entries = await fs12.promises.readdir(cursorDir, { withFileTypes: true });
|
|
1586
1749
|
} catch (error) {
|
|
1587
1750
|
if (error.code === "ENOENT") return [];
|
|
1588
1751
|
throw error;
|
|
@@ -1590,9 +1753,9 @@ async function discoverCursorNamespaces(memoryDir, peerUrl) {
|
|
|
1590
1753
|
const namespaces = /* @__PURE__ */ new Set();
|
|
1591
1754
|
for (const entry of entries) {
|
|
1592
1755
|
if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
|
|
1593
|
-
const cursor = await readConvergeCursor(
|
|
1756
|
+
const cursor = await readConvergeCursor(path3.join(cursorDir, entry.name));
|
|
1594
1757
|
if (!cursor) throw new Error(`invalid converge cursor: ${entry.name}`);
|
|
1595
|
-
if (
|
|
1758
|
+
if (path3.basename(defaultConvergeCursorPath(memoryDir, peerUrl, cursor.namespace)) !== entry.name) continue;
|
|
1596
1759
|
namespaces.add(cursor.namespace);
|
|
1597
1760
|
}
|
|
1598
1761
|
return [...namespaces].sort();
|
|
@@ -1658,7 +1821,7 @@ async function computeConvergePlan(options = {}) {
|
|
|
1658
1821
|
let config = options.config;
|
|
1659
1822
|
if (!config) {
|
|
1660
1823
|
try {
|
|
1661
|
-
config =
|
|
1824
|
+
config = parseConfig11({});
|
|
1662
1825
|
} catch {
|
|
1663
1826
|
}
|
|
1664
1827
|
}
|
|
@@ -1704,7 +1867,7 @@ async function computeConvergePlan(options = {}) {
|
|
|
1704
1867
|
return await readFile3({
|
|
1705
1868
|
root: rootInfo.rootDir,
|
|
1706
1869
|
path: file.path,
|
|
1707
|
-
filePath:
|
|
1870
|
+
filePath: path3.join(rootInfo.rootDir, file.path)
|
|
1708
1871
|
});
|
|
1709
1872
|
} catch (error) {
|
|
1710
1873
|
manifestReadFailed = true;
|
|
@@ -1909,7 +2072,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
1909
2072
|
let config = options.config;
|
|
1910
2073
|
if (!config) {
|
|
1911
2074
|
try {
|
|
1912
|
-
config =
|
|
2075
|
+
config = parseConfig11({});
|
|
1913
2076
|
} catch {
|
|
1914
2077
|
}
|
|
1915
2078
|
}
|
|
@@ -2066,13 +2229,13 @@ async function executeConvergeApply(options = {}) {
|
|
|
2066
2229
|
const rootDir = rootMap.get(entry.namespace);
|
|
2067
2230
|
if (rootDir) {
|
|
2068
2231
|
try {
|
|
2069
|
-
const filePath =
|
|
2232
|
+
const filePath = path3.join(rootDir, localPath);
|
|
2070
2233
|
const io = await createOfflineStorageIo(rootDir);
|
|
2071
2234
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
2072
2235
|
if (current.sha256 !== entry.localSha256) {
|
|
2073
2236
|
throw new Error(`local file changed during push: ${localPath}`);
|
|
2074
2237
|
}
|
|
2075
|
-
const stat2 = await
|
|
2238
|
+
const stat2 = await fs12.promises.stat(filePath);
|
|
2076
2239
|
let chunks;
|
|
2077
2240
|
let chunkOffset = 0;
|
|
2078
2241
|
const resetChunks = async () => {
|
|
@@ -2163,7 +2326,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
2163
2326
|
if (rootDir && entry.localSha256) {
|
|
2164
2327
|
try {
|
|
2165
2328
|
const io = await createOfflineStorageIo(rootDir);
|
|
2166
|
-
const filePath =
|
|
2329
|
+
const filePath = path3.join(rootDir, localPath);
|
|
2167
2330
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
2168
2331
|
if (current.sha256 === entry.localSha256) {
|
|
2169
2332
|
await io.deleteFile({ root: rootDir, path: localPath, filePath });
|
|
@@ -2216,7 +2379,7 @@ async function executeConvergeApply(options = {}) {
|
|
|
2216
2379
|
if (rootDir) {
|
|
2217
2380
|
try {
|
|
2218
2381
|
const io = await createOfflineStorageIo(rootDir);
|
|
2219
|
-
const filePath =
|
|
2382
|
+
const filePath = path3.join(rootDir, localPath);
|
|
2220
2383
|
const current = await io.readFileDigest({ root: rootDir, path: localPath, filePath });
|
|
2221
2384
|
if (current.sha256 === entry.localSha256) {
|
|
2222
2385
|
await io.deleteFile({ root: rootDir, path: localPath, filePath });
|
|
@@ -2349,7 +2512,7 @@ function formatConvergeApplyReport(result) {
|
|
|
2349
2512
|
lines.push(formatConvergeReport(result.plan));
|
|
2350
2513
|
return lines.join("\n");
|
|
2351
2514
|
}
|
|
2352
|
-
async function cmdConverge(action, rest, json, config =
|
|
2515
|
+
async function cmdConverge(action, rest, json, config = parseConfig11({})) {
|
|
2353
2516
|
if (action === "help" || action === "--help" || action === "-h" || rest.includes("--help") || rest.includes("-h")) {
|
|
2354
2517
|
console.log(`Usage: remnic converge <plan|apply> [options]
|
|
2355
2518
|
|
|
@@ -2555,8 +2718,8 @@ function renderReplayResult(result, targetNamespace, format) {
|
|
|
2555
2718
|
}
|
|
2556
2719
|
|
|
2557
2720
|
// src/quarantine-replay.ts
|
|
2558
|
-
import * as
|
|
2559
|
-
import { EngramAccessService, Orchestrator as
|
|
2721
|
+
import * as fs13 from "fs";
|
|
2722
|
+
import { EngramAccessService, Orchestrator as Orchestrator8, initLogger as initLogger3, parseConfig as parseConfig12, resolveRemnicConfigRecord as resolveRemnicConfigRecord11 } from "@remnic/core";
|
|
2560
2723
|
import { WriteQuarantineStore } from "@remnic/core/write-quarantine.js";
|
|
2561
2724
|
function valueFlag(args, flag) {
|
|
2562
2725
|
const occurrences = args.filter((a) => a === flag).length;
|
|
@@ -2604,9 +2767,9 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
|
|
|
2604
2767
|
let orchestrator;
|
|
2605
2768
|
try {
|
|
2606
2769
|
const configPath = resolveConfigPath2();
|
|
2607
|
-
const raw =
|
|
2608
|
-
const config =
|
|
2609
|
-
orchestrator = new
|
|
2770
|
+
const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
|
|
2771
|
+
const config = parseConfig12(resolveRemnicConfigRecord11(raw));
|
|
2772
|
+
orchestrator = new Orchestrator8(config);
|
|
2610
2773
|
await orchestrator.initialize();
|
|
2611
2774
|
await orchestrator.deferredReady;
|
|
2612
2775
|
const service = new EngramAccessService(orchestrator);
|
|
@@ -2636,15 +2799,15 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
|
|
|
2636
2799
|
}
|
|
2637
2800
|
|
|
2638
2801
|
// src/offline-impression-rotation.ts
|
|
2639
|
-
import
|
|
2640
|
-
import { parseConfig as
|
|
2802
|
+
import fs14 from "fs";
|
|
2803
|
+
import { parseConfig as parseConfig13, resolveRemnicConfigRecord as resolveRemnicConfigRecord12, drainPendingImpressionsForOfflineSync } from "@remnic/core";
|
|
2641
2804
|
import { LastRecallStore } from "@remnic/core/recall-state";
|
|
2642
2805
|
function parseConfigQuietly(raw) {
|
|
2643
2806
|
const originalWarn = console.warn;
|
|
2644
2807
|
console.warn = () => {
|
|
2645
2808
|
};
|
|
2646
2809
|
try {
|
|
2647
|
-
return
|
|
2810
|
+
return parseConfig13(resolveRemnicConfigRecord12(raw));
|
|
2648
2811
|
} finally {
|
|
2649
2812
|
console.warn = originalWarn;
|
|
2650
2813
|
}
|
|
@@ -2658,7 +2821,7 @@ var OFFLINE_CONFIG_KEYS = [
|
|
|
2658
2821
|
function pickOfflineConfigRecord(raw) {
|
|
2659
2822
|
let resolved;
|
|
2660
2823
|
try {
|
|
2661
|
-
resolved =
|
|
2824
|
+
resolved = resolveRemnicConfigRecord12(raw);
|
|
2662
2825
|
} catch {
|
|
2663
2826
|
resolved = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
2664
2827
|
}
|
|
@@ -2671,7 +2834,7 @@ function pickOfflineConfigRecord(raw) {
|
|
|
2671
2834
|
function resolveOfflineImpressionRotation(configPath) {
|
|
2672
2835
|
let raw;
|
|
2673
2836
|
try {
|
|
2674
|
-
raw =
|
|
2837
|
+
raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
|
|
2675
2838
|
} catch {
|
|
2676
2839
|
throw new Error(
|
|
2677
2840
|
`cannot read recall-impression rotation from ${configPath}: config file could not be read as JSON`
|
|
@@ -2707,15 +2870,15 @@ import {
|
|
|
2707
2870
|
readFileSync as readFileSync2,
|
|
2708
2871
|
statSync
|
|
2709
2872
|
} from "fs";
|
|
2710
|
-
import
|
|
2873
|
+
import path4 from "path";
|
|
2711
2874
|
import { fileURLToPath } from "url";
|
|
2712
2875
|
var STALE_BUILD_TOLERANCE_MS = 1e3;
|
|
2713
2876
|
function assertLocalBenchBuildFreshForDevelopment(currentModuleUrl) {
|
|
2714
2877
|
if (isTruthyEnv(process.env.REMNIC_BENCH_ALLOW_STALE_DIST)) {
|
|
2715
2878
|
return;
|
|
2716
2879
|
}
|
|
2717
|
-
const currentDir =
|
|
2718
|
-
const benchPackageDir =
|
|
2880
|
+
const currentDir = path4.dirname(fileURLToPath(currentModuleUrl));
|
|
2881
|
+
const benchPackageDir = path4.resolve(currentDir, "../../bench");
|
|
2719
2882
|
const freshness = checkBenchBuildFreshness(benchPackageDir);
|
|
2720
2883
|
if (!freshness.stale) {
|
|
2721
2884
|
return;
|
|
@@ -2732,7 +2895,7 @@ function assertLocalBenchBuildFreshForDevelopment(currentModuleUrl) {
|
|
|
2732
2895
|
);
|
|
2733
2896
|
}
|
|
2734
2897
|
function checkBenchBuildFreshness(benchPackageDir) {
|
|
2735
|
-
const packageJsonPath =
|
|
2898
|
+
const packageJsonPath = path4.join(benchPackageDir, "package.json");
|
|
2736
2899
|
if (!existsSync2(packageJsonPath)) {
|
|
2737
2900
|
return { stale: false };
|
|
2738
2901
|
}
|
|
@@ -2745,17 +2908,17 @@ function checkBenchBuildFreshness(benchPackageDir) {
|
|
|
2745
2908
|
if (packageName !== "@remnic/bench") {
|
|
2746
2909
|
return { stale: false };
|
|
2747
2910
|
}
|
|
2748
|
-
const srcDir =
|
|
2911
|
+
const srcDir = path4.join(benchPackageDir, "src");
|
|
2749
2912
|
if (!isDirectory(srcDir)) {
|
|
2750
2913
|
return { stale: false };
|
|
2751
2914
|
}
|
|
2752
2915
|
const sourceRoots = [
|
|
2753
2916
|
srcDir,
|
|
2754
2917
|
packageJsonPath,
|
|
2755
|
-
|
|
2756
|
-
|
|
2918
|
+
path4.join(benchPackageDir, "tsup.config.ts"),
|
|
2919
|
+
path4.join(benchPackageDir, "tsconfig.json")
|
|
2757
2920
|
];
|
|
2758
|
-
const distPath =
|
|
2921
|
+
const distPath = path4.join(benchPackageDir, "dist", "index.js");
|
|
2759
2922
|
if (!existsSync2(distPath)) {
|
|
2760
2923
|
return {
|
|
2761
2924
|
stale: true,
|
|
@@ -2798,7 +2961,7 @@ function newestMtime(roots) {
|
|
|
2798
2961
|
}
|
|
2799
2962
|
if (stat2.isDirectory()) {
|
|
2800
2963
|
for (const child of readdirSync(entryPath)) {
|
|
2801
|
-
visit(
|
|
2964
|
+
visit(path4.join(entryPath, child));
|
|
2802
2965
|
}
|
|
2803
2966
|
return;
|
|
2804
2967
|
}
|
|
@@ -2831,18 +2994,18 @@ function isTruthyEnv(value) {
|
|
|
2831
2994
|
|
|
2832
2995
|
// src/optional-bench.ts
|
|
2833
2996
|
import { existsSync as existsSync3 } from "fs";
|
|
2834
|
-
import
|
|
2997
|
+
import path5 from "path";
|
|
2835
2998
|
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
|
|
2836
2999
|
var SPECIFIER2 = "@remnic/bench";
|
|
2837
3000
|
var TSX_ESM_API_SPECIFIER = "tsx/esm/api";
|
|
2838
3001
|
var cached2;
|
|
2839
3002
|
var cachedFromLocalWorkspaceBenchSource = false;
|
|
2840
3003
|
function resolveLocalWorkspaceBenchPaths() {
|
|
2841
|
-
const currentDir =
|
|
2842
|
-
const benchPackageDir =
|
|
3004
|
+
const currentDir = path5.dirname(fileURLToPath2(import.meta.url));
|
|
3005
|
+
const benchPackageDir = path5.resolve(currentDir, "../../bench");
|
|
2843
3006
|
return {
|
|
2844
|
-
distEntry:
|
|
2845
|
-
sourceEntry:
|
|
3007
|
+
distEntry: path5.join(benchPackageDir, "dist", "index.js"),
|
|
3008
|
+
sourceEntry: path5.join(benchPackageDir, "src", "index.ts")
|
|
2846
3009
|
};
|
|
2847
3010
|
}
|
|
2848
3011
|
async function tryImportLocalWorkspaceBenchSource(err) {
|
|
@@ -2929,12 +3092,12 @@ function assertBenchModuleFreshForDevelopment() {
|
|
|
2929
3092
|
}
|
|
2930
3093
|
|
|
2931
3094
|
// src/cmd-security.ts
|
|
2932
|
-
import
|
|
3095
|
+
import fs15 from "fs";
|
|
2933
3096
|
import {
|
|
2934
|
-
Orchestrator as
|
|
2935
|
-
parseConfig as
|
|
3097
|
+
Orchestrator as Orchestrator9,
|
|
3098
|
+
parseConfig as parseConfig14,
|
|
2936
3099
|
initLogger as initLogger4,
|
|
2937
|
-
resolveRemnicConfigRecord as
|
|
3100
|
+
resolveRemnicConfigRecord as resolveRemnicConfigRecord13,
|
|
2938
3101
|
runAuditMemoryCliCommand,
|
|
2939
3102
|
formatAuditMemoryReport
|
|
2940
3103
|
} from "@remnic/core";
|
|
@@ -2949,9 +3112,9 @@ async function cmdSecurity(rest) {
|
|
|
2949
3112
|
}
|
|
2950
3113
|
initLogger4();
|
|
2951
3114
|
const configPath = resolveConfigPath();
|
|
2952
|
-
const raw =
|
|
2953
|
-
const config =
|
|
2954
|
-
const orchestrator = new
|
|
3115
|
+
const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
|
|
3116
|
+
const config = parseConfig14(resolveRemnicConfigRecord13(raw));
|
|
3117
|
+
const orchestrator = new Orchestrator9(config);
|
|
2955
3118
|
await orchestrator.initialize();
|
|
2956
3119
|
try {
|
|
2957
3120
|
const sinceFlag = rest.indexOf("--since");
|
|
@@ -2974,8 +3137,8 @@ async function cmdSecurity(rest) {
|
|
|
2974
3137
|
}
|
|
2975
3138
|
|
|
2976
3139
|
// src/daemon-service-candidates.ts
|
|
2977
|
-
import
|
|
2978
|
-
import
|
|
3140
|
+
import fs16 from "fs";
|
|
3141
|
+
import path6 from "path";
|
|
2979
3142
|
var LAUNCHD_LABEL = "ai.remnic.daemon";
|
|
2980
3143
|
var LEGACY_REMNIC_SERVER_LAUNCHD_LABEL = "ai.remnic.server";
|
|
2981
3144
|
var LEGACY_LAUNCHD_LABEL = "ai.engram.daemon";
|
|
@@ -2988,15 +3151,15 @@ var SYSTEMD_SERVICE = "remnic.service";
|
|
|
2988
3151
|
var LEGACY_SYSTEMD_SERVICE = "engram.service";
|
|
2989
3152
|
var SYSTEMD_SERVICE_CANDIDATES = [SYSTEMD_SERVICE, LEGACY_SYSTEMD_SERVICE];
|
|
2990
3153
|
function launchdPlistPaths(homeDir) {
|
|
2991
|
-
return LAUNCHD_LABEL_CANDIDATES.map((label) =>
|
|
3154
|
+
return LAUNCHD_LABEL_CANDIDATES.map((label) => path6.join(homeDir, "Library", "LaunchAgents", `${label}.plist`));
|
|
2992
3155
|
}
|
|
2993
3156
|
function systemdUnitPaths(homeDir) {
|
|
2994
|
-
return SYSTEMD_SERVICE_CANDIDATES.map((service) =>
|
|
3157
|
+
return SYSTEMD_SERVICE_CANDIDATES.map((service) => path6.join(homeDir, ".config", "systemd", "user", service));
|
|
2995
3158
|
}
|
|
2996
3159
|
function anyFileExists(paths) {
|
|
2997
3160
|
return paths.some((candidate) => {
|
|
2998
3161
|
try {
|
|
2999
|
-
return
|
|
3162
|
+
return fs16.statSync(candidate).isFile();
|
|
3000
3163
|
} catch {
|
|
3001
3164
|
return false;
|
|
3002
3165
|
}
|
|
@@ -3008,7 +3171,7 @@ function commandNames(command) {
|
|
|
3008
3171
|
}
|
|
3009
3172
|
function isRunnableNodeScript(filePath) {
|
|
3010
3173
|
try {
|
|
3011
|
-
const text =
|
|
3174
|
+
const text = fs16.readFileSync(filePath, "utf8").slice(0, 4096);
|
|
3012
3175
|
const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
|
|
3013
3176
|
if (/^#!.*\bnode\b/.test(firstLine)) return true;
|
|
3014
3177
|
if (firstLine.startsWith("#!")) return false;
|
|
@@ -3021,20 +3184,20 @@ function isRunnableNodeScript(filePath) {
|
|
|
3021
3184
|
function resolveShimNodeScript(filePath) {
|
|
3022
3185
|
let text;
|
|
3023
3186
|
try {
|
|
3024
|
-
text =
|
|
3187
|
+
text = fs16.readFileSync(filePath, "utf8").slice(0, 16384);
|
|
3025
3188
|
} catch {
|
|
3026
3189
|
return void 0;
|
|
3027
3190
|
}
|
|
3028
|
-
const basedir =
|
|
3191
|
+
const basedir = path6.dirname(filePath);
|
|
3029
3192
|
const jsReferencePattern = /"([^"]+\.js)"|'([^']+\.js)'|([^\s"'`]+\.js)/g;
|
|
3030
3193
|
for (const match of text.matchAll(jsReferencePattern)) {
|
|
3031
3194
|
const raw = match[1] ?? match[2] ?? match[3];
|
|
3032
3195
|
if (!raw) continue;
|
|
3033
3196
|
const candidate = raw.replaceAll("${basedir}", basedir).replaceAll("$basedir", basedir).replaceAll("\\ ", " ");
|
|
3034
|
-
const resolved =
|
|
3197
|
+
const resolved = path6.isAbsolute(candidate) ? candidate : path6.resolve(basedir, candidate);
|
|
3035
3198
|
try {
|
|
3036
|
-
if (
|
|
3037
|
-
return
|
|
3199
|
+
if (fs16.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
|
|
3200
|
+
return fs16.realpathSync(resolved);
|
|
3038
3201
|
}
|
|
3039
3202
|
} catch {
|
|
3040
3203
|
}
|
|
@@ -3042,19 +3205,19 @@ function resolveShimNodeScript(filePath) {
|
|
|
3042
3205
|
return void 0;
|
|
3043
3206
|
}
|
|
3044
3207
|
function resolveRunnableNodeScript(filePath) {
|
|
3045
|
-
const realPath =
|
|
3208
|
+
const realPath = fs16.realpathSync(filePath);
|
|
3046
3209
|
if (isRunnableNodeScript(realPath)) return realPath;
|
|
3047
3210
|
return resolveShimNodeScript(realPath);
|
|
3048
3211
|
}
|
|
3049
3212
|
function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
|
|
3050
|
-
for (const dir of pathEnv.split(
|
|
3213
|
+
for (const dir of pathEnv.split(path6.delimiter)) {
|
|
3051
3214
|
if (!dir) continue;
|
|
3052
3215
|
for (const name of commandNames(command)) {
|
|
3053
|
-
const candidate =
|
|
3216
|
+
const candidate = path6.join(dir, name);
|
|
3054
3217
|
try {
|
|
3055
|
-
const stat2 =
|
|
3218
|
+
const stat2 = fs16.statSync(candidate);
|
|
3056
3219
|
if (!stat2.isFile()) continue;
|
|
3057
|
-
if (process.platform !== "win32")
|
|
3220
|
+
if (process.platform !== "win32") fs16.accessSync(candidate, fs16.constants.X_OK);
|
|
3058
3221
|
const runnable = resolveRunnableNodeScript(candidate);
|
|
3059
3222
|
if (runnable) return runnable;
|
|
3060
3223
|
} catch {
|
|
@@ -3064,11 +3227,11 @@ function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
|
|
|
3064
3227
|
return void 0;
|
|
3065
3228
|
}
|
|
3066
3229
|
function serverBinWrapperRequiredPath(candidate) {
|
|
3067
|
-
const filename =
|
|
3230
|
+
const filename = path6.basename(candidate);
|
|
3068
3231
|
if (filename !== "remnic-server.js" && filename !== "engram-server.js") return void 0;
|
|
3069
|
-
const binDir =
|
|
3070
|
-
if (
|
|
3071
|
-
return
|
|
3232
|
+
const binDir = path6.dirname(candidate);
|
|
3233
|
+
if (path6.basename(binDir) !== "bin") return void 0;
|
|
3234
|
+
return path6.join(path6.dirname(binDir), "dist", "index.js");
|
|
3072
3235
|
}
|
|
3073
3236
|
|
|
3074
3237
|
// src/service-candidates.ts
|
|
@@ -3090,7 +3253,7 @@ function firstSuccessfulCandidate(candidates, attempt) {
|
|
|
3090
3253
|
}
|
|
3091
3254
|
|
|
3092
3255
|
// src/bench-args.ts
|
|
3093
|
-
import
|
|
3256
|
+
import path8 from "path";
|
|
3094
3257
|
|
|
3095
3258
|
// src/bench-flags.ts
|
|
3096
3259
|
function readBenchOptionValue(argv, flag) {
|
|
@@ -3455,7 +3618,7 @@ function collectBenchmarks(argv) {
|
|
|
3455
3618
|
}
|
|
3456
3619
|
|
|
3457
3620
|
// src/bench-args-research.ts
|
|
3458
|
-
import
|
|
3621
|
+
import path7 from "path";
|
|
3459
3622
|
function readPositiveInteger(args, flag) {
|
|
3460
3623
|
const raw = readBenchOptionValue(args, flag);
|
|
3461
3624
|
if (raw === void 0) return void 0;
|
|
@@ -3501,7 +3664,7 @@ function parseBenchResearchArgs(action, args) {
|
|
|
3501
3664
|
}
|
|
3502
3665
|
const outRaw = readBenchOptionValue(args, "--out");
|
|
3503
3666
|
if (outRaw !== void 0) {
|
|
3504
|
-
out =
|
|
3667
|
+
out = path7.resolve(expandTilde(outRaw));
|
|
3505
3668
|
}
|
|
3506
3669
|
}
|
|
3507
3670
|
const epochs = readPositiveInteger(args, "--epochs");
|
|
@@ -3515,8 +3678,8 @@ function parseBenchResearchArgs(action, args) {
|
|
|
3515
3678
|
}
|
|
3516
3679
|
return {
|
|
3517
3680
|
runRef,
|
|
3518
|
-
memoryDir: memoryDirRaw ?
|
|
3519
|
-
qmdPath: qmdPathRaw ?
|
|
3681
|
+
memoryDir: memoryDirRaw ? path7.resolve(expandTilde(memoryDirRaw)) : void 0,
|
|
3682
|
+
qmdPath: qmdPathRaw ? path7.resolve(expandTilde(qmdPathRaw)) : void 0,
|
|
3520
3683
|
collection,
|
|
3521
3684
|
users: readPositiveInteger(args, "--users"),
|
|
3522
3685
|
epochs,
|
|
@@ -3736,7 +3899,7 @@ function parseBenchArgs(argv) {
|
|
|
3736
3899
|
}
|
|
3737
3900
|
validateBenchFlags(action, args);
|
|
3738
3901
|
const driftGenPositionals = action === "drift-gen" && driftGenAction === "validate" ? collectBenchmarks(args.slice(1)) : [];
|
|
3739
|
-
const driftGenDir = driftGenPositionals[0] ?
|
|
3902
|
+
const driftGenDir = driftGenPositionals[0] ? path8.resolve(expandTilde(driftGenPositionals[0])) : void 0;
|
|
3740
3903
|
const benchmarkArgs = action === "baseline" || action === "datasets" || action === "providers" || action === "runs" || action === "drift-gen" && (args[0] === "validate" || args[0] === "generate") ? args.slice(1) : args;
|
|
3741
3904
|
const benchmarks = collectBenchmarks(benchmarkArgs);
|
|
3742
3905
|
const datasetDir = readBenchOptionValue(args, "--dataset-dir") ?? readBenchOptionValue(args, "--dataset");
|
|
@@ -4286,13 +4449,13 @@ function parseBenchArgs(argv) {
|
|
|
4286
4449
|
mcpUrl,
|
|
4287
4450
|
mcpToolMap,
|
|
4288
4451
|
mcpDemo,
|
|
4289
|
-
datasetDir: datasetDir ?
|
|
4290
|
-
resultsDir: resultsDir ?
|
|
4291
|
-
baselinesDir: baselinesDir ?
|
|
4452
|
+
datasetDir: datasetDir ? path8.resolve(expandTilde(datasetDir)) : void 0,
|
|
4453
|
+
resultsDir: resultsDir ? path8.resolve(expandTilde(resultsDir)) : void 0,
|
|
4454
|
+
baselinesDir: baselinesDir ? path8.resolve(expandTilde(baselinesDir)) : void 0,
|
|
4292
4455
|
runtimeProfile,
|
|
4293
4456
|
matrixProfiles,
|
|
4294
|
-
remnicConfigPath: remnicConfigRaw ?
|
|
4295
|
-
openclawConfigPath: openclawConfigRaw ?
|
|
4457
|
+
remnicConfigPath: remnicConfigRaw ? path8.resolve(expandTilde(remnicConfigRaw)) : void 0,
|
|
4458
|
+
openclawConfigPath: openclawConfigRaw ? path8.resolve(expandTilde(openclawConfigRaw)) : void 0,
|
|
4296
4459
|
modelSource,
|
|
4297
4460
|
gatewayAgentId,
|
|
4298
4461
|
fastGatewayAgentId,
|
|
@@ -4315,13 +4478,13 @@ function parseBenchArgs(argv) {
|
|
|
4315
4478
|
internalDisableThinking: args.includes("--internal-disable-thinking"),
|
|
4316
4479
|
internalCodexReasoningEffort,
|
|
4317
4480
|
threshold,
|
|
4318
|
-
custom: customRaw ?
|
|
4481
|
+
custom: customRaw ? path8.resolve(expandTilde(customRaw)) : void 0,
|
|
4319
4482
|
baselineAction,
|
|
4320
4483
|
datasetAction,
|
|
4321
4484
|
providerAction,
|
|
4322
4485
|
runAction,
|
|
4323
4486
|
format,
|
|
4324
|
-
output: output ?
|
|
4487
|
+
output: output ? path8.resolve(expandTilde(output)) : void 0,
|
|
4325
4488
|
target,
|
|
4326
4489
|
publishedName,
|
|
4327
4490
|
publishedSeed,
|
|
@@ -4331,24 +4494,24 @@ function parseBenchArgs(argv) {
|
|
|
4331
4494
|
publishedIngestConcurrency,
|
|
4332
4495
|
publishedTaskFilter,
|
|
4333
4496
|
memcorrectAdapter,
|
|
4334
|
-
publishedOut: publishedOutRaw ?
|
|
4497
|
+
publishedOut: publishedOutRaw ? path8.resolve(expandTilde(publishedOutRaw)) : void 0,
|
|
4335
4498
|
publishedDryRun: args.includes("--dry-run"),
|
|
4336
4499
|
requestTimeout,
|
|
4337
4500
|
localJudgeRequestTimeout,
|
|
4338
4501
|
frontierJudgeRequestTimeout,
|
|
4339
|
-
calibrationDir: calibrationDirRaw ?
|
|
4502
|
+
calibrationDir: calibrationDirRaw ? path8.resolve(expandTilde(calibrationDirRaw)) : void 0,
|
|
4340
4503
|
calibrationLocalConfigSha256,
|
|
4341
4504
|
calibrationFrontierConfigSha256,
|
|
4342
4505
|
sourceResultId,
|
|
4343
4506
|
expectedAnswerSetSha256,
|
|
4344
4507
|
expectedQuestionIdListSha256,
|
|
4345
|
-
taskIdsFile: taskIdsFileRaw ?
|
|
4508
|
+
taskIdsFile: taskIdsFileRaw ? path8.resolve(expandTilde(taskIdsFileRaw)) : void 0,
|
|
4346
4509
|
expectedTaskIdListSha256,
|
|
4347
4510
|
drainTimeout,
|
|
4348
4511
|
// Issue #1573 PR1: surface judge-cache flags into the runner options.
|
|
4349
4512
|
noJudgeCache: args.includes("--no-judge-cache"),
|
|
4350
|
-
judgeCacheDir: judgeCacheDirRaw ?
|
|
4351
|
-
localLabManifestPath: localLabManifestRaw ?
|
|
4513
|
+
judgeCacheDir: judgeCacheDirRaw ? path8.resolve(expandTilde(judgeCacheDirRaw)) : void 0,
|
|
4514
|
+
localLabManifestPath: localLabManifestRaw ? path8.resolve(expandTilde(localLabManifestRaw)) : void 0,
|
|
4352
4515
|
max429WaitMs,
|
|
4353
4516
|
disableThinking: args.includes("--disable-thinking"),
|
|
4354
4517
|
amaBenchJudgeProtocol,
|
|
@@ -4386,9 +4549,9 @@ function assertCalibrationProvenanceMatches(binding, state, benchmarkId) {
|
|
|
4386
4549
|
|
|
4387
4550
|
// src/bench-status.ts
|
|
4388
4551
|
import { mkdir, readFile, readdir as readdir2, rename, writeFile } from "fs/promises";
|
|
4389
|
-
import
|
|
4552
|
+
import path9 from "path";
|
|
4390
4553
|
function createBenchStatusPath(resultsDir, pid, startedAtMs = Date.now()) {
|
|
4391
|
-
return
|
|
4554
|
+
return path9.join(resultsDir, `bench-status-${startedAtMs}-${pid}.json`);
|
|
4392
4555
|
}
|
|
4393
4556
|
var BENCH_STATUS_FILENAME = /^bench-status-\d+-\d+\.json$/;
|
|
4394
4557
|
var VALID_BENCH_ENTRY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "complete", "failed"]);
|
|
@@ -4401,7 +4564,7 @@ async function findLatestBenchStatusFile(resultsDir) {
|
|
|
4401
4564
|
}
|
|
4402
4565
|
const candidates = entries.filter((name) => BENCH_STATUS_FILENAME.test(name)).sort().reverse();
|
|
4403
4566
|
for (const name of candidates) {
|
|
4404
|
-
const filePath =
|
|
4567
|
+
const filePath = path9.join(resultsDir, name);
|
|
4405
4568
|
const status = await readBenchStatus(filePath);
|
|
4406
4569
|
if (status) {
|
|
4407
4570
|
return filePath;
|
|
@@ -4410,7 +4573,7 @@ async function findLatestBenchStatusFile(resultsDir) {
|
|
|
4410
4573
|
return null;
|
|
4411
4574
|
}
|
|
4412
4575
|
async function atomicWriteJSON(filePath, data) {
|
|
4413
|
-
await mkdir(
|
|
4576
|
+
await mkdir(path9.dirname(filePath), { recursive: true });
|
|
4414
4577
|
const tmp = `${filePath}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
|
|
4415
4578
|
await writeFile(tmp, JSON.stringify(data, null, 2) + "\n");
|
|
4416
4579
|
await rename(tmp, filePath);
|
|
@@ -4527,8 +4690,8 @@ function finalizeBenchStatus(filePath) {
|
|
|
4527
4690
|
}
|
|
4528
4691
|
|
|
4529
4692
|
// src/bench-fallback.ts
|
|
4530
|
-
import
|
|
4531
|
-
import
|
|
4693
|
+
import fs17 from "fs";
|
|
4694
|
+
import path10 from "path";
|
|
4532
4695
|
var FALLBACK_RESULTS_DIRNAME = "fallback-runs";
|
|
4533
4696
|
function buildBenchRunnerArgs(parsed, benchmarkId, outputDir) {
|
|
4534
4697
|
const args = ["--benchmark", benchmarkId];
|
|
@@ -4592,34 +4755,34 @@ function findUnsupportedFallbackBenchOptions(parsed) {
|
|
|
4592
4755
|
return unsupported;
|
|
4593
4756
|
}
|
|
4594
4757
|
function createFallbackBenchOutputDir(resultsDir, benchmarkId, pid, startedAtMs = Date.now()) {
|
|
4595
|
-
return
|
|
4758
|
+
return path10.join(
|
|
4596
4759
|
resultsDir,
|
|
4597
4760
|
FALLBACK_RESULTS_DIRNAME,
|
|
4598
4761
|
`${benchmarkId}-${startedAtMs}-${pid}`
|
|
4599
4762
|
);
|
|
4600
4763
|
}
|
|
4601
4764
|
function resolveFallbackBenchResultPath(outputDir) {
|
|
4602
|
-
const entries =
|
|
4765
|
+
const entries = fs17.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
|
|
4603
4766
|
if (entries.length === 0) {
|
|
4604
4767
|
throw new Error(`Fallback benchmark runner did not write a JSON result artifact in ${outputDir}`);
|
|
4605
4768
|
}
|
|
4606
|
-
return
|
|
4769
|
+
return path10.join(outputDir, entries[0]);
|
|
4607
4770
|
}
|
|
4608
4771
|
|
|
4609
4772
|
// src/openclaw-upgrade-swap.ts
|
|
4610
|
-
import
|
|
4611
|
-
import
|
|
4773
|
+
import fs18 from "fs";
|
|
4774
|
+
import path11 from "path";
|
|
4612
4775
|
function describeError(error) {
|
|
4613
4776
|
return error instanceof Error ? error.message : String(error);
|
|
4614
4777
|
}
|
|
4615
4778
|
function createSiblingTempFilePath(targetPath, label) {
|
|
4616
4779
|
const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
|
|
4617
|
-
return
|
|
4780
|
+
return path11.join(path11.dirname(targetPath), `.${path11.basename(targetPath)}.${label}.${nonce}.tmp`);
|
|
4618
4781
|
}
|
|
4619
4782
|
function resolveAtomicWriteMode(targetPath, explicitMode) {
|
|
4620
4783
|
if (explicitMode !== void 0) return explicitMode;
|
|
4621
4784
|
try {
|
|
4622
|
-
return
|
|
4785
|
+
return fs18.statSync(targetPath).mode & 4095;
|
|
4623
4786
|
} catch (error) {
|
|
4624
4787
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
4625
4788
|
return 384;
|
|
@@ -4629,8 +4792,8 @@ function resolveAtomicWriteMode(targetPath, explicitMode) {
|
|
|
4629
4792
|
}
|
|
4630
4793
|
function resolveAtomicReplacementPath(targetPath) {
|
|
4631
4794
|
try {
|
|
4632
|
-
if (
|
|
4633
|
-
return
|
|
4795
|
+
if (fs18.lstatSync(targetPath).isSymbolicLink()) {
|
|
4796
|
+
return fs18.realpathSync(targetPath);
|
|
4634
4797
|
}
|
|
4635
4798
|
} catch (error) {
|
|
4636
4799
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -4642,12 +4805,12 @@ function resolveAtomicReplacementPath(targetPath) {
|
|
|
4642
4805
|
}
|
|
4643
4806
|
function createSiblingSwapPath(targetDir, label) {
|
|
4644
4807
|
const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
|
|
4645
|
-
return
|
|
4808
|
+
return path11.join(path11.dirname(targetDir), `.${path11.basename(targetDir)}.${label}.${nonce}`);
|
|
4646
4809
|
}
|
|
4647
4810
|
function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
|
|
4648
4811
|
if (!displacedDir) return void 0;
|
|
4649
4812
|
try {
|
|
4650
|
-
|
|
4813
|
+
fs18.rmSync(displacedDir, { recursive: true, force: true });
|
|
4651
4814
|
return void 0;
|
|
4652
4815
|
} catch (error) {
|
|
4653
4816
|
return `Warning: ${context}, but failed to remove the displaced plugin copy at ${displacedDir}: ${describeError(error)}`;
|
|
@@ -4655,43 +4818,43 @@ function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
|
|
|
4655
4818
|
}
|
|
4656
4819
|
function atomicWriteFileSync(targetPath, data, options = {}) {
|
|
4657
4820
|
const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
|
|
4658
|
-
|
|
4821
|
+
fs18.mkdirSync(path11.dirname(resolvedTargetPath), { recursive: true });
|
|
4659
4822
|
const tempPath = createSiblingTempFilePath(resolvedTargetPath, "write");
|
|
4660
4823
|
const mode = resolveAtomicWriteMode(resolvedTargetPath, options.mode);
|
|
4661
4824
|
try {
|
|
4662
4825
|
if (options.hooks?.writeTempFileSync) {
|
|
4663
4826
|
options.hooks.writeTempFileSync(tempPath);
|
|
4664
4827
|
} else {
|
|
4665
|
-
|
|
4828
|
+
fs18.writeFileSync(tempPath, data, { mode });
|
|
4666
4829
|
}
|
|
4667
|
-
|
|
4668
|
-
const renameTempFileSync = options.hooks?.renameTempFileSync ??
|
|
4830
|
+
fs18.chmodSync(tempPath, mode);
|
|
4831
|
+
const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs18.renameSync;
|
|
4669
4832
|
renameTempFileSync(tempPath, resolvedTargetPath);
|
|
4670
4833
|
} catch (error) {
|
|
4671
|
-
|
|
4834
|
+
fs18.rmSync(tempPath, { force: true });
|
|
4672
4835
|
throw error;
|
|
4673
4836
|
}
|
|
4674
4837
|
}
|
|
4675
4838
|
function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
|
|
4676
|
-
if (!
|
|
4839
|
+
if (!fs18.existsSync(sourcePath)) return;
|
|
4677
4840
|
const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
|
|
4678
|
-
|
|
4841
|
+
fs18.mkdirSync(path11.dirname(resolvedTargetPath), { recursive: true });
|
|
4679
4842
|
const tempPath = createSiblingTempFilePath(resolvedTargetPath, "copy");
|
|
4680
|
-
const mode =
|
|
4843
|
+
const mode = fs18.statSync(sourcePath).mode & 4095;
|
|
4681
4844
|
try {
|
|
4682
|
-
const copyTempFileSync = options.hooks?.copyTempFileSync ??
|
|
4845
|
+
const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs18.copyFileSync;
|
|
4683
4846
|
copyTempFileSync(sourcePath, tempPath);
|
|
4684
|
-
|
|
4685
|
-
const renameTempFileSync = options.hooks?.renameTempFileSync ??
|
|
4847
|
+
fs18.chmodSync(tempPath, mode);
|
|
4848
|
+
const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs18.renameSync;
|
|
4686
4849
|
renameTempFileSync(tempPath, resolvedTargetPath);
|
|
4687
4850
|
} catch (error) {
|
|
4688
|
-
|
|
4851
|
+
fs18.rmSync(tempPath, { force: true });
|
|
4689
4852
|
throw error;
|
|
4690
4853
|
}
|
|
4691
4854
|
}
|
|
4692
4855
|
function cleanupRollbackDirectory(rollbackDir) {
|
|
4693
4856
|
if (!rollbackDir) return;
|
|
4694
|
-
|
|
4857
|
+
fs18.rmSync(rollbackDir, { recursive: true, force: true });
|
|
4695
4858
|
}
|
|
4696
4859
|
function cleanupRollbackDirectoryBestEffort(rollbackDir) {
|
|
4697
4860
|
if (!rollbackDir) return void 0;
|
|
@@ -4703,20 +4866,20 @@ function cleanupRollbackDirectoryBestEffort(rollbackDir) {
|
|
|
4703
4866
|
}
|
|
4704
4867
|
}
|
|
4705
4868
|
function restoreDirectoryFromRollback(targetDir, rollbackDir) {
|
|
4706
|
-
if (!
|
|
4869
|
+
if (!fs18.existsSync(rollbackDir)) {
|
|
4707
4870
|
throw new Error(`Rollback directory is missing: ${rollbackDir}`);
|
|
4708
4871
|
}
|
|
4709
|
-
|
|
4710
|
-
const displacedDir =
|
|
4872
|
+
fs18.mkdirSync(path11.dirname(targetDir), { recursive: true });
|
|
4873
|
+
const displacedDir = fs18.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
|
|
4711
4874
|
if (displacedDir) {
|
|
4712
|
-
|
|
4875
|
+
fs18.renameSync(targetDir, displacedDir);
|
|
4713
4876
|
}
|
|
4714
4877
|
try {
|
|
4715
|
-
|
|
4878
|
+
fs18.renameSync(rollbackDir, targetDir);
|
|
4716
4879
|
} catch (restoreError) {
|
|
4717
|
-
if (displacedDir &&
|
|
4880
|
+
if (displacedDir && fs18.existsSync(displacedDir)) {
|
|
4718
4881
|
try {
|
|
4719
|
-
|
|
4882
|
+
fs18.renameSync(displacedDir, targetDir);
|
|
4720
4883
|
} catch (revertError) {
|
|
4721
4884
|
throw new AggregateError(
|
|
4722
4885
|
[restoreError, revertError],
|
|
@@ -4732,23 +4895,23 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
|
|
|
4732
4895
|
return cleanupDisplacedDirectoryBestEffort(displacedDir, `restored the previous plugin copy into ${targetDir}`);
|
|
4733
4896
|
}
|
|
4734
4897
|
function restoreDirectoryFromBackup(targetDir, backupDir) {
|
|
4735
|
-
if (!
|
|
4898
|
+
if (!fs18.existsSync(backupDir)) {
|
|
4736
4899
|
throw new Error(`Plugin backup directory is missing: ${backupDir}`);
|
|
4737
4900
|
}
|
|
4738
|
-
|
|
4901
|
+
fs18.mkdirSync(path11.dirname(targetDir), { recursive: true });
|
|
4739
4902
|
const stagedDir = createSiblingSwapPath(targetDir, "backup-restore");
|
|
4740
|
-
const displacedDir =
|
|
4741
|
-
|
|
4903
|
+
const displacedDir = fs18.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
|
|
4904
|
+
fs18.cpSync(backupDir, stagedDir, { recursive: true });
|
|
4742
4905
|
if (displacedDir) {
|
|
4743
|
-
|
|
4906
|
+
fs18.renameSync(targetDir, displacedDir);
|
|
4744
4907
|
}
|
|
4745
4908
|
try {
|
|
4746
|
-
|
|
4909
|
+
fs18.renameSync(stagedDir, targetDir);
|
|
4747
4910
|
} catch (restoreError) {
|
|
4748
|
-
|
|
4749
|
-
if (displacedDir &&
|
|
4911
|
+
fs18.rmSync(targetDir, { recursive: true, force: true });
|
|
4912
|
+
if (displacedDir && fs18.existsSync(displacedDir)) {
|
|
4750
4913
|
try {
|
|
4751
|
-
|
|
4914
|
+
fs18.renameSync(displacedDir, targetDir);
|
|
4752
4915
|
} catch (revertError) {
|
|
4753
4916
|
throw new AggregateError(
|
|
4754
4917
|
[restoreError, revertError],
|
|
@@ -4756,7 +4919,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
|
|
|
4756
4919
|
);
|
|
4757
4920
|
}
|
|
4758
4921
|
}
|
|
4759
|
-
|
|
4922
|
+
fs18.rmSync(stagedDir, { recursive: true, force: true });
|
|
4760
4923
|
throw new Error(
|
|
4761
4924
|
`Failed to restore the plugin backup into ${targetDir}. The durable backup remains preserved at ${backupDir}.`,
|
|
4762
4925
|
{ cause: restoreError }
|
|
@@ -4781,7 +4944,7 @@ function rollbackOpenclawUpgrade({
|
|
|
4781
4944
|
let configRemovalAttempted = false;
|
|
4782
4945
|
let pluginRestored = false;
|
|
4783
4946
|
try {
|
|
4784
|
-
if (rollbackDir &&
|
|
4947
|
+
if (rollbackDir && fs18.existsSync(rollbackDir)) {
|
|
4785
4948
|
const cleanupWarning = restoreDirectoryFromRollback(pluginDir, rollbackDir);
|
|
4786
4949
|
notes.push(`Restored previous plugin from rollback copy at ${rollbackDir}`);
|
|
4787
4950
|
if (cleanupWarning) notes.push(cleanupWarning);
|
|
@@ -4791,7 +4954,7 @@ function rollbackOpenclawUpgrade({
|
|
|
4791
4954
|
rollbackRestoreError = error instanceof Error ? error.message : String(error);
|
|
4792
4955
|
}
|
|
4793
4956
|
try {
|
|
4794
|
-
if (!pluginRestored && pluginBackupDir &&
|
|
4957
|
+
if (!pluginRestored && pluginBackupDir && fs18.existsSync(pluginBackupDir)) {
|
|
4795
4958
|
const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
|
|
4796
4959
|
if (rollbackRestoreError) {
|
|
4797
4960
|
notes.push(`Rollback copy restore failed; restored previous plugin from durable backup at ${pluginBackupDir}`);
|
|
@@ -4816,12 +4979,12 @@ function rollbackOpenclawUpgrade({
|
|
|
4816
4979
|
notes.push("No previous plugin copy was available for automatic restore");
|
|
4817
4980
|
}
|
|
4818
4981
|
try {
|
|
4819
|
-
if (configBackupPath &&
|
|
4982
|
+
if (configBackupPath && fs18.existsSync(configBackupPath)) {
|
|
4820
4983
|
restoreFileFromBackup(configPath, configBackupPath);
|
|
4821
4984
|
notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
|
|
4822
|
-
} else if (removeConfigIfUnbacked &&
|
|
4985
|
+
} else if (removeConfigIfUnbacked && fs18.existsSync(configPath)) {
|
|
4823
4986
|
configRemovalAttempted = true;
|
|
4824
|
-
|
|
4987
|
+
fs18.rmSync(configPath, { force: true });
|
|
4825
4988
|
notes.push("Removed OpenClaw config created during the failed upgrade");
|
|
4826
4989
|
}
|
|
4827
4990
|
} catch (error) {
|
|
@@ -4874,9 +5037,9 @@ Run this manually when you're ready:
|
|
|
4874
5037
|
|
|
4875
5038
|
// src/openclaw-managed-upgrade-loader.ts
|
|
4876
5039
|
import { execFileSync } from "child_process";
|
|
4877
|
-
import
|
|
5040
|
+
import fs19 from "fs";
|
|
4878
5041
|
import os from "os";
|
|
4879
|
-
import
|
|
5042
|
+
import path12 from "path";
|
|
4880
5043
|
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "url";
|
|
4881
5044
|
var MANAGED_UPGRADE_SPECIFIER = "@remnic/plugin-openclaw/managed-upgrade";
|
|
4882
5045
|
var OPENCLAW_PLUGIN_PACKAGE = "@remnic/plugin-openclaw";
|
|
@@ -4948,9 +5111,9 @@ function buildOpenclawManagedUpgradePackageSpec(version = "latest") {
|
|
|
4948
5111
|
return `${OPENCLAW_PLUGIN_PACKAGE}@${version}`;
|
|
4949
5112
|
}
|
|
4950
5113
|
function readCliAdapterRange() {
|
|
4951
|
-
const moduleDir =
|
|
4952
|
-
const manifestPath =
|
|
4953
|
-
const manifest = JSON.parse(
|
|
5114
|
+
const moduleDir = path12.dirname(fileURLToPath3(import.meta.url));
|
|
5115
|
+
const manifestPath = path12.resolve(moduleDir, "../package.json");
|
|
5116
|
+
const manifest = JSON.parse(fs19.readFileSync(manifestPath, "utf8"));
|
|
4954
5117
|
if (manifest.name !== "@remnic/cli") {
|
|
4955
5118
|
throw new Error(`Invalid @remnic/cli package manifest at ${manifestPath}.`);
|
|
4956
5119
|
}
|
|
@@ -4994,7 +5157,7 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
4994
5157
|
const adapterMissing = isSpecifierNotFoundError(error, OPENCLAW_PLUGIN_PACKAGE) || isSpecifierNotFoundError(error, MANAGED_UPGRADE_SPECIFIER) || isManagedUpgradeSubpathMissing(error);
|
|
4995
5158
|
if (!adapterMissing) throw error;
|
|
4996
5159
|
}
|
|
4997
|
-
const temporaryRoot =
|
|
5160
|
+
const temporaryRoot = fs19.mkdtempSync(path12.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
|
|
4998
5161
|
try {
|
|
4999
5162
|
const toolingPackageSpec = `${OPENCLAW_PLUGIN_PACKAGE}@${readCliAdapterRange()}`;
|
|
5000
5163
|
const installArgs = [
|
|
@@ -5008,13 +5171,13 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
5008
5171
|
toolingPackageSpec
|
|
5009
5172
|
];
|
|
5010
5173
|
(hooks.runNpmInstall ?? runNpmInstall)(installArgs);
|
|
5011
|
-
const resolverPath =
|
|
5012
|
-
|
|
5174
|
+
const resolverPath = path12.join(temporaryRoot, "load-managed-upgrade.mjs");
|
|
5175
|
+
fs19.writeFileSync(resolverPath, `export * from ${JSON.stringify(MANAGED_UPGRADE_SPECIFIER)};
|
|
5013
5176
|
`, "utf8");
|
|
5014
5177
|
return await importModule(pathToFileURL2(resolverPath).href);
|
|
5015
5178
|
} finally {
|
|
5016
5179
|
try {
|
|
5017
|
-
|
|
5180
|
+
fs19.rmSync(temporaryRoot, { recursive: true, force: true });
|
|
5018
5181
|
} catch (error) {
|
|
5019
5182
|
const detail = error instanceof Error ? error.message : String(error);
|
|
5020
5183
|
console.warn(`Could not remove temporary managed upgrade project at ${temporaryRoot}: ${detail}`);
|
|
@@ -5023,13 +5186,13 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
|
|
|
5023
5186
|
}
|
|
5024
5187
|
|
|
5025
5188
|
// src/remote-daemon.ts
|
|
5026
|
-
import
|
|
5189
|
+
import fs20 from "fs";
|
|
5027
5190
|
function readCompatEnv(primary, legacy) {
|
|
5028
5191
|
return process.env[primary] ?? process.env[legacy];
|
|
5029
5192
|
}
|
|
5030
5193
|
function readRemnicConfigRecord(configPath) {
|
|
5031
5194
|
try {
|
|
5032
|
-
const parsed = JSON.parse(
|
|
5195
|
+
const parsed = JSON.parse(fs20.readFileSync(configPath, "utf8"));
|
|
5033
5196
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
5034
5197
|
return parsed;
|
|
5035
5198
|
}
|
|
@@ -5258,11 +5421,11 @@ async function remoteRecallXray(daemon, request) {
|
|
|
5258
5421
|
}
|
|
5259
5422
|
|
|
5260
5423
|
// src/daemon-service.ts
|
|
5261
|
-
import
|
|
5262
|
-
import
|
|
5424
|
+
import fs21 from "fs";
|
|
5425
|
+
import path13 from "path";
|
|
5263
5426
|
import * as childProcess from "child_process";
|
|
5264
5427
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5265
|
-
var thisModuleDir =
|
|
5428
|
+
var thisModuleDir = path13.dirname(fileURLToPath4(import.meta.url));
|
|
5266
5429
|
function launchdLoadPlist(plistPath, processApi = childProcess) {
|
|
5267
5430
|
processApi.execFileSync("launchctl", ["load", "-w", plistPath], { stdio: "pipe" });
|
|
5268
5431
|
}
|
|
@@ -5270,7 +5433,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
|
|
|
5270
5433
|
processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
|
|
5271
5434
|
}
|
|
5272
5435
|
function resolveServerBinDetails(options = {}) {
|
|
5273
|
-
const existsSync4 = options.existsSync ??
|
|
5436
|
+
const existsSync4 = options.existsSync ?? fs21.existsSync;
|
|
5274
5437
|
const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
|
|
5275
5438
|
const moduleDir = options.moduleDir ?? thisModuleDir;
|
|
5276
5439
|
const packageResolve = options.packageResolve ?? resolveImportSpecifier;
|
|
@@ -5284,8 +5447,8 @@ function resolveServerBinDetails(options = {}) {
|
|
|
5284
5447
|
});
|
|
5285
5448
|
} catch {
|
|
5286
5449
|
}
|
|
5287
|
-
const workspaceServerBin =
|
|
5288
|
-
const workspaceDistIndex =
|
|
5450
|
+
const workspaceServerBin = path13.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
|
|
5451
|
+
const workspaceDistIndex = path13.resolve(moduleDir, "../../remnic-server/dist/index.js");
|
|
5289
5452
|
candidates.push(
|
|
5290
5453
|
{
|
|
5291
5454
|
path: workspaceServerBin,
|
|
@@ -5306,11 +5469,11 @@ function resolveServerBinDetails(options = {}) {
|
|
|
5306
5469
|
});
|
|
5307
5470
|
}
|
|
5308
5471
|
candidates.push({
|
|
5309
|
-
path:
|
|
5472
|
+
path: path13.resolve(moduleDir, "../../remnic-server/src/index.ts"),
|
|
5310
5473
|
source: "workspace-source"
|
|
5311
5474
|
});
|
|
5312
5475
|
const selected = candidates.find((candidate) => isCandidateReady(candidate, existsSync4)) ?? candidates.find((candidate) => existsSync4(candidate.path)) ?? candidates[0] ?? {
|
|
5313
|
-
path:
|
|
5476
|
+
path: path13.resolve(moduleDir, "../../remnic-server/dist/index.js"),
|
|
5314
5477
|
source: "workspace-dist"
|
|
5315
5478
|
};
|
|
5316
5479
|
const exists = existsSync4(selected.path);
|
|
@@ -5329,8 +5492,8 @@ function resolveServerBin(options = {}) {
|
|
|
5329
5492
|
return resolveServerBinDetails(options).path;
|
|
5330
5493
|
}
|
|
5331
5494
|
function readVerifiedDaemonPid(options) {
|
|
5332
|
-
const readFileSync4 = options.readFileSync ??
|
|
5333
|
-
const unlinkSync = options.unlinkSync ??
|
|
5495
|
+
const readFileSync4 = options.readFileSync ?? fs21.readFileSync;
|
|
5496
|
+
const unlinkSync = options.unlinkSync ?? fs21.unlinkSync;
|
|
5334
5497
|
const processKill = options.processKill ?? process.kill;
|
|
5335
5498
|
const platform = options.platform ?? process.platform;
|
|
5336
5499
|
const execFileSync4 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
|
|
@@ -5365,7 +5528,7 @@ function readVerifiedDaemonPid(options) {
|
|
|
5365
5528
|
}
|
|
5366
5529
|
function doesProcessCommandLookLikeRemnicDaemon(command, expectedServerBin) {
|
|
5367
5530
|
const normalizedCommand = command.trim();
|
|
5368
|
-
const normalizedExpected =
|
|
5531
|
+
const normalizedExpected = path13.resolve(expandTilde(expectedServerBin));
|
|
5369
5532
|
return normalizedCommand.includes(normalizedExpected) || /(?:^|\s|[/\\])(?:remnic-server|engram-server)(?:\.js)?(?:\s|$)/.test(normalizedCommand) || /@remnic[/\\]server[/\\]/.test(normalizedCommand) || /packages[/\\]remnic-server[/\\](?:bin[/\\]remnic-server\.js|dist[/\\]index\.js|src[/\\]index\.ts)/.test(normalizedCommand);
|
|
5370
5533
|
}
|
|
5371
5534
|
function parseDaemonPid(raw) {
|
|
@@ -5430,8 +5593,8 @@ function removePidFileBestEffort(file, unlinkSync) {
|
|
|
5430
5593
|
}
|
|
5431
5594
|
}
|
|
5432
5595
|
function inspectLaunchdPlist(plistPath, options = {}) {
|
|
5433
|
-
const existsSync4 = options.existsSync ??
|
|
5434
|
-
const readFileSync4 = options.readFileSync ??
|
|
5596
|
+
const existsSync4 = options.existsSync ?? fs21.existsSync;
|
|
5597
|
+
const readFileSync4 = options.readFileSync ?? fs21.readFileSync;
|
|
5435
5598
|
if (!existsSync4(plistPath)) {
|
|
5436
5599
|
return {
|
|
5437
5600
|
installed: false,
|
|
@@ -5470,7 +5633,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
|
|
|
5470
5633
|
};
|
|
5471
5634
|
}
|
|
5472
5635
|
const expandedServerArg = expandTilde(serverArg);
|
|
5473
|
-
if (!
|
|
5636
|
+
if (!path13.isAbsolute(expandedServerArg)) {
|
|
5474
5637
|
return {
|
|
5475
5638
|
installed: true,
|
|
5476
5639
|
ok: false,
|
|
@@ -5542,8 +5705,8 @@ function normalizeResolvedPath(resolved) {
|
|
|
5542
5705
|
return resolved;
|
|
5543
5706
|
}
|
|
5544
5707
|
function packageServerBinFromEntry(packageEntry) {
|
|
5545
|
-
if (
|
|
5546
|
-
return
|
|
5708
|
+
if (path13.basename(packageEntry) === "index.js" && path13.basename(path13.dirname(packageEntry)) === "dist") {
|
|
5709
|
+
return path13.join(path13.dirname(path13.dirname(packageEntry)), "bin", "remnic-server.js");
|
|
5547
5710
|
}
|
|
5548
5711
|
return packageEntry;
|
|
5549
5712
|
}
|
|
@@ -5609,7 +5772,7 @@ function stripConfigArgv(args) {
|
|
|
5609
5772
|
}
|
|
5610
5773
|
|
|
5611
5774
|
// src/import-dispatch.ts
|
|
5612
|
-
import
|
|
5775
|
+
import fs22 from "fs";
|
|
5613
5776
|
import {
|
|
5614
5777
|
runImporter,
|
|
5615
5778
|
validateImportBatchSize,
|
|
@@ -5618,7 +5781,7 @@ import {
|
|
|
5618
5781
|
|
|
5619
5782
|
// src/import-bundle-detect.ts
|
|
5620
5783
|
import { lstatSync as lstatSync2, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
5621
|
-
import
|
|
5784
|
+
import path14 from "path";
|
|
5622
5785
|
function detectBundleEntries(bundleDir, options = {}) {
|
|
5623
5786
|
const readdir3 = options.readdirImpl ?? defaultReaddir;
|
|
5624
5787
|
const readFileImpl = options.readFileImpl ?? defaultReadFile;
|
|
@@ -5649,7 +5812,7 @@ function detectBundleEntries(bundleDir, options = {}) {
|
|
|
5649
5812
|
for (const filePath of roots) {
|
|
5650
5813
|
if (seenFiles.has(filePath)) continue;
|
|
5651
5814
|
seenFiles.add(filePath);
|
|
5652
|
-
const name =
|
|
5815
|
+
const name = path14.basename(filePath);
|
|
5653
5816
|
const match = classifyFile(name, filePath, readFileImpl);
|
|
5654
5817
|
if (match) entries.push(match);
|
|
5655
5818
|
}
|
|
@@ -5687,7 +5850,7 @@ function collectCandidatePaths(root, readdir3, isDirectory2, isRegularFile) {
|
|
|
5687
5850
|
return;
|
|
5688
5851
|
}
|
|
5689
5852
|
for (const entry of entries) {
|
|
5690
|
-
const full =
|
|
5853
|
+
const full = path14.join(dir, entry);
|
|
5691
5854
|
if (isDirectory2(full)) {
|
|
5692
5855
|
walk(full, depth + 1);
|
|
5693
5856
|
} else if (isRegularFile(full)) {
|
|
@@ -5766,7 +5929,8 @@ var SUPPORTED_IMPORTERS = [
|
|
|
5766
5929
|
"claude",
|
|
5767
5930
|
"gemini",
|
|
5768
5931
|
"mem0",
|
|
5769
|
-
"supermemory"
|
|
5932
|
+
"supermemory",
|
|
5933
|
+
"okf"
|
|
5770
5934
|
];
|
|
5771
5935
|
function isSupportedImporterName(value) {
|
|
5772
5936
|
return SUPPORTED_IMPORTERS.includes(value);
|
|
@@ -5824,16 +5988,16 @@ Or add it to a project:
|
|
|
5824
5988
|
}
|
|
5825
5989
|
|
|
5826
5990
|
// src/import-dispatch.ts
|
|
5827
|
-
var IMPORT_USAGE = `remnic import \u2014 Bring memory from ChatGPT, Claude, Gemini, Mem0,
|
|
5991
|
+
var IMPORT_USAGE = `remnic import \u2014 Bring memory from ChatGPT, Claude, Gemini, Mem0, Supermemory, or OKF
|
|
5828
5992
|
|
|
5829
5993
|
Usage:
|
|
5830
5994
|
remnic import --adapter <name> --file <path> [options]
|
|
5995
|
+
remnic import okf <dir> [options]
|
|
5831
5996
|
|
|
5832
5997
|
Required:
|
|
5833
5998
|
--adapter <name> One of: ${SUPPORTED_IMPORTERS.join(" | ")}
|
|
5834
|
-
--file <path> Path to a text/JSON source export
|
|
5835
|
-
|
|
5836
|
-
omitted for API-only adapters (mem0).
|
|
5999
|
+
--file <path> Path to a text/JSON source export, or an OKF directory.
|
|
6000
|
+
Archives must be unpacked first.
|
|
5837
6001
|
|
|
5838
6002
|
Options:
|
|
5839
6003
|
--dry-run Parse and transform only; do not write memories.
|
|
@@ -5849,20 +6013,17 @@ Bulk mode (slice 7):
|
|
|
5849
6013
|
mem0 exports inside <dir> and run each
|
|
5850
6014
|
matching adapter. Replaces --adapter/--file.
|
|
5851
6015
|
|
|
5852
|
-
|
|
5853
|
-
(@remnic/import-chatgpt, @remnic/import-claude, @remnic/import-gemini,
|
|
5854
|
-
@remnic/import-mem0, @remnic/import-supermemory) land in follow-up slices.
|
|
5855
|
-
Install whichever you need:
|
|
6016
|
+
Install the adapter you need:
|
|
5856
6017
|
|
|
5857
6018
|
npm install -g @remnic/import-chatgpt
|
|
5858
|
-
npm install -g @remnic/import-
|
|
5859
|
-
npm install -g @remnic/import-gemini
|
|
5860
|
-
npm install -g @remnic/import-mem0
|
|
5861
|
-
npm install -g @remnic/import-supermemory
|
|
6019
|
+
npm install -g @remnic/import-okf
|
|
5862
6020
|
`;
|
|
5863
6021
|
function parseImportArgs(rest) {
|
|
5864
6022
|
const args = [...rest];
|
|
5865
|
-
|
|
6023
|
+
let adapter = takeValue(args, "--adapter");
|
|
6024
|
+
if (!adapter && args[0] && !args[0].startsWith("--") && isSupportedImporterName(args[0])) {
|
|
6025
|
+
adapter = args.shift();
|
|
6026
|
+
}
|
|
5866
6027
|
if (!adapter) {
|
|
5867
6028
|
throw new Error(
|
|
5868
6029
|
`--adapter <name> is required. Valid values: ${SUPPORTED_IMPORTERS.join(", ")}`
|
|
@@ -5874,7 +6035,7 @@ function parseImportArgs(rest) {
|
|
|
5874
6035
|
);
|
|
5875
6036
|
}
|
|
5876
6037
|
const fileRaw = takeOptionalValue(args, "--file");
|
|
5877
|
-
|
|
6038
|
+
let file = fileRaw !== void 0 ? expandTilde(fileRaw) : void 0;
|
|
5878
6039
|
const batchSizeRaw = takeOptionalValue(args, "--batch-size");
|
|
5879
6040
|
let batchSize;
|
|
5880
6041
|
if (batchSizeRaw !== void 0) {
|
|
@@ -5899,6 +6060,9 @@ function parseImportArgs(rest) {
|
|
|
5899
6060
|
}
|
|
5900
6061
|
const dryRun = consumeFlag(args, "--dry-run");
|
|
5901
6062
|
const includeConversations = consumeFlag(args, "--include-conversations");
|
|
6063
|
+
if (file === void 0 && args[0] && !args[0].startsWith("--")) {
|
|
6064
|
+
file = expandTilde(args.shift());
|
|
6065
|
+
}
|
|
5902
6066
|
rejectLeftoverImportArgs(args, "remnic import");
|
|
5903
6067
|
return {
|
|
5904
6068
|
adapter,
|
|
@@ -5923,14 +6087,19 @@ function rejectLeftoverImportArgs(args, command) {
|
|
|
5923
6087
|
}
|
|
5924
6088
|
}
|
|
5925
6089
|
async function runImportCommand(args, io) {
|
|
5926
|
-
if (args.file && isZipFilePath(args.file)) {
|
|
6090
|
+
if (args.file && (isZipFilePath(args.file) || /\.(tgz|tar\.gz)$/i.test(args.file))) {
|
|
5927
6091
|
throw new Error(
|
|
5928
|
-
`
|
|
6092
|
+
`unpack first: archive imports are not supported ('${args.file}'). Extract the archive, then pass the directory.`
|
|
5929
6093
|
);
|
|
5930
6094
|
}
|
|
5931
6095
|
const adapter = await io.loadAdapter(args.adapter);
|
|
5932
6096
|
let input;
|
|
5933
|
-
if (args.
|
|
6097
|
+
if (args.adapter === "okf") {
|
|
6098
|
+
if (!args.file) {
|
|
6099
|
+
throw new Error("OKF import requires a directory path (remnic import okf <dir>)");
|
|
6100
|
+
}
|
|
6101
|
+
input = args.file;
|
|
6102
|
+
} else if (args.file) {
|
|
5934
6103
|
try {
|
|
5935
6104
|
input = await io.readFile(args.file);
|
|
5936
6105
|
} catch (err) {
|
|
@@ -6123,7 +6292,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
|
|
|
6123
6292
|
let materializedTarget;
|
|
6124
6293
|
let materializePromise;
|
|
6125
6294
|
const io = {
|
|
6126
|
-
readFile: ioOverrides.readFile ?? (async (p) =>
|
|
6295
|
+
readFile: ioOverrides.readFile ?? (async (p) => fs22.promises.readFile(p, "utf-8")),
|
|
6127
6296
|
loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
|
|
6128
6297
|
runImporter: ioOverrides.runImporter ?? runImporter,
|
|
6129
6298
|
getWriteTarget: async () => {
|
|
@@ -6236,8 +6405,8 @@ async function cmdCapture(rest, io) {
|
|
|
6236
6405
|
}
|
|
6237
6406
|
|
|
6238
6407
|
// src/import-lossless-claw-cmd.ts
|
|
6239
|
-
import
|
|
6240
|
-
import
|
|
6408
|
+
import fs23 from "fs";
|
|
6409
|
+
import path15 from "path";
|
|
6241
6410
|
import {
|
|
6242
6411
|
applyLcmSchema,
|
|
6243
6412
|
ensureLcmStateDir,
|
|
@@ -6348,15 +6517,15 @@ async function loadImportLosslessClawModule() {
|
|
|
6348
6517
|
|
|
6349
6518
|
// src/import-lossless-claw-cmd.ts
|
|
6350
6519
|
function assertDirectoryOrAbsent(p, label) {
|
|
6351
|
-
if (
|
|
6520
|
+
if (fs23.existsSync(p) && !fs23.statSync(p).isDirectory()) {
|
|
6352
6521
|
throw new Error(`${label} is not a directory: ${p}`);
|
|
6353
6522
|
}
|
|
6354
6523
|
}
|
|
6355
6524
|
function assertFile(p, label) {
|
|
6356
|
-
if (!
|
|
6525
|
+
if (!fs23.existsSync(p)) {
|
|
6357
6526
|
throw new Error(`${label} does not exist: ${p}`);
|
|
6358
6527
|
}
|
|
6359
|
-
if (!
|
|
6528
|
+
if (!fs23.statSync(p).isFile()) {
|
|
6360
6529
|
throw new Error(`${label} is not a file: ${p}`);
|
|
6361
6530
|
}
|
|
6362
6531
|
}
|
|
@@ -6387,8 +6556,8 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
|
|
|
6387
6556
|
let destDb;
|
|
6388
6557
|
try {
|
|
6389
6558
|
if (parsed.dryRun) {
|
|
6390
|
-
const lcmPath =
|
|
6391
|
-
if (
|
|
6559
|
+
const lcmPath = path15.join(memoryDir, "state", "lcm.sqlite");
|
|
6560
|
+
if (fs23.existsSync(lcmPath)) {
|
|
6392
6561
|
destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
|
|
6393
6562
|
} else {
|
|
6394
6563
|
destDb = mod.openInMemoryDestinationDatabase();
|
|
@@ -6509,7 +6678,7 @@ function printBenchComparisonSummary(comparison, baseline, candidate) {
|
|
|
6509
6678
|
// src/bench-coding-commands.ts
|
|
6510
6679
|
import { lstat as lstat2, readFile as readFile2, realpath, stat } from "fs/promises";
|
|
6511
6680
|
import os2 from "os";
|
|
6512
|
-
import
|
|
6681
|
+
import path16 from "path";
|
|
6513
6682
|
var UINT32_MAX = 4294967295;
|
|
6514
6683
|
var FROZEN_GENERATOR_SEED = 81;
|
|
6515
6684
|
var FROZEN_TASK_COUNT = 30;
|
|
@@ -6519,7 +6688,7 @@ var FROZEN_MAX_STEPS = 12;
|
|
|
6519
6688
|
var FROZEN_MAX_TOOL_CALLS = 8;
|
|
6520
6689
|
var FROZEN_MAX_OUTPUT_CHARS = 16384;
|
|
6521
6690
|
var MAX_OUTPUT_BYTES = 16384;
|
|
6522
|
-
var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR =
|
|
6691
|
+
var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR = path16.join(
|
|
6523
6692
|
resolveHomeDir(),
|
|
6524
6693
|
".remnic",
|
|
6525
6694
|
"bench",
|
|
@@ -6853,7 +7022,7 @@ function parseBenchCodingArgs(args) {
|
|
|
6853
7022
|
throw new Error(`unknown bench coding subcommand ${args[0]}`);
|
|
6854
7023
|
}
|
|
6855
7024
|
function normalizeCommandPaths(command) {
|
|
6856
|
-
const resolve2 = (value) =>
|
|
7025
|
+
const resolve2 = (value) => path16.resolve(expandTilde(value));
|
|
6857
7026
|
if (command.kind === "repo-generate") {
|
|
6858
7027
|
return { ...command, outputDir: resolve2(command.outputDir) };
|
|
6859
7028
|
}
|
|
@@ -6884,23 +7053,23 @@ function normalizeCommandPaths(command) {
|
|
|
6884
7053
|
return command;
|
|
6885
7054
|
}
|
|
6886
7055
|
async function canonicalProspectivePath(value) {
|
|
6887
|
-
let candidate =
|
|
7056
|
+
let candidate = path16.resolve(value);
|
|
6888
7057
|
const missingSegments = [];
|
|
6889
7058
|
while (true) {
|
|
6890
7059
|
try {
|
|
6891
|
-
return
|
|
7060
|
+
return path16.join(await realpath(candidate), ...missingSegments.reverse());
|
|
6892
7061
|
} catch (error) {
|
|
6893
7062
|
if (error.code !== "ENOENT") throw error;
|
|
6894
|
-
const parent =
|
|
7063
|
+
const parent = path16.dirname(candidate);
|
|
6895
7064
|
if (parent === candidate) throw error;
|
|
6896
|
-
missingSegments.push(
|
|
7065
|
+
missingSegments.push(path16.basename(candidate));
|
|
6897
7066
|
candidate = parent;
|
|
6898
7067
|
}
|
|
6899
7068
|
}
|
|
6900
7069
|
}
|
|
6901
7070
|
function isSameOrDescendant(candidate, root) {
|
|
6902
|
-
const relative =
|
|
6903
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
7071
|
+
const relative = path16.relative(root, candidate);
|
|
7072
|
+
return relative === "" || relative !== ".." && !relative.startsWith(`..${path16.sep}`) && !path16.isAbsolute(relative);
|
|
6904
7073
|
}
|
|
6905
7074
|
async function pathExists(value) {
|
|
6906
7075
|
try {
|
|
@@ -6919,7 +7088,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
|
|
|
6919
7088
|
const configured = process.env[variable]?.trim();
|
|
6920
7089
|
if (!configured) continue;
|
|
6921
7090
|
const memoryRoot = await canonicalProspectivePath(
|
|
6922
|
-
|
|
7091
|
+
path16.resolve(expandTilde(configured))
|
|
6923
7092
|
);
|
|
6924
7093
|
if (isSameOrDescendant(canonicalOutput, memoryRoot)) {
|
|
6925
7094
|
throw new Error(refusal);
|
|
@@ -6927,10 +7096,10 @@ async function assertSafeBenchmarkOutput(outputDir) {
|
|
|
6927
7096
|
}
|
|
6928
7097
|
let candidate = canonicalOutput;
|
|
6929
7098
|
while (true) {
|
|
6930
|
-
const hasProfile = await pathExists(
|
|
6931
|
-
const hasMemoryData = await pathExists(
|
|
7099
|
+
const hasProfile = await pathExists(path16.join(candidate, "profile.md"));
|
|
7100
|
+
const hasMemoryData = await pathExists(path16.join(candidate, "facts")) || await pathExists(path16.join(candidate, "entities")) || await pathExists(path16.join(candidate, "state"));
|
|
6932
7101
|
if (hasProfile && hasMemoryData) throw new Error(refusal);
|
|
6933
|
-
const parent =
|
|
7102
|
+
const parent = path16.dirname(candidate);
|
|
6934
7103
|
if (parent === candidate) break;
|
|
6935
7104
|
candidate = parent;
|
|
6936
7105
|
}
|
|
@@ -6942,7 +7111,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
|
|
|
6942
7111
|
async function assertH6StatsRunDirectory(runDir, commandName = "stats") {
|
|
6943
7112
|
try {
|
|
6944
7113
|
const parsed = JSON.parse(
|
|
6945
|
-
await readFile2(
|
|
7114
|
+
await readFile2(path16.join(runDir, "run.json"), "utf8")
|
|
6946
7115
|
);
|
|
6947
7116
|
if (parsed.schemaVersion !== 1 || typeof parsed.runId !== "string" || parsed.runId.length === 0 || typeof parsed.suiteVersion !== "string" || !parsed.suiteVersion.startsWith("h6-failure-gate-v1-")) {
|
|
6948
7117
|
throw new Error("invalid H6 metadata");
|
|
@@ -7001,7 +7170,7 @@ async function runRepoVerification(command, bench) {
|
|
|
7001
7170
|
if (command.directory === void 0) {
|
|
7002
7171
|
dataset = await requireFunction(bench, "loadCommittedH6BenchmarkDataset")();
|
|
7003
7172
|
} else {
|
|
7004
|
-
const serialized = await readFile2(
|
|
7173
|
+
const serialized = await readFile2(path16.join(command.directory, "dataset.json"), "utf8").catch(
|
|
7005
7174
|
() => void 0
|
|
7006
7175
|
);
|
|
7007
7176
|
if (serialized === void 0) {
|
|
@@ -7129,8 +7298,8 @@ async function cmdBenchCoding(args) {
|
|
|
7129
7298
|
}
|
|
7130
7299
|
|
|
7131
7300
|
// src/bench-security-commands.ts
|
|
7132
|
-
import
|
|
7133
|
-
var DEFAULT_OUTPUT_DIR =
|
|
7301
|
+
import path17 from "path";
|
|
7302
|
+
var DEFAULT_OUTPUT_DIR = path17.join(
|
|
7134
7303
|
resolveHomeDir(),
|
|
7135
7304
|
".remnic",
|
|
7136
7305
|
"bench",
|
|
@@ -7279,7 +7448,7 @@ ${BENCH_SECURITY_USAGE}`);
|
|
|
7279
7448
|
}
|
|
7280
7449
|
|
|
7281
7450
|
// src/bench-research-commands.ts
|
|
7282
|
-
import
|
|
7451
|
+
import path18 from "path";
|
|
7283
7452
|
function emit(result) {
|
|
7284
7453
|
if (result.output) {
|
|
7285
7454
|
console.log(result.output);
|
|
@@ -7297,7 +7466,7 @@ async function runBenchResearchCommand(parsed) {
|
|
|
7297
7466
|
emit(
|
|
7298
7467
|
await runAttributeCliCommand({
|
|
7299
7468
|
runRef: parsed.runRef,
|
|
7300
|
-
resultsDir: parsed.resultsDir ??
|
|
7469
|
+
resultsDir: parsed.resultsDir ?? path18.join(resolveHomeDir(), ".remnic", "bench", "results"),
|
|
7301
7470
|
memoryDir: parsed.memoryDir,
|
|
7302
7471
|
qmdPath: parsed.qmdPath,
|
|
7303
7472
|
collection: parsed.collection,
|
|
@@ -7567,15 +7736,15 @@ registerPublisher("hermes", () => new HermesMemoryExtensionPublisher());
|
|
|
7567
7736
|
registerPublisher("pi", () => new LazyPluginPiPublisher("pi", (mod) => mod.PiMemoryExtensionPublisher));
|
|
7568
7737
|
registerPublisher("omp", () => new LazyPluginPiPublisher("omp", (mod) => mod.OmpMemoryExtensionPublisher));
|
|
7569
7738
|
registerPublisher("prime-agent", () => new LazyPluginPiPublisher("prime-agent", (mod) => mod.PrimeAgentMemoryExtensionPublisher));
|
|
7570
|
-
var PID_DIR =
|
|
7571
|
-
var LEGACY_PID_DIR =
|
|
7572
|
-
var PID_FILE =
|
|
7573
|
-
var LEGACY_PID_FILE =
|
|
7574
|
-
var LOG_FILE =
|
|
7575
|
-
var LEGACY_LOG_FILE =
|
|
7576
|
-
var CLI_MODULE_DIR =
|
|
7577
|
-
var CLI_REPO_ROOT =
|
|
7578
|
-
var EVAL_RUNNER_PATH =
|
|
7739
|
+
var PID_DIR = path19.join(resolveHomeDir(), ".remnic");
|
|
7740
|
+
var LEGACY_PID_DIR = path19.join(resolveHomeDir(), ".engram");
|
|
7741
|
+
var PID_FILE = path19.join(PID_DIR, "server.pid");
|
|
7742
|
+
var LEGACY_PID_FILE = path19.join(LEGACY_PID_DIR, "server.pid");
|
|
7743
|
+
var LOG_FILE = path19.join(PID_DIR, "server.log");
|
|
7744
|
+
var LEGACY_LOG_FILE = path19.join(LEGACY_PID_DIR, "server.log");
|
|
7745
|
+
var CLI_MODULE_DIR = path19.dirname(fileURLToPath5(import.meta.url));
|
|
7746
|
+
var CLI_REPO_ROOT = path19.resolve(CLI_MODULE_DIR, "../../..");
|
|
7747
|
+
var EVAL_RUNNER_PATH = path19.join(CLI_REPO_ROOT, "evals", "run.ts");
|
|
7579
7748
|
var OPENCLAW_GATEWAY_LABEL = "ai.openclaw.gateway";
|
|
7580
7749
|
var CLI_SUCCESS_EXIT_GRACE_MS = 5e3;
|
|
7581
7750
|
var CLI_OUTPUT_FLUSH_GRACE_MS = 250;
|
|
@@ -7740,7 +7909,7 @@ async function resolveAllBenchmarks() {
|
|
|
7740
7909
|
if (packageBenchmarks) {
|
|
7741
7910
|
return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
|
|
7742
7911
|
}
|
|
7743
|
-
if (!
|
|
7912
|
+
if (!fs24.existsSync(EVAL_RUNNER_PATH)) {
|
|
7744
7913
|
return [];
|
|
7745
7914
|
}
|
|
7746
7915
|
return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
|
|
@@ -7788,17 +7957,17 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
|
|
|
7788
7957
|
`Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
|
|
7789
7958
|
);
|
|
7790
7959
|
}
|
|
7791
|
-
if (!
|
|
7960
|
+
if (!fs24.existsSync(EVAL_RUNNER_PATH)) {
|
|
7792
7961
|
console.error(
|
|
7793
7962
|
"Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
|
|
7794
7963
|
);
|
|
7795
7964
|
process.exit(1);
|
|
7796
7965
|
}
|
|
7797
7966
|
const tsxCandidates = [
|
|
7798
|
-
|
|
7799
|
-
|
|
7967
|
+
path19.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
|
|
7968
|
+
path19.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
|
|
7800
7969
|
];
|
|
7801
|
-
const tsxCmd = tsxCandidates.find((candidate) =>
|
|
7970
|
+
const tsxCmd = tsxCandidates.find((candidate) => fs24.existsSync(candidate)) ?? "tsx";
|
|
7802
7971
|
const fallbackOutputDir = createFallbackBenchOutputDir(
|
|
7803
7972
|
parsed.resultsDir ?? resolveBenchOutputDir(),
|
|
7804
7973
|
benchmarkId,
|
|
@@ -7815,7 +7984,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
|
|
|
7815
7984
|
return resolveFallbackBenchResultPath(fallbackOutputDir);
|
|
7816
7985
|
}
|
|
7817
7986
|
function resolveBenchOutputDir() {
|
|
7818
|
-
return
|
|
7987
|
+
return path19.join(resolveHomeDir(), ".remnic", "bench", "results");
|
|
7819
7988
|
}
|
|
7820
7989
|
var DOWNLOADABLE_BENCHMARK_DATASETS = [
|
|
7821
7990
|
"ama-bench",
|
|
@@ -7860,8 +8029,8 @@ var MEMORY_AGENT_BENCH_SPLIT_FILENAMES = [
|
|
|
7860
8029
|
];
|
|
7861
8030
|
var MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES = [
|
|
7862
8031
|
"entity2id.json",
|
|
7863
|
-
|
|
7864
|
-
|
|
8032
|
+
path19.join("processed_data", "Recsys_Redial", "entity2id.json"),
|
|
8033
|
+
path19.join("Recsys_Redial", "entity2id.json")
|
|
7865
8034
|
];
|
|
7866
8035
|
var DOWNLOADED_DATASET_MARKERS = {
|
|
7867
8036
|
"ama-bench": { anyOf: ["open_end_qa_set.jsonl"] },
|
|
@@ -7936,18 +8105,18 @@ var PERSONAMEM_DATASET_FILE_CANDIDATES = [
|
|
|
7936
8105
|
"benchmark/benchmark.csv",
|
|
7937
8106
|
"benchmark.csv"
|
|
7938
8107
|
];
|
|
7939
|
-
var PERSONAMEM_COMPLETION_MARKER =
|
|
8108
|
+
var PERSONAMEM_COMPLETION_MARKER = path19.join(
|
|
7940
8109
|
"data",
|
|
7941
8110
|
"chat_history_32k",
|
|
7942
8111
|
".download-complete"
|
|
7943
8112
|
);
|
|
7944
8113
|
function resolveRealpathWithinDataset(datasetPath, relativePath) {
|
|
7945
8114
|
try {
|
|
7946
|
-
const datasetRoot =
|
|
7947
|
-
const candidatePath =
|
|
7948
|
-
const candidateRealPath =
|
|
7949
|
-
const relativeToRoot =
|
|
7950
|
-
if (relativeToRoot.startsWith("..") ||
|
|
8115
|
+
const datasetRoot = fs24.realpathSync(datasetPath);
|
|
8116
|
+
const candidatePath = path19.resolve(datasetRoot, relativePath);
|
|
8117
|
+
const candidateRealPath = fs24.realpathSync(candidatePath);
|
|
8118
|
+
const relativeToRoot = path19.relative(datasetRoot, candidateRealPath);
|
|
8119
|
+
if (relativeToRoot.startsWith("..") || path19.isAbsolute(relativeToRoot)) {
|
|
7951
8120
|
return null;
|
|
7952
8121
|
}
|
|
7953
8122
|
return candidateRealPath;
|
|
@@ -8003,15 +8172,15 @@ function parseCsvRows(raw) {
|
|
|
8003
8172
|
}
|
|
8004
8173
|
function isPersonaMemDatasetComplete(datasetPath) {
|
|
8005
8174
|
try {
|
|
8006
|
-
const completionMarkerPath =
|
|
8007
|
-
if (
|
|
8175
|
+
const completionMarkerPath = path19.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
|
|
8176
|
+
if (fs24.statSync(completionMarkerPath).isFile()) {
|
|
8008
8177
|
return true;
|
|
8009
8178
|
}
|
|
8010
8179
|
} catch {
|
|
8011
8180
|
}
|
|
8012
8181
|
const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
|
|
8013
8182
|
try {
|
|
8014
|
-
return
|
|
8183
|
+
return fs24.statSync(path19.join(datasetPath, candidate)).isFile();
|
|
8015
8184
|
} catch {
|
|
8016
8185
|
return false;
|
|
8017
8186
|
}
|
|
@@ -8020,7 +8189,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
8020
8189
|
return false;
|
|
8021
8190
|
}
|
|
8022
8191
|
try {
|
|
8023
|
-
const rows = parseCsvRows(
|
|
8192
|
+
const rows = parseCsvRows(fs24.readFileSync(path19.join(datasetPath, datasetFile), "utf8"));
|
|
8024
8193
|
if (rows.length < 2) {
|
|
8025
8194
|
return false;
|
|
8026
8195
|
}
|
|
@@ -8035,7 +8204,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
8035
8204
|
}
|
|
8036
8205
|
return historyPaths.every((relativePath) => {
|
|
8037
8206
|
const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
|
|
8038
|
-
return resolvedPath !== null &&
|
|
8207
|
+
return resolvedPath !== null && fs24.statSync(resolvedPath).isFile();
|
|
8039
8208
|
});
|
|
8040
8209
|
} catch {
|
|
8041
8210
|
return false;
|
|
@@ -8043,14 +8212,14 @@ function isPersonaMemDatasetComplete(datasetPath) {
|
|
|
8043
8212
|
}
|
|
8044
8213
|
function hasDatasetFile(datasetPath, relativePath) {
|
|
8045
8214
|
try {
|
|
8046
|
-
return
|
|
8215
|
+
return fs24.statSync(path19.join(datasetPath, relativePath)).isFile();
|
|
8047
8216
|
} catch {
|
|
8048
8217
|
return false;
|
|
8049
8218
|
}
|
|
8050
8219
|
}
|
|
8051
8220
|
function hasMemoryAgentBenchEntityMapping(datasetPath) {
|
|
8052
|
-
const absoluteDatasetPath =
|
|
8053
|
-
const roots = [absoluteDatasetPath,
|
|
8221
|
+
const absoluteDatasetPath = path19.resolve(datasetPath);
|
|
8222
|
+
const roots = [absoluteDatasetPath, path19.dirname(absoluteDatasetPath)];
|
|
8054
8223
|
return hasDatasetFile(absoluteDatasetPath, "entity2id.json") || roots.some(
|
|
8055
8224
|
(root) => MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES.filter((relativePath) => relativePath !== "entity2id.json").some((relativePath) => hasDatasetFile(root, relativePath))
|
|
8056
8225
|
);
|
|
@@ -8061,12 +8230,12 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
|
|
|
8061
8230
|
...MEMORY_AGENT_BENCH_SPLIT_FILENAMES
|
|
8062
8231
|
];
|
|
8063
8232
|
return candidateFilenames.some((filename) => {
|
|
8064
|
-
const filePath =
|
|
8233
|
+
const filePath = path19.join(datasetPath, filename);
|
|
8065
8234
|
try {
|
|
8066
|
-
if (!
|
|
8235
|
+
if (!fs24.statSync(filePath).isFile()) {
|
|
8067
8236
|
return false;
|
|
8068
8237
|
}
|
|
8069
|
-
const raw =
|
|
8238
|
+
const raw = fs24.readFileSync(filePath, "utf8");
|
|
8070
8239
|
return /"source"\s*:\s*"recsys[_-]/i.test(raw);
|
|
8071
8240
|
} catch {
|
|
8072
8241
|
return false;
|
|
@@ -8082,7 +8251,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
|
|
|
8082
8251
|
function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
8083
8252
|
let stats;
|
|
8084
8253
|
try {
|
|
8085
|
-
stats =
|
|
8254
|
+
stats = fs24.statSync(datasetPath);
|
|
8086
8255
|
} catch {
|
|
8087
8256
|
return false;
|
|
8088
8257
|
}
|
|
@@ -8092,7 +8261,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8092
8261
|
const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
|
|
8093
8262
|
if (!marker) {
|
|
8094
8263
|
try {
|
|
8095
|
-
return
|
|
8264
|
+
return fs24.readdirSync(datasetPath).length > 0;
|
|
8096
8265
|
} catch {
|
|
8097
8266
|
return false;
|
|
8098
8267
|
}
|
|
@@ -8100,7 +8269,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8100
8269
|
if (marker.allOf) {
|
|
8101
8270
|
const hasAllRequiredFiles = marker.allOf.every((name) => {
|
|
8102
8271
|
try {
|
|
8103
|
-
return
|
|
8272
|
+
return fs24.statSync(path19.join(datasetPath, name)).isFile();
|
|
8104
8273
|
} catch {
|
|
8105
8274
|
return false;
|
|
8106
8275
|
}
|
|
@@ -8112,7 +8281,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8112
8281
|
if (marker.anyOf) {
|
|
8113
8282
|
const hasMarkerFile = marker.anyOf.some((name) => {
|
|
8114
8283
|
try {
|
|
8115
|
-
return
|
|
8284
|
+
return fs24.statSync(path19.join(datasetPath, name)).isFile();
|
|
8116
8285
|
} catch {
|
|
8117
8286
|
return false;
|
|
8118
8287
|
}
|
|
@@ -8130,7 +8299,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8130
8299
|
}
|
|
8131
8300
|
if (marker.ext) {
|
|
8132
8301
|
try {
|
|
8133
|
-
return
|
|
8302
|
+
return fs24.readdirSync(datasetPath).some(
|
|
8134
8303
|
(name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
|
|
8135
8304
|
);
|
|
8136
8305
|
} catch {
|
|
@@ -8140,9 +8309,9 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
|
|
|
8140
8309
|
return false;
|
|
8141
8310
|
}
|
|
8142
8311
|
async function launchBenchUi(resultsDir) {
|
|
8143
|
-
const benchUiDir =
|
|
8312
|
+
const benchUiDir = path19.join(CLI_REPO_ROOT, "packages", "bench-ui");
|
|
8144
8313
|
const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
8145
|
-
if (!
|
|
8314
|
+
if (!fs24.existsSync(path19.join(benchUiDir, "package.json"))) {
|
|
8146
8315
|
console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
|
|
8147
8316
|
process.exit(1);
|
|
8148
8317
|
}
|
|
@@ -8169,24 +8338,24 @@ async function launchBenchUi(resultsDir) {
|
|
|
8169
8338
|
});
|
|
8170
8339
|
}
|
|
8171
8340
|
function resolveRepoDatasetRoot() {
|
|
8172
|
-
const repoCandidate =
|
|
8341
|
+
const repoCandidate = path19.join(CLI_REPO_ROOT, "evals", "datasets");
|
|
8173
8342
|
if (isRepoCheckout()) {
|
|
8174
8343
|
return repoCandidate;
|
|
8175
8344
|
}
|
|
8176
|
-
return
|
|
8345
|
+
return path19.join(resolveHomeDir(), ".remnic", "bench", "datasets");
|
|
8177
8346
|
}
|
|
8178
8347
|
function listDownloadableBenchmarks() {
|
|
8179
8348
|
return [...DOWNLOADABLE_BENCHMARK_DATASETS];
|
|
8180
8349
|
}
|
|
8181
8350
|
function resolveDatasetDownloadScriptPath() {
|
|
8182
|
-
const bundled =
|
|
8183
|
-
if (
|
|
8351
|
+
const bundled = path19.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
|
|
8352
|
+
if (fs24.existsSync(bundled)) {
|
|
8184
8353
|
return bundled;
|
|
8185
8354
|
}
|
|
8186
|
-
return
|
|
8355
|
+
return path19.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
|
|
8187
8356
|
}
|
|
8188
8357
|
function isRepoCheckout() {
|
|
8189
|
-
return
|
|
8358
|
+
return fs24.existsSync(path19.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs24.existsSync(path19.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
|
|
8190
8359
|
}
|
|
8191
8360
|
function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
|
|
8192
8361
|
const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
|
|
@@ -8237,7 +8406,7 @@ function resolveBenchDatasetDir(benchmarkId, quick, datasetDirOverride) {
|
|
|
8237
8406
|
if (quick) {
|
|
8238
8407
|
return void 0;
|
|
8239
8408
|
}
|
|
8240
|
-
const datasetDir =
|
|
8409
|
+
const datasetDir = path19.join(resolveRepoDatasetRoot(), benchmarkId);
|
|
8241
8410
|
if (isDatasetDownloaded(datasetDir, benchmarkId)) {
|
|
8242
8411
|
return datasetDir;
|
|
8243
8412
|
}
|
|
@@ -8494,13 +8663,13 @@ async function exportBenchPackageResult(parsed) {
|
|
|
8494
8663
|
process.exit(1);
|
|
8495
8664
|
}
|
|
8496
8665
|
const result = await loadBenchmarkResult(summary.path);
|
|
8497
|
-
const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(
|
|
8666
|
+
const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path19.dirname(summary.path), result.meta.id) : void 0;
|
|
8498
8667
|
const rendered = renderBenchmarkResultExport(result, parsed.format, {
|
|
8499
8668
|
...reportCardProvenance ? { reportCardProvenance } : {}
|
|
8500
8669
|
});
|
|
8501
8670
|
if (parsed.output) {
|
|
8502
|
-
|
|
8503
|
-
|
|
8671
|
+
fs24.mkdirSync(path19.dirname(parsed.output), { recursive: true });
|
|
8672
|
+
fs24.writeFileSync(parsed.output, rendered);
|
|
8504
8673
|
console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
|
|
8505
8674
|
return;
|
|
8506
8675
|
}
|
|
@@ -8517,7 +8686,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8517
8686
|
process.exit(1);
|
|
8518
8687
|
}
|
|
8519
8688
|
const status = supported.map((benchmarkId) => {
|
|
8520
|
-
const datasetPath =
|
|
8689
|
+
const datasetPath = path19.join(datasetRoot, benchmarkId);
|
|
8521
8690
|
return {
|
|
8522
8691
|
benchmark: benchmarkId,
|
|
8523
8692
|
downloaded: isDatasetDownloaded(datasetPath, benchmarkId),
|
|
@@ -8545,7 +8714,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8545
8714
|
process.exit(1);
|
|
8546
8715
|
}
|
|
8547
8716
|
const scriptPath = resolveDatasetDownloadScriptPath();
|
|
8548
|
-
if (!
|
|
8717
|
+
if (!fs24.existsSync(scriptPath)) {
|
|
8549
8718
|
console.error(`ERROR: dataset download script not found: ${scriptPath}`);
|
|
8550
8719
|
process.exit(1);
|
|
8551
8720
|
}
|
|
@@ -8555,7 +8724,7 @@ async function manageBenchDatasets(parsed) {
|
|
|
8555
8724
|
runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, parsed.json === true);
|
|
8556
8725
|
downloaded.push({
|
|
8557
8726
|
benchmark: benchmarkId,
|
|
8558
|
-
path:
|
|
8727
|
+
path: path19.join(datasetRoot, benchmarkId)
|
|
8559
8728
|
});
|
|
8560
8729
|
}
|
|
8561
8730
|
if (parsed.json) {
|
|
@@ -8694,10 +8863,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
8694
8863
|
}
|
|
8695
8864
|
const bench = await loadBenchModule();
|
|
8696
8865
|
const resultsDir = expandTilde(
|
|
8697
|
-
parsed.resultsDir ??
|
|
8866
|
+
parsed.resultsDir ?? path19.join(resolveHomeDir(), ".remnic", "bench", "results")
|
|
8698
8867
|
);
|
|
8699
8868
|
const calibrationDir = expandTilde(
|
|
8700
|
-
parsed.calibrationDir ??
|
|
8869
|
+
parsed.calibrationDir ?? path19.join(resolveHomeDir(), ".remnic", "bench", "calibration")
|
|
8701
8870
|
);
|
|
8702
8871
|
const stored = await bench.listBenchmarkResults(resultsDir);
|
|
8703
8872
|
const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
|
|
@@ -8745,7 +8914,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
|
|
|
8745
8914
|
);
|
|
8746
8915
|
process.exit(1);
|
|
8747
8916
|
}
|
|
8748
|
-
const sourceResultSha256 = createHash4("sha256").update(
|
|
8917
|
+
const sourceResultSha256 = createHash4("sha256").update(fs24.readFileSync(latest.path)).digest("hex");
|
|
8749
8918
|
const expandedManifestPath = expandTilde(manifestPath);
|
|
8750
8919
|
if (!bench.resolveLocalLabJudgeProviderConfig) {
|
|
8751
8920
|
console.error(
|
|
@@ -9160,7 +9329,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
|
|
|
9160
9329
|
}
|
|
9161
9330
|
let decoded;
|
|
9162
9331
|
try {
|
|
9163
|
-
decoded = JSON.parse(
|
|
9332
|
+
decoded = JSON.parse(fs24.readFileSync(parsed.taskIdsFile, "utf8"));
|
|
9164
9333
|
} catch (error) {
|
|
9165
9334
|
throw new Error(
|
|
9166
9335
|
`Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -9257,7 +9426,7 @@ async function loadPublishedPromotionHelpers() {
|
|
|
9257
9426
|
return {
|
|
9258
9427
|
async promoteArtifactsToPublished(args) {
|
|
9259
9428
|
const { mkdirSync, readFileSync: readFileSync4, writeFileSync } = await import("fs");
|
|
9260
|
-
const
|
|
9429
|
+
const path20 = await import("path");
|
|
9261
9430
|
mkdirSync(args.publishedOutDir, { recursive: true });
|
|
9262
9431
|
if (args.artifactPaths.length === 0) {
|
|
9263
9432
|
console.warn(
|
|
@@ -9274,13 +9443,13 @@ async function loadPublishedPromotionHelpers() {
|
|
|
9274
9443
|
const modelSlug = args.model.replace(/[^a-zA-Z0-9_.-]/g, "-");
|
|
9275
9444
|
const rawProfile = parsedObj.config?.runtimeProfile;
|
|
9276
9445
|
const profileSlug = typeof rawProfile === "string" && rawProfile.length > 0 ? `-${rawProfile.replace(/[^a-zA-Z0-9_.-]/g, "-")}` : "";
|
|
9277
|
-
const target =
|
|
9446
|
+
const target = path20.join(
|
|
9278
9447
|
args.publishedOutDir,
|
|
9279
9448
|
`${today}-${args.benchmarkId}-${modelSlug}${profileSlug}-${gitShaShort}.json`
|
|
9280
9449
|
);
|
|
9281
9450
|
writeFileSync(target, raw, "utf8");
|
|
9282
9451
|
console.log(
|
|
9283
|
-
`[bench published] Promoted ${
|
|
9452
|
+
`[bench published] Promoted ${path20.basename(artifactPath)} \u2192 ${target}`
|
|
9284
9453
|
);
|
|
9285
9454
|
}
|
|
9286
9455
|
void benchModule;
|
|
@@ -9387,7 +9556,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
|
|
|
9387
9556
|
const previousCodexDiagnosticsDir = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV];
|
|
9388
9557
|
const previousCodexDiagnosticsMode = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_MODE_ENV];
|
|
9389
9558
|
if (!previousCodexDiagnosticsDir) {
|
|
9390
|
-
process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] =
|
|
9559
|
+
process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path19.join(
|
|
9391
9560
|
outputDir,
|
|
9392
9561
|
"codex-cli-diagnostics"
|
|
9393
9562
|
);
|
|
@@ -9537,7 +9706,7 @@ async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmark
|
|
|
9537
9706
|
);
|
|
9538
9707
|
}
|
|
9539
9708
|
const calibrationDir = expandTilde(
|
|
9540
|
-
calibrationBinding.calibrationDir ??
|
|
9709
|
+
calibrationBinding.calibrationDir ?? path19.join(resolveHomeDir(), ".remnic", "bench", "calibration")
|
|
9541
9710
|
);
|
|
9542
9711
|
const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
|
|
9543
9712
|
if (!state) {
|
|
@@ -9835,7 +10004,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
|
|
|
9835
10004
|
return void 0;
|
|
9836
10005
|
}
|
|
9837
10006
|
try {
|
|
9838
|
-
return
|
|
10007
|
+
return fs24.realpathSync(datasetDir);
|
|
9839
10008
|
} catch {
|
|
9840
10009
|
return datasetDir;
|
|
9841
10010
|
}
|
|
@@ -9889,13 +10058,13 @@ async function writeBenchReproManifestForPackageRun(args) {
|
|
|
9889
10058
|
}
|
|
9890
10059
|
function loadStandaloneConvergeCommandConfig() {
|
|
9891
10060
|
const configPath = resolveConfigPath();
|
|
9892
|
-
const raw =
|
|
9893
|
-
return
|
|
10061
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
10062
|
+
return parseConfig15(resolveRemnicConfigRecord14(raw));
|
|
9894
10063
|
}
|
|
9895
10064
|
function parseConvergePluginConfig(value) {
|
|
9896
10065
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
9897
10066
|
if (Object.keys(value).length === 0) return void 0;
|
|
9898
|
-
return
|
|
10067
|
+
return parseConfig15(resolveRemnicConfigRecord14(value));
|
|
9899
10068
|
}
|
|
9900
10069
|
function loadConvergeCommandConfig() {
|
|
9901
10070
|
if (readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH")) {
|
|
@@ -9908,23 +10077,23 @@ function loadConvergeCommandConfig() {
|
|
|
9908
10077
|
return loadStandaloneConvergeCommandConfig();
|
|
9909
10078
|
}
|
|
9910
10079
|
function resolveConfigPath(cliPath) {
|
|
9911
|
-
if (cliPath) return
|
|
10080
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
9912
10081
|
const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
|
|
9913
|
-
if (envPath) return
|
|
10082
|
+
if (envPath) return path19.resolve(expandTilde(envPath));
|
|
9914
10083
|
const candidates = [
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
10084
|
+
path19.join(process.cwd(), "remnic.config.json"),
|
|
10085
|
+
path19.join(process.cwd(), "engram.config.json"),
|
|
10086
|
+
path19.join(resolveHomeDir(), ".config", "remnic", "config.json"),
|
|
10087
|
+
path19.join(resolveHomeDir(), ".config", "engram", "config.json")
|
|
9919
10088
|
];
|
|
9920
10089
|
for (const candidate of candidates) {
|
|
9921
|
-
if (
|
|
10090
|
+
if (fs24.existsSync(candidate)) return candidate;
|
|
9922
10091
|
}
|
|
9923
|
-
return
|
|
10092
|
+
return path19.join(resolveHomeDir(), ".config", "remnic", "config.json");
|
|
9924
10093
|
}
|
|
9925
10094
|
function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
9926
10095
|
const configPath = resolveConfigPath(cliPath);
|
|
9927
|
-
if (
|
|
10096
|
+
if (fs24.existsSync(configPath)) {
|
|
9928
10097
|
return configPath;
|
|
9929
10098
|
}
|
|
9930
10099
|
if (cliPath) {
|
|
@@ -9934,7 +10103,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
|
9934
10103
|
}
|
|
9935
10104
|
function resolveExistingBenchOpenclawConfigPath(cliPath) {
|
|
9936
10105
|
const configPath = resolveOpenclawConfigPath(cliPath);
|
|
9937
|
-
if (
|
|
10106
|
+
if (fs24.existsSync(configPath)) {
|
|
9938
10107
|
return configPath;
|
|
9939
10108
|
}
|
|
9940
10109
|
if (cliPath) {
|
|
@@ -10034,34 +10203,34 @@ async function resolvePackageBenchRuntime(benchModule, parsed, runtimeProfile) {
|
|
|
10034
10203
|
);
|
|
10035
10204
|
}
|
|
10036
10205
|
function normalizeMemoryDirPath(memoryDir) {
|
|
10037
|
-
return
|
|
10206
|
+
return path19.resolve(expandTilde(memoryDir));
|
|
10038
10207
|
}
|
|
10039
10208
|
function resolveMemoryDir() {
|
|
10040
10209
|
const configMemoryDir = (() => {
|
|
10041
10210
|
const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
|
|
10042
10211
|
if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
|
|
10043
10212
|
const configPath = resolveConfigPath();
|
|
10044
|
-
const raw =
|
|
10045
|
-
const remnicCfg =
|
|
10213
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
10214
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
10046
10215
|
if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
|
|
10047
10216
|
return normalizeMemoryDirPath(remnicCfg.memoryDir);
|
|
10048
10217
|
}
|
|
10049
10218
|
const home = resolveHomeDir();
|
|
10050
|
-
const standalonePath =
|
|
10051
|
-
const legacyStandalonePath =
|
|
10052
|
-
const openclawPath =
|
|
10053
|
-
if (
|
|
10054
|
-
if (
|
|
10219
|
+
const standalonePath = path19.join(home, ".remnic", "memory");
|
|
10220
|
+
const legacyStandalonePath = path19.join(home, ".engram", "memory");
|
|
10221
|
+
const openclawPath = path19.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
10222
|
+
if (fs24.existsSync(standalonePath)) return standalonePath;
|
|
10223
|
+
if (fs24.existsSync(legacyStandalonePath)) return legacyStandalonePath;
|
|
10055
10224
|
return openclawPath;
|
|
10056
10225
|
})();
|
|
10057
10226
|
const manifestPath = getManifestPath();
|
|
10058
|
-
if (
|
|
10227
|
+
if (fs24.existsSync(manifestPath)) {
|
|
10059
10228
|
try {
|
|
10060
10229
|
const active = getActiveSpace();
|
|
10061
10230
|
if (active?.memoryDir) {
|
|
10062
10231
|
const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
|
|
10063
|
-
if (!
|
|
10064
|
-
|
|
10232
|
+
if (!fs24.existsSync(activeMemoryDir)) {
|
|
10233
|
+
fs24.mkdirSync(activeMemoryDir, { recursive: true });
|
|
10065
10234
|
}
|
|
10066
10235
|
return activeMemoryDir;
|
|
10067
10236
|
}
|
|
@@ -10098,25 +10267,25 @@ function resolveFlagStrict(args, flag) {
|
|
|
10098
10267
|
var REMNIC_OPENCLAW_LEGACY_PLUGIN_ID = "openclaw-engram";
|
|
10099
10268
|
function resolveOpenclawStateDir() {
|
|
10100
10269
|
const configuredStateDir = process.env.OPENCLAW_STATE_DIR?.trim();
|
|
10101
|
-
return configuredStateDir ?
|
|
10270
|
+
return configuredStateDir ? path19.resolve(expandTilde(configuredStateDir)) : path19.join(resolveHomeDir(), ".openclaw");
|
|
10102
10271
|
}
|
|
10103
10272
|
var DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR = [
|
|
10104
10273
|
process.env.OPENCLAW_CONFIG_PATH,
|
|
10105
10274
|
process.env.OPENCLAW_ENGRAM_CONFIG_PATH,
|
|
10106
|
-
|
|
10275
|
+
path19.join(resolveOpenclawStateDir(), "openclaw.json")
|
|
10107
10276
|
].filter(Boolean);
|
|
10108
10277
|
function resolveOpenclawConfigPath(cliPath) {
|
|
10109
|
-
if (cliPath) return
|
|
10278
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
10110
10279
|
const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
|
|
10111
|
-
if (envPath) return
|
|
10280
|
+
if (envPath) return path19.resolve(expandTilde(envPath));
|
|
10112
10281
|
for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
|
|
10113
|
-
if (
|
|
10282
|
+
if (fs24.existsSync(candidate)) return candidate;
|
|
10114
10283
|
}
|
|
10115
|
-
return
|
|
10284
|
+
return path19.join(resolveOpenclawStateDir(), "openclaw.json");
|
|
10116
10285
|
}
|
|
10117
10286
|
function readOpenclawConfig(configPath) {
|
|
10118
|
-
if (!
|
|
10119
|
-
const raw =
|
|
10287
|
+
if (!fs24.existsSync(configPath)) return {};
|
|
10288
|
+
const raw = fs24.readFileSync(configPath, "utf-8");
|
|
10120
10289
|
let parsed;
|
|
10121
10290
|
try {
|
|
10122
10291
|
parsed = JSON.parse(raw);
|
|
@@ -10171,10 +10340,10 @@ function buildRemnicOpenclawHooksPolicy(legacyHooks, existingHooks) {
|
|
|
10171
10340
|
function resolveOpenclawInstallMemoryDir(args) {
|
|
10172
10341
|
const existingMemoryDir = (typeof args.existingNewEntryConfig.memoryDir === "string" ? args.existingNewEntryConfig.memoryDir : void 0) || (args.migrateLegacy && typeof args.legacyConfigToMerge.memoryDir === "string" ? args.legacyConfigToMerge.memoryDir : void 0);
|
|
10173
10342
|
if (args.requestedMemoryDir) {
|
|
10174
|
-
return
|
|
10343
|
+
return path19.resolve(expandTilde(args.requestedMemoryDir));
|
|
10175
10344
|
}
|
|
10176
10345
|
if (existingMemoryDir) {
|
|
10177
|
-
return
|
|
10346
|
+
return path19.resolve(expandTilde(existingMemoryDir));
|
|
10178
10347
|
}
|
|
10179
10348
|
return args.fallbackMemoryDir;
|
|
10180
10349
|
}
|
|
@@ -10192,21 +10361,21 @@ function resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir) {
|
|
|
10192
10361
|
if (!config || typeof config !== "object" || Array.isArray(config)) continue;
|
|
10193
10362
|
const memoryDir = config.memoryDir;
|
|
10194
10363
|
if (typeof memoryDir === "string" && memoryDir.trim().length > 0) {
|
|
10195
|
-
return
|
|
10364
|
+
return path19.resolve(expandTilde(memoryDir));
|
|
10196
10365
|
}
|
|
10197
10366
|
}
|
|
10198
10367
|
return fallbackMemoryDir;
|
|
10199
10368
|
}
|
|
10200
10369
|
function resolveOpenclawPluginDir(cliPath) {
|
|
10201
|
-
if (cliPath) return
|
|
10370
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
10202
10371
|
return resolveOpenclawManagedPluginDir();
|
|
10203
10372
|
}
|
|
10204
10373
|
function resolveOpenclawManagedPluginDir() {
|
|
10205
|
-
return
|
|
10374
|
+
return path19.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
|
|
10206
10375
|
}
|
|
10207
10376
|
function resolveOpenclawLegacyPluginDir(cliPath) {
|
|
10208
|
-
if (cliPath) return
|
|
10209
|
-
return
|
|
10377
|
+
if (cliPath) return path19.resolve(expandTilde(cliPath));
|
|
10378
|
+
return path19.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
|
|
10210
10379
|
}
|
|
10211
10380
|
function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
|
|
10212
10381
|
const yyyy = now.getFullYear().toString();
|
|
@@ -10218,9 +10387,9 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
|
|
|
10218
10387
|
return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
|
|
10219
10388
|
}
|
|
10220
10389
|
function backupPathIfPresent(sourcePath, backupPath) {
|
|
10221
|
-
if (!
|
|
10222
|
-
|
|
10223
|
-
|
|
10390
|
+
if (!fs24.existsSync(sourcePath)) return false;
|
|
10391
|
+
fs24.mkdirSync(path19.dirname(backupPath), { recursive: true });
|
|
10392
|
+
fs24.cpSync(sourcePath, backupPath, { recursive: true });
|
|
10224
10393
|
return true;
|
|
10225
10394
|
}
|
|
10226
10395
|
function restartOpenclawGateway() {
|
|
@@ -10238,15 +10407,15 @@ function restartOpenclawGateway() {
|
|
|
10238
10407
|
});
|
|
10239
10408
|
}
|
|
10240
10409
|
function cmdInit() {
|
|
10241
|
-
const configPath =
|
|
10242
|
-
if (
|
|
10410
|
+
const configPath = path19.join(process.cwd(), "remnic.config.json");
|
|
10411
|
+
if (fs24.existsSync(configPath)) {
|
|
10243
10412
|
console.log(`Config already exists: ${configPath}`);
|
|
10244
10413
|
return;
|
|
10245
10414
|
}
|
|
10246
10415
|
const template = {
|
|
10247
10416
|
remnic: {
|
|
10248
10417
|
openaiApiKey: "${OPENAI_API_KEY}",
|
|
10249
|
-
memoryDir:
|
|
10418
|
+
memoryDir: path19.join(process.cwd(), ".remnic", "memory"),
|
|
10250
10419
|
memoryOsPreset: "balanced"
|
|
10251
10420
|
},
|
|
10252
10421
|
server: {
|
|
@@ -10255,7 +10424,7 @@ function cmdInit() {
|
|
|
10255
10424
|
authToken: "${REMNIC_AUTH_TOKEN}"
|
|
10256
10425
|
}
|
|
10257
10426
|
};
|
|
10258
|
-
|
|
10427
|
+
fs24.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
|
|
10259
10428
|
console.log(`Created ${configPath}`);
|
|
10260
10429
|
console.log("\nSet these environment variables:");
|
|
10261
10430
|
console.log(" export OPENAI_API_KEY=sk-...");
|
|
@@ -10308,7 +10477,7 @@ async function cmdStatus(json) {
|
|
|
10308
10477
|
console.log(`Remnic server: running${pid ? ` (pid ${pid})` : ""}`);
|
|
10309
10478
|
await printHealthCheck(resolveDaemonBaseUrl(resolveConfigPath()), resolveStatusProbeToken());
|
|
10310
10479
|
}
|
|
10311
|
-
async function oauthFetch(method,
|
|
10480
|
+
async function oauthFetch(method, path20, token, body) {
|
|
10312
10481
|
const controller = new AbortController();
|
|
10313
10482
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
10314
10483
|
try {
|
|
@@ -10327,7 +10496,7 @@ async function oauthFetch(method, path19, token, body) {
|
|
|
10327
10496
|
if (body !== void 0) {
|
|
10328
10497
|
init.body = JSON.stringify(body);
|
|
10329
10498
|
}
|
|
10330
|
-
const response = await fetch(`${resolveDaemonBaseUrl(resolveConfigPath())}${
|
|
10499
|
+
const response = await fetch(`${resolveDaemonBaseUrl(resolveConfigPath())}${path20}`, init);
|
|
10331
10500
|
if (response.status === 401) {
|
|
10332
10501
|
throw new Error(
|
|
10333
10502
|
"operator token rejected by remnic-server (HTTP 401). Update `server.authToken` or `REMNIC_AUTH_TOKEN` to match the running daemon."
|
|
@@ -10677,10 +10846,10 @@ async function cmdQuery(queryText, json, explain) {
|
|
|
10677
10846
|
}
|
|
10678
10847
|
initLogger5();
|
|
10679
10848
|
const configPath = resolveConfigPath();
|
|
10680
|
-
const raw =
|
|
10681
|
-
const remnicCfg =
|
|
10682
|
-
const config =
|
|
10683
|
-
const orchestrator = new
|
|
10849
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
10850
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
10851
|
+
const config = parseConfig15(remnicCfg);
|
|
10852
|
+
const orchestrator = new Orchestrator10(config);
|
|
10684
10853
|
await orchestrator.initialize();
|
|
10685
10854
|
const service = new EngramAccessService2(orchestrator);
|
|
10686
10855
|
const recallRequest = buildQueryRecallRequest(queryText);
|
|
@@ -10857,10 +11026,10 @@ async function cmdXray(rest) {
|
|
|
10857
11026
|
}
|
|
10858
11027
|
initLogger5();
|
|
10859
11028
|
const configPath = resolveConfigPath();
|
|
10860
|
-
const raw =
|
|
10861
|
-
const remnicCfg =
|
|
10862
|
-
const config =
|
|
10863
|
-
const orchestrator = new
|
|
11029
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
11030
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
11031
|
+
const config = parseConfig15(remnicCfg);
|
|
11032
|
+
const orchestrator = new Orchestrator10(config);
|
|
10864
11033
|
await orchestrator.initialize();
|
|
10865
11034
|
await orchestrator.deferredReady;
|
|
10866
11035
|
const service = new EngramAccessService2(orchestrator);
|
|
@@ -10890,8 +11059,8 @@ async function runWhoKnowsCommand(rest, io) {
|
|
|
10890
11059
|
async function withLocalService(fn) {
|
|
10891
11060
|
initLogger5();
|
|
10892
11061
|
const configPath = resolveConfigPath();
|
|
10893
|
-
const raw =
|
|
10894
|
-
const orchestrator = new
|
|
11062
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
11063
|
+
const orchestrator = new Orchestrator10(parseConfig15(resolveRemnicConfigRecord14(raw)));
|
|
10895
11064
|
await orchestrator.initialize();
|
|
10896
11065
|
await orchestrator.deferredReady;
|
|
10897
11066
|
const service = new EngramAccessService2(orchestrator);
|
|
@@ -10923,9 +11092,9 @@ async function cmdPromotionCandidates(rest) {
|
|
|
10923
11092
|
async function cmdVersions(rest) {
|
|
10924
11093
|
initLogger5();
|
|
10925
11094
|
const configPath = resolveConfigPath();
|
|
10926
|
-
const raw =
|
|
10927
|
-
const remnicCfg =
|
|
10928
|
-
const config =
|
|
11095
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
11096
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
11097
|
+
const config = parseConfig15(remnicCfg);
|
|
10929
11098
|
if (!config.versioningEnabled) {
|
|
10930
11099
|
console.error("Page versioning is disabled (versioningEnabled = false).");
|
|
10931
11100
|
process.exit(1);
|
|
@@ -10945,7 +11114,7 @@ async function cmdVersions(rest) {
|
|
|
10945
11114
|
console.error("Usage: remnic versions list <page-path>");
|
|
10946
11115
|
process.exit(1);
|
|
10947
11116
|
}
|
|
10948
|
-
const absPath =
|
|
11117
|
+
const absPath = path19.resolve(pagePath);
|
|
10949
11118
|
const history = await listVersions(absPath, versioningConfig, memDir);
|
|
10950
11119
|
if (json) {
|
|
10951
11120
|
console.log(JSON.stringify(history, null, 2));
|
|
@@ -10970,7 +11139,7 @@ async function cmdVersions(rest) {
|
|
|
10970
11139
|
console.error("Usage: remnic versions show <page-path> <version-id>");
|
|
10971
11140
|
process.exit(1);
|
|
10972
11141
|
}
|
|
10973
|
-
const absPath =
|
|
11142
|
+
const absPath = path19.resolve(pagePath);
|
|
10974
11143
|
try {
|
|
10975
11144
|
const content = await getVersion(absPath, versionId, versioningConfig, memDir);
|
|
10976
11145
|
console.log(content);
|
|
@@ -10988,7 +11157,7 @@ async function cmdVersions(rest) {
|
|
|
10988
11157
|
console.error("Usage: remnic versions diff <page-path> <v1> <v2>");
|
|
10989
11158
|
process.exit(1);
|
|
10990
11159
|
}
|
|
10991
|
-
const absPath =
|
|
11160
|
+
const absPath = path19.resolve(pagePath);
|
|
10992
11161
|
try {
|
|
10993
11162
|
const diffOutput = await diffVersions(absPath, v1, v2, versioningConfig, memDir);
|
|
10994
11163
|
console.log(diffOutput);
|
|
@@ -11005,7 +11174,7 @@ async function cmdVersions(rest) {
|
|
|
11005
11174
|
console.error("Usage: remnic versions revert <page-path> <version-id>");
|
|
11006
11175
|
process.exit(1);
|
|
11007
11176
|
}
|
|
11008
|
-
const absPath =
|
|
11177
|
+
const absPath = path19.resolve(pagePath);
|
|
11009
11178
|
try {
|
|
11010
11179
|
const version = await revertToVersion(absPath, versionId, versioningConfig, void 0, memDir);
|
|
11011
11180
|
if (json) {
|
|
@@ -11039,13 +11208,13 @@ Options:
|
|
|
11039
11208
|
async function cmdEnrich(rest) {
|
|
11040
11209
|
initLogger5();
|
|
11041
11210
|
const configPath = resolveConfigPath();
|
|
11042
|
-
const raw =
|
|
11043
|
-
const remnicCfg =
|
|
11044
|
-
const config =
|
|
11211
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
11212
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
11213
|
+
const config = parseConfig15(remnicCfg);
|
|
11045
11214
|
const subcommand = rest[0];
|
|
11046
11215
|
if (subcommand === "audit") {
|
|
11047
11216
|
const memoryDir2 = expandTilde(config.memoryDir);
|
|
11048
|
-
const auditDir2 =
|
|
11217
|
+
const auditDir2 = path19.join(memoryDir2, "enrichment");
|
|
11049
11218
|
const sinceFlag = resolveFlag(rest.slice(1), "--since");
|
|
11050
11219
|
const entries = await readAuditLog(auditDir2, sinceFlag ?? void 0);
|
|
11051
11220
|
if (entries.length === 0) {
|
|
@@ -11069,7 +11238,7 @@ async function cmdEnrich(rest) {
|
|
|
11069
11238
|
pipelineConfig2.providers = [
|
|
11070
11239
|
{ id: "web-search", enabled: true, costTier: "cheap" }
|
|
11071
11240
|
];
|
|
11072
|
-
const orchestrator2 = new
|
|
11241
|
+
const orchestrator2 = new Orchestrator10(config);
|
|
11073
11242
|
await orchestrator2.initialize();
|
|
11074
11243
|
await orchestrator2.deferredReady;
|
|
11075
11244
|
const searchBackend2 = orchestrator2.qmd;
|
|
@@ -11105,7 +11274,7 @@ Registered providers:`);
|
|
|
11105
11274
|
console.error("Usage: remnic enrich <entity-name> | --all | --dry-run | audit | providers");
|
|
11106
11275
|
process.exit(1);
|
|
11107
11276
|
}
|
|
11108
|
-
const orchestrator = new
|
|
11277
|
+
const orchestrator = new Orchestrator10(config);
|
|
11109
11278
|
await orchestrator.initialize();
|
|
11110
11279
|
await orchestrator.deferredReady;
|
|
11111
11280
|
const storage = await orchestrator.getStorage(config.defaultNamespace);
|
|
@@ -11170,7 +11339,7 @@ Registered providers:`);
|
|
|
11170
11339
|
return;
|
|
11171
11340
|
}
|
|
11172
11341
|
const memoryDir = expandTilde(config.memoryDir);
|
|
11173
|
-
const auditDir =
|
|
11342
|
+
const auditDir = path19.join(memoryDir, "enrichment");
|
|
11174
11343
|
let totalPersisted = 0;
|
|
11175
11344
|
for (const result of results) {
|
|
11176
11345
|
for (const candidate of result.acceptedCandidates) {
|
|
@@ -11233,9 +11402,9 @@ Registered providers:`);
|
|
|
11233
11402
|
async function cmdExtensions(action, rest) {
|
|
11234
11403
|
initLogger5();
|
|
11235
11404
|
const configPath = resolveConfigPath();
|
|
11236
|
-
const raw =
|
|
11237
|
-
const remnicCfg =
|
|
11238
|
-
const config =
|
|
11405
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
11406
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
11407
|
+
const config = parseConfig15(remnicCfg);
|
|
11239
11408
|
const root = resolveExtensionsRoot(config);
|
|
11240
11409
|
const noopLog = { warn: () => {
|
|
11241
11410
|
}, debug: () => {
|
|
@@ -11284,7 +11453,7 @@ Root: ${root}`);
|
|
|
11284
11453
|
const extensions = await discoverMemoryExtensions(root, warnLog);
|
|
11285
11454
|
let entries = [];
|
|
11286
11455
|
try {
|
|
11287
|
-
entries =
|
|
11456
|
+
entries = fs24.readdirSync(root);
|
|
11288
11457
|
} catch {
|
|
11289
11458
|
console.log(`Extensions root does not exist: ${root}`);
|
|
11290
11459
|
process.exitCode = 0;
|
|
@@ -11293,9 +11462,9 @@ Root: ${root}`);
|
|
|
11293
11462
|
const validNames = new Set(extensions.map((e) => e.name));
|
|
11294
11463
|
let errors = 0;
|
|
11295
11464
|
for (const entry of entries) {
|
|
11296
|
-
const entryPath =
|
|
11465
|
+
const entryPath = path19.join(root, entry);
|
|
11297
11466
|
try {
|
|
11298
|
-
if (!
|
|
11467
|
+
if (!fs24.statSync(entryPath).isDirectory()) continue;
|
|
11299
11468
|
} catch {
|
|
11300
11469
|
continue;
|
|
11301
11470
|
}
|
|
@@ -11327,9 +11496,9 @@ Root: ${root}`);
|
|
|
11327
11496
|
async function cmdBriefing(rest) {
|
|
11328
11497
|
initLogger5();
|
|
11329
11498
|
const configPath = resolveConfigPath();
|
|
11330
|
-
const raw =
|
|
11331
|
-
const remnicCfg =
|
|
11332
|
-
const config =
|
|
11499
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
11500
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
11501
|
+
const config = parseConfig15(remnicCfg);
|
|
11333
11502
|
if (!config.briefing.enabled) {
|
|
11334
11503
|
console.error("Briefing is disabled in config (briefing.enabled = false).");
|
|
11335
11504
|
process.exit(1);
|
|
@@ -11382,7 +11551,7 @@ async function cmdBriefing(rest) {
|
|
|
11382
11551
|
process.exit(1);
|
|
11383
11552
|
}
|
|
11384
11553
|
const format = effectiveFormatFlag === "json" ? "json" : effectiveFormatFlag === "markdown" ? "markdown" : config.briefing.defaultFormat;
|
|
11385
|
-
const orchestrator = new
|
|
11554
|
+
const orchestrator = new Orchestrator10(config);
|
|
11386
11555
|
await orchestrator.initialize();
|
|
11387
11556
|
const storage = await orchestrator.getStorage(config.defaultNamespace);
|
|
11388
11557
|
const calendarSource = config.briefing.calendarSource ? new FileCalendarSource(config.briefing.calendarSource) : void 0;
|
|
@@ -11407,10 +11576,10 @@ async function cmdBriefing(rest) {
|
|
|
11407
11576
|
if (save) {
|
|
11408
11577
|
try {
|
|
11409
11578
|
const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
|
|
11410
|
-
|
|
11579
|
+
fs24.mkdirSync(saveDir, { recursive: true });
|
|
11411
11580
|
const filename = briefingFilename(new Date(result.window.to), format);
|
|
11412
|
-
const filePath =
|
|
11413
|
-
|
|
11581
|
+
const filePath = path19.join(saveDir, filename);
|
|
11582
|
+
fs24.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
|
|
11414
11583
|
console.error(`Saved briefing: ${filePath}`);
|
|
11415
11584
|
} catch (err) {
|
|
11416
11585
|
console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -11428,7 +11597,7 @@ async function cmdDoctor() {
|
|
|
11428
11597
|
detail: `${nodeVersion} (requires >= 22.12.0)`
|
|
11429
11598
|
});
|
|
11430
11599
|
const configPath = resolveConfigPath();
|
|
11431
|
-
const configExists =
|
|
11600
|
+
const configExists = fs24.existsSync(configPath);
|
|
11432
11601
|
checks.push({ name: "Config file", ok: configExists, detail: configPath });
|
|
11433
11602
|
let standaloneConfig;
|
|
11434
11603
|
let standaloneConfigError;
|
|
@@ -11436,11 +11605,11 @@ async function cmdDoctor() {
|
|
|
11436
11605
|
let configuredNs = { invalid: false };
|
|
11437
11606
|
if (configExists) {
|
|
11438
11607
|
try {
|
|
11439
|
-
const raw = JSON.parse(
|
|
11440
|
-
const remnicCfg =
|
|
11608
|
+
const raw = JSON.parse(fs24.readFileSync(configPath, "utf8"));
|
|
11609
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
11441
11610
|
standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
|
|
11442
11611
|
configuredNs = readConfiguredNamespace(remnicCfg);
|
|
11443
|
-
standaloneConfig =
|
|
11612
|
+
standaloneConfig = parseConfig15(remnicCfg);
|
|
11444
11613
|
} catch (err) {
|
|
11445
11614
|
standaloneConfigError = err instanceof Error ? err.message : String(err);
|
|
11446
11615
|
}
|
|
@@ -11449,10 +11618,10 @@ async function cmdDoctor() {
|
|
|
11449
11618
|
try {
|
|
11450
11619
|
memoryDir = resolveMemoryDir();
|
|
11451
11620
|
} catch {
|
|
11452
|
-
memoryDir =
|
|
11621
|
+
memoryDir = parseConfig15({}).memoryDir;
|
|
11453
11622
|
}
|
|
11454
11623
|
try {
|
|
11455
|
-
|
|
11624
|
+
fs24.mkdirSync(memoryDir, { recursive: true });
|
|
11456
11625
|
checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
|
|
11457
11626
|
} catch {
|
|
11458
11627
|
checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
|
|
@@ -11481,7 +11650,7 @@ async function cmdDoctor() {
|
|
|
11481
11650
|
});
|
|
11482
11651
|
if (nsPolicyCheck) checks.push(nsPolicyCheck);
|
|
11483
11652
|
const openclawConfigPath = resolveOpenclawConfigPath();
|
|
11484
|
-
const openclawConfigExists =
|
|
11653
|
+
const openclawConfigExists = fs24.existsSync(openclawConfigPath);
|
|
11485
11654
|
let openclawConfig = {};
|
|
11486
11655
|
let openclawConfigValid = false;
|
|
11487
11656
|
let openclawPluginModeConfigured = false;
|
|
@@ -11489,7 +11658,7 @@ async function cmdDoctor() {
|
|
|
11489
11658
|
let activeOpenclawEntryConfig = null;
|
|
11490
11659
|
if (openclawConfigExists) {
|
|
11491
11660
|
try {
|
|
11492
|
-
const parsed = JSON.parse(
|
|
11661
|
+
const parsed = JSON.parse(fs24.readFileSync(openclawConfigPath, "utf-8"));
|
|
11493
11662
|
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
11494
11663
|
openclawConfig = parsed;
|
|
11495
11664
|
openclawConfigValid = true;
|
|
@@ -11565,13 +11734,13 @@ async function cmdDoctor() {
|
|
|
11565
11734
|
const rawMemoryDir = entryConfig?.memoryDir;
|
|
11566
11735
|
const configuredMemoryDir = typeof rawMemoryDir === "string" ? rawMemoryDir : void 0;
|
|
11567
11736
|
if (configuredMemoryDir) {
|
|
11568
|
-
const resolvedMemDir =
|
|
11737
|
+
const resolvedMemDir = path19.resolve(expandTilde(configuredMemoryDir));
|
|
11569
11738
|
let memDirOk = false;
|
|
11570
11739
|
let memDirDetail = `${resolvedMemDir} (not found)`;
|
|
11571
11740
|
let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
|
|
11572
|
-
if (
|
|
11741
|
+
if (fs24.existsSync(resolvedMemDir)) {
|
|
11573
11742
|
try {
|
|
11574
|
-
const stat2 =
|
|
11743
|
+
const stat2 = fs24.statSync(resolvedMemDir);
|
|
11575
11744
|
if (stat2.isDirectory()) {
|
|
11576
11745
|
memDirOk = true;
|
|
11577
11746
|
memDirDetail = resolvedMemDir;
|
|
@@ -11726,12 +11895,12 @@ async function cmdDoctor() {
|
|
|
11726
11895
|
}
|
|
11727
11896
|
function cmdConfig() {
|
|
11728
11897
|
const configPath = resolveConfigPath();
|
|
11729
|
-
if (!
|
|
11898
|
+
if (!fs24.existsSync(configPath)) {
|
|
11730
11899
|
console.log("No config file found. Run `remnic init` to create one.");
|
|
11731
11900
|
return;
|
|
11732
11901
|
}
|
|
11733
11902
|
console.log(`Config: ${configPath}`);
|
|
11734
|
-
const rawConfig =
|
|
11903
|
+
const rawConfig = fs24.readFileSync(configPath, "utf8");
|
|
11735
11904
|
const redacted = rawConfig.replace(
|
|
11736
11905
|
/("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
|
|
11737
11906
|
"$1[REDACTED]$3"
|
|
@@ -11778,7 +11947,7 @@ async function cmdMigrate(json, rollback) {
|
|
|
11778
11947
|
console.log(` Rollback: ${result.rollbackCommand}`);
|
|
11779
11948
|
}
|
|
11780
11949
|
function cmdOnboard(dirPath, json) {
|
|
11781
|
-
const directory =
|
|
11950
|
+
const directory = path19.resolve(dirPath || process.cwd());
|
|
11782
11951
|
const result = onboard({ directory });
|
|
11783
11952
|
if (json) {
|
|
11784
11953
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -11797,7 +11966,7 @@ Suggested namespace: ${result.plan.suggestedNamespace}`);
|
|
|
11797
11966
|
async function cmdCurate(targetPath, json) {
|
|
11798
11967
|
const memoryDir = resolveMemoryDir();
|
|
11799
11968
|
const result = await curate({
|
|
11800
|
-
targetPath:
|
|
11969
|
+
targetPath: path19.resolve(targetPath),
|
|
11801
11970
|
memoryDir,
|
|
11802
11971
|
source: "curation",
|
|
11803
11972
|
checkDuplicates: true,
|
|
@@ -11839,9 +12008,9 @@ async function cmdReview(action, rest) {
|
|
|
11839
12008
|
const configPath = resolveConfigPath();
|
|
11840
12009
|
let tombstonesConfig = null;
|
|
11841
12010
|
try {
|
|
11842
|
-
const rawCfg =
|
|
11843
|
-
const remnicCfg =
|
|
11844
|
-
const config =
|
|
12011
|
+
const rawCfg = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
12012
|
+
const remnicCfg = resolveRemnicConfigRecord14(rawCfg);
|
|
12013
|
+
const config = parseConfig15(remnicCfg);
|
|
11845
12014
|
tombstonesConfig = {
|
|
11846
12015
|
enabled: config.tombstonesEnabled,
|
|
11847
12016
|
semanticMatch: config.tombstonesSemanticMatch,
|
|
@@ -11927,7 +12096,7 @@ async function cmdSync(action, rest, json) {
|
|
|
11927
12096
|
}
|
|
11928
12097
|
function localOfflineSourceId(memoryDir) {
|
|
11929
12098
|
const host = os3.hostname() || "unknown-host";
|
|
11930
|
-
const dirHash = createHash4("sha256").update(
|
|
12099
|
+
const dirHash = createHash4("sha256").update(path19.resolve(memoryDir)).digest("hex").slice(0, 16);
|
|
11931
12100
|
return `remnic-local:${host}:${dirHash}`;
|
|
11932
12101
|
}
|
|
11933
12102
|
function normalizeOfflineRemoteUrl(raw) {
|
|
@@ -12325,10 +12494,10 @@ var OFFLINE_SYNC_CONTENT_MISSING_RETRY_MAX = 3;
|
|
|
12325
12494
|
var OFFLINE_SYNC_CONTENT_MISSING_RETRY_DELAY_MS = 250;
|
|
12326
12495
|
var OfflineRemoteFileChangedError = class extends Error {
|
|
12327
12496
|
path;
|
|
12328
|
-
constructor(
|
|
12329
|
-
super(`remote file changed while fetching offline content: ${
|
|
12497
|
+
constructor(path20) {
|
|
12498
|
+
super(`remote file changed while fetching offline content: ${path20}`);
|
|
12330
12499
|
this.name = "OfflineRemoteFileChangedError";
|
|
12331
|
-
this.path =
|
|
12500
|
+
this.path = path20;
|
|
12332
12501
|
}
|
|
12333
12502
|
};
|
|
12334
12503
|
function isOfflineRemoteFileChangedError(error) {
|
|
@@ -12583,13 +12752,13 @@ async function pushOfflineFileContent(args) {
|
|
|
12583
12752
|
}
|
|
12584
12753
|
async function pushOfflineFileContentFromChunkReader(args) {
|
|
12585
12754
|
const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
|
|
12586
|
-
const stat2 =
|
|
12755
|
+
const stat2 = fs24.statSync(filePath);
|
|
12587
12756
|
if (stat2.mtimeMs !== args.file.mtimeMs) {
|
|
12588
12757
|
throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
|
|
12589
12758
|
}
|
|
12590
12759
|
const hash = createHash4("sha256");
|
|
12591
12760
|
const chunks = args.readFileChunks({
|
|
12592
|
-
root:
|
|
12761
|
+
root: path19.resolve(args.memoryDir),
|
|
12593
12762
|
path: args.file.path,
|
|
12594
12763
|
filePath,
|
|
12595
12764
|
chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
|
|
@@ -13074,7 +13243,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
|
|
|
13074
13243
|
return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
|
|
13075
13244
|
}
|
|
13076
13245
|
async function runOfflineSyncOnce(options) {
|
|
13077
|
-
|
|
13246
|
+
fs24.mkdirSync(options.memoryDir, { recursive: true });
|
|
13078
13247
|
let activeStatePath = options.statePath;
|
|
13079
13248
|
let priorState = await readOfflineSyncState(activeStatePath);
|
|
13080
13249
|
let syncNamespace = options.namespace ?? priorState?.namespace;
|
|
@@ -13699,7 +13868,7 @@ Environment fallbacks:
|
|
|
13699
13868
|
REMNIC_OFFLINE_REMOTE_URL, REMNIC_OFFLINE_TOKEN, REMNIC_AUTH_TOKEN`);
|
|
13700
13869
|
return;
|
|
13701
13870
|
}
|
|
13702
|
-
const memoryDir =
|
|
13871
|
+
const memoryDir = path19.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
|
|
13703
13872
|
const namespace = resolveRequiredValueFlag(rest, "--namespace");
|
|
13704
13873
|
const includeTranscripts = !hasFlag(rest, "--no-transcripts");
|
|
13705
13874
|
const stateOverride = resolveRequiredValueFlag(rest, "--state");
|
|
@@ -13707,7 +13876,7 @@ Environment fallbacks:
|
|
|
13707
13876
|
const configPath = resolveConfigPath();
|
|
13708
13877
|
let config;
|
|
13709
13878
|
try {
|
|
13710
|
-
const rawConfig =
|
|
13879
|
+
const rawConfig = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
13711
13880
|
config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
|
|
13712
13881
|
} catch {
|
|
13713
13882
|
throw new Error(
|
|
@@ -13719,10 +13888,10 @@ Environment fallbacks:
|
|
|
13719
13888
|
const needsRemote = action === "prepare" || action === "sync" || action === "watch";
|
|
13720
13889
|
const remoteUrl = needsRemote ? resolveOfflineRemoteUrl(rest) : resolveOptionalOfflineRemoteUrl(rest);
|
|
13721
13890
|
const token = needsRemote ? resolveOfflineToken(rest) : void 0;
|
|
13722
|
-
const statePath = statePathExplicit ?
|
|
13891
|
+
const statePath = statePathExplicit ? path19.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
|
|
13723
13892
|
if (action === "prepare") {
|
|
13724
13893
|
if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
|
|
13725
|
-
|
|
13894
|
+
fs24.mkdirSync(memoryDir, { recursive: true });
|
|
13726
13895
|
const remoteSnapshot = await fetchOfflineSnapshot({
|
|
13727
13896
|
remoteUrl,
|
|
13728
13897
|
token,
|
|
@@ -13821,7 +13990,7 @@ Environment fallbacks:
|
|
|
13821
13990
|
return;
|
|
13822
13991
|
}
|
|
13823
13992
|
if (action === "status") {
|
|
13824
|
-
|
|
13993
|
+
fs24.mkdirSync(memoryDir, { recursive: true });
|
|
13825
13994
|
const state = statePath ? await readOfflineSyncState(statePath) : null;
|
|
13826
13995
|
if (state && remoteUrl && statePath) {
|
|
13827
13996
|
assertOfflineStateMatches({
|
|
@@ -13901,11 +14070,11 @@ Environment fallbacks:
|
|
|
13901
14070
|
failures: result.largeFilePushFailures
|
|
13902
14071
|
});
|
|
13903
14072
|
largeFileFailureCounts = advanced.counts;
|
|
13904
|
-
for (const
|
|
13905
|
-
if (skippedLargeFiles.has(
|
|
13906
|
-
skippedLargeFiles.add(
|
|
14073
|
+
for (const path20 of advanced.newlySkipped) {
|
|
14074
|
+
if (skippedLargeFiles.has(path20)) continue;
|
|
14075
|
+
skippedLargeFiles.add(path20);
|
|
13907
14076
|
console.warn(
|
|
13908
|
-
`offline sync: permanently skipping ${
|
|
14077
|
+
`offline sync: permanently skipping ${path20} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
|
|
13909
14078
|
);
|
|
13910
14079
|
}
|
|
13911
14080
|
const pulled = result.pull ? result.pull.upserted + result.pull.deleted : 0;
|
|
@@ -13920,11 +14089,11 @@ Environment fallbacks:
|
|
|
13920
14089
|
failures: error.failures
|
|
13921
14090
|
});
|
|
13922
14091
|
largeFileFailureCounts = advanced.counts;
|
|
13923
|
-
for (const
|
|
13924
|
-
if (skippedLargeFiles.has(
|
|
13925
|
-
skippedLargeFiles.add(
|
|
14092
|
+
for (const path20 of advanced.newlySkipped) {
|
|
14093
|
+
if (skippedLargeFiles.has(path20)) continue;
|
|
14094
|
+
skippedLargeFiles.add(path20);
|
|
13926
14095
|
console.warn(
|
|
13927
|
-
`offline sync: permanently skipping ${
|
|
14096
|
+
`offline sync: permanently skipping ${path20} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
|
|
13928
14097
|
);
|
|
13929
14098
|
}
|
|
13930
14099
|
}
|
|
@@ -13959,7 +14128,7 @@ function cmdDedup(json) {
|
|
|
13959
14128
|
function readInstalledConnectorConfig(configPath, fallback) {
|
|
13960
14129
|
if (!configPath) return fallback;
|
|
13961
14130
|
try {
|
|
13962
|
-
const parsed = JSON.parse(
|
|
14131
|
+
const parsed = JSON.parse(fs24.readFileSync(configPath, "utf8"));
|
|
13963
14132
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
|
|
13964
14133
|
const { token: _token, ...config } = parsed;
|
|
13965
14134
|
return config;
|
|
@@ -14065,7 +14234,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14065
14234
|
const connectorDaemonUrl = typeof effectiveConnectorConfig.remnicDaemonUrl === "string" && effectiveConnectorConfig.remnicDaemonUrl.trim().length > 0 ? effectiveConnectorConfig.remnicDaemonUrl.trim() : void 0;
|
|
14066
14235
|
const pubResult = await pub.publish({
|
|
14067
14236
|
config: { memoryDir, namespace: connectorNamespace, daemonUrl: connectorDaemonUrl },
|
|
14068
|
-
skillsRoot:
|
|
14237
|
+
skillsRoot: path19.join(memoryDir, "skills"),
|
|
14069
14238
|
rollbackTokenEntry: preInstallTokenEntry,
|
|
14070
14239
|
log: { info: console.log, warn: console.warn, error: console.error }
|
|
14071
14240
|
});
|
|
@@ -14137,7 +14306,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14137
14306
|
const pub = factory();
|
|
14138
14307
|
const available = await pub.isHostAvailable();
|
|
14139
14308
|
const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
|
|
14140
|
-
const extensionExists = available && extRoot ?
|
|
14309
|
+
const extensionExists = available && extRoot ? fs24.existsSync(extRoot) : false;
|
|
14141
14310
|
publisherChecks.push({
|
|
14142
14311
|
name: `Publisher: ${targetHostId}`,
|
|
14143
14312
|
ok: !available || extensionExists,
|
|
@@ -14211,7 +14380,7 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14211
14380
|
let connectorsCfg;
|
|
14212
14381
|
const configPath = resolveConfigPath();
|
|
14213
14382
|
try {
|
|
14214
|
-
const raw =
|
|
14383
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
14215
14384
|
connectorsCfg = parseConfigQuietly(raw).connectors;
|
|
14216
14385
|
} catch {
|
|
14217
14386
|
process.stderr.write(
|
|
@@ -14287,10 +14456,10 @@ async function cmdConnectors(action, rest, json) {
|
|
|
14287
14456
|
}
|
|
14288
14457
|
initLogger5();
|
|
14289
14458
|
const configPath = resolveConfigPath();
|
|
14290
|
-
const raw =
|
|
14291
|
-
const remnicCfg =
|
|
14292
|
-
const config =
|
|
14293
|
-
const orchestrator = new
|
|
14459
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
14460
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
14461
|
+
const config = parseConfig15(remnicCfg);
|
|
14462
|
+
const orchestrator = new Orchestrator10(config);
|
|
14294
14463
|
try {
|
|
14295
14464
|
await orchestrator.initialize();
|
|
14296
14465
|
await orchestrator.deferredReady;
|
|
@@ -14412,9 +14581,9 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
|
|
|
14412
14581
|
console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
|
|
14413
14582
|
process.exit(1);
|
|
14414
14583
|
}
|
|
14415
|
-
const rawConfig =
|
|
14416
|
-
const pluginConfig =
|
|
14417
|
-
const config =
|
|
14584
|
+
const rawConfig = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
14585
|
+
const pluginConfig = resolveRemnicConfigRecord14(rawConfig);
|
|
14586
|
+
const config = parseConfig15(pluginConfig);
|
|
14418
14587
|
if (subAction === "generate") {
|
|
14419
14588
|
let outputDir;
|
|
14420
14589
|
try {
|
|
@@ -14425,22 +14594,22 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
|
|
|
14425
14594
|
}
|
|
14426
14595
|
const manifest = generateMarketplaceManifest();
|
|
14427
14596
|
await writeMarketplaceManifest(outputDir, manifest);
|
|
14428
|
-
const outPath =
|
|
14597
|
+
const outPath = path19.join(outputDir, "marketplace.json");
|
|
14429
14598
|
if (json) {
|
|
14430
14599
|
console.log(JSON.stringify({ status: "generated", path: outPath }, null, 2));
|
|
14431
14600
|
} else {
|
|
14432
14601
|
console.log(`Generated marketplace.json at ${outPath}`);
|
|
14433
14602
|
}
|
|
14434
14603
|
} else if (subAction === "validate") {
|
|
14435
|
-
const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ??
|
|
14436
|
-
const resolved =
|
|
14437
|
-
if (!
|
|
14604
|
+
const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path19.join(process.cwd(), "marketplace.json");
|
|
14605
|
+
const resolved = path19.resolve(targetPath);
|
|
14606
|
+
if (!fs24.existsSync(resolved)) {
|
|
14438
14607
|
console.error(`File not found: ${resolved}`);
|
|
14439
14608
|
process.exit(1);
|
|
14440
14609
|
}
|
|
14441
14610
|
let parsed;
|
|
14442
14611
|
try {
|
|
14443
|
-
parsed = JSON.parse(
|
|
14612
|
+
parsed = JSON.parse(fs24.readFileSync(resolved, "utf8"));
|
|
14444
14613
|
} catch {
|
|
14445
14614
|
console.error(`Invalid JSON in ${resolved}`);
|
|
14446
14615
|
process.exit(1);
|
|
@@ -14643,10 +14812,10 @@ async function cmdSpace(action, rest, json) {
|
|
|
14643
14812
|
async function cmdLegacyBenchmark(action, rest, json) {
|
|
14644
14813
|
initLogger5();
|
|
14645
14814
|
const configPath = resolveConfigPath();
|
|
14646
|
-
const raw =
|
|
14647
|
-
const remnicCfg =
|
|
14648
|
-
const config =
|
|
14649
|
-
const orchestrator = new
|
|
14815
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
14816
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
14817
|
+
const config = parseConfig15(remnicCfg);
|
|
14818
|
+
const orchestrator = new Orchestrator10(config);
|
|
14650
14819
|
const service = new EngramAccessService2(orchestrator);
|
|
14651
14820
|
const { runBenchSuite, loadBaseline, checkRegression } = await loadBenchModule();
|
|
14652
14821
|
const benchConfig = {
|
|
@@ -14845,7 +15014,7 @@ async function cmdBench(rest) {
|
|
|
14845
15014
|
}
|
|
14846
15015
|
const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
|
|
14847
15016
|
const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
|
|
14848
|
-
printBenchStatusLine(parsed.json, `Resuming from: ${
|
|
15017
|
+
printBenchStatusLine(parsed.json, `Resuming from: ${path19.basename(latestStatusPath)}`);
|
|
14849
15018
|
printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
|
|
14850
15019
|
printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
|
|
14851
15020
|
const before = selectedBenchmarks.length;
|
|
@@ -15013,9 +15182,9 @@ Options:
|
|
|
15013
15182
|
);
|
|
15014
15183
|
process.exit(1);
|
|
15015
15184
|
} else {
|
|
15016
|
-
fixturePath =
|
|
15185
|
+
fixturePath = path19.resolve(expandTilde(fixturePathRaw));
|
|
15017
15186
|
}
|
|
15018
|
-
const outPath =
|
|
15187
|
+
const outPath = path19.resolve(expandTilde(outPathRaw));
|
|
15019
15188
|
const benchModule = await loadBenchModule();
|
|
15020
15189
|
const runner = benchModule.runProceduralAblationCli;
|
|
15021
15190
|
if (typeof runner !== "function") {
|
|
@@ -15034,7 +15203,7 @@ Options:
|
|
|
15034
15203
|
);
|
|
15035
15204
|
console.log(`wrote ${outPath}`);
|
|
15036
15205
|
}
|
|
15037
|
-
var LOGS_DIR =
|
|
15206
|
+
var LOGS_DIR = path19.join(PID_DIR, "logs");
|
|
15038
15207
|
var LAUNCHD_PLIST_PATHS = launchdPlistPaths(resolveHomeDir());
|
|
15039
15208
|
var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
|
|
15040
15209
|
var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
|
|
@@ -15048,7 +15217,7 @@ function readPid() {
|
|
|
15048
15217
|
function inferPort() {
|
|
15049
15218
|
try {
|
|
15050
15219
|
const configPath = resolveConfigPath();
|
|
15051
|
-
const raw = JSON.parse(
|
|
15220
|
+
const raw = JSON.parse(fs24.readFileSync(configPath, "utf8"));
|
|
15052
15221
|
return raw.server?.port ?? 4318;
|
|
15053
15222
|
} catch {
|
|
15054
15223
|
return 4318;
|
|
@@ -15111,7 +15280,7 @@ function selectLaunchdInspection(openclawPluginModeConfigured) {
|
|
|
15111
15280
|
for (const plistPath of LAUNCHD_PLIST_PATHS.slice(1)) {
|
|
15112
15281
|
const legacy = inspectLaunchdPlist(plistPath);
|
|
15113
15282
|
if (!legacy.installed) continue;
|
|
15114
|
-
const label =
|
|
15283
|
+
const label = path19.basename(plistPath, ".plist");
|
|
15115
15284
|
return legacy.ok ? {
|
|
15116
15285
|
...legacy,
|
|
15117
15286
|
warn: true,
|
|
@@ -15143,13 +15312,13 @@ function daemonInstall() {
|
|
|
15143
15312
|
process.exit(1);
|
|
15144
15313
|
}
|
|
15145
15314
|
const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
|
|
15146
|
-
|
|
15315
|
+
fs24.mkdirSync(LOGS_DIR, { recursive: true });
|
|
15147
15316
|
if (isMacOS()) {
|
|
15148
|
-
const templatePath =
|
|
15149
|
-
const template =
|
|
15317
|
+
const templatePath = path19.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
|
|
15318
|
+
const template = fs24.readFileSync(templatePath, "utf8");
|
|
15150
15319
|
const plist = renderTemplate(template, vars);
|
|
15151
|
-
|
|
15152
|
-
|
|
15320
|
+
fs24.mkdirSync(path19.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
|
|
15321
|
+
fs24.writeFileSync(LAUNCHD_PLIST_PATH, plist);
|
|
15153
15322
|
try {
|
|
15154
15323
|
launchdLoadPlist(LAUNCHD_PLIST_PATH);
|
|
15155
15324
|
} catch (err) {
|
|
@@ -15165,11 +15334,11 @@ function daemonInstall() {
|
|
|
15165
15334
|
console.log(` RunAtLoad: true, KeepAlive: true`);
|
|
15166
15335
|
console.log(` Logs: ${LOGS_DIR}/daemon.log`);
|
|
15167
15336
|
} else if (isLinux()) {
|
|
15168
|
-
const templatePath =
|
|
15169
|
-
const template =
|
|
15337
|
+
const templatePath = path19.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
|
|
15338
|
+
const template = fs24.readFileSync(templatePath, "utf8");
|
|
15170
15339
|
const unit = renderTemplate(template, vars);
|
|
15171
|
-
|
|
15172
|
-
|
|
15340
|
+
fs24.mkdirSync(path19.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
|
|
15341
|
+
fs24.writeFileSync(SYSTEMD_UNIT_PATH, unit);
|
|
15173
15342
|
try {
|
|
15174
15343
|
childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
|
|
15175
15344
|
} catch (err) {
|
|
@@ -15205,7 +15374,7 @@ function daemonUninstall() {
|
|
|
15205
15374
|
} catch {
|
|
15206
15375
|
}
|
|
15207
15376
|
try {
|
|
15208
|
-
|
|
15377
|
+
fs24.unlinkSync(plistPath);
|
|
15209
15378
|
removed = true;
|
|
15210
15379
|
console.log(`Removed launchd service: ${plistPath}`);
|
|
15211
15380
|
} catch {
|
|
@@ -15225,7 +15394,7 @@ function daemonUninstall() {
|
|
|
15225
15394
|
let removed = false;
|
|
15226
15395
|
for (const unitPath of SYSTEMD_UNIT_PATHS) {
|
|
15227
15396
|
try {
|
|
15228
|
-
|
|
15397
|
+
fs24.unlinkSync(unitPath);
|
|
15229
15398
|
removed = true;
|
|
15230
15399
|
console.log(`Removed systemd service: ${unitPath}`);
|
|
15231
15400
|
} catch {
|
|
@@ -15292,13 +15461,13 @@ async function daemonStatus() {
|
|
|
15292
15461
|
console.log(` Port: ${port}`);
|
|
15293
15462
|
console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
|
|
15294
15463
|
console.log(` Platform: ${process.platform}`);
|
|
15295
|
-
console.log(` PID file: ${
|
|
15296
|
-
console.log(` Log file: ${
|
|
15464
|
+
console.log(` PID file: ${fs24.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
|
|
15465
|
+
console.log(` Log file: ${fs24.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
|
|
15297
15466
|
try {
|
|
15298
15467
|
const configPath = resolveConfigPath();
|
|
15299
|
-
const raw =
|
|
15300
|
-
const remnicCfg =
|
|
15301
|
-
const config =
|
|
15468
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
15469
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
15470
|
+
const config = parseConfig15(remnicCfg);
|
|
15302
15471
|
const extRoot = resolveExtensionsRoot(config);
|
|
15303
15472
|
const noopLog = { warn: () => {
|
|
15304
15473
|
}, debug: () => {
|
|
@@ -15337,9 +15506,9 @@ function daemonStart() {
|
|
|
15337
15506
|
return;
|
|
15338
15507
|
}
|
|
15339
15508
|
}
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
const logStream =
|
|
15509
|
+
fs24.mkdirSync(PID_DIR, { recursive: true });
|
|
15510
|
+
fs24.mkdirSync(LOGS_DIR, { recursive: true });
|
|
15511
|
+
const logStream = fs24.openSync(LOG_FILE, "a");
|
|
15343
15512
|
const serverBin = resolveServerBin();
|
|
15344
15513
|
const isSource = serverBin.endsWith(".ts");
|
|
15345
15514
|
let cmd;
|
|
@@ -15361,7 +15530,7 @@ function daemonStart() {
|
|
|
15361
15530
|
}
|
|
15362
15531
|
});
|
|
15363
15532
|
child.unref();
|
|
15364
|
-
|
|
15533
|
+
fs24.writeFileSync(PID_FILE, String(child.pid));
|
|
15365
15534
|
console.log(`Started remnic server (pid ${child.pid})`);
|
|
15366
15535
|
console.log(` Log: ${LOG_FILE}`);
|
|
15367
15536
|
}
|
|
@@ -15395,11 +15564,11 @@ function daemonStop() {
|
|
|
15395
15564
|
console.log("Process not found (cleaning up PID file)");
|
|
15396
15565
|
}
|
|
15397
15566
|
try {
|
|
15398
|
-
|
|
15567
|
+
fs24.unlinkSync(PID_FILE);
|
|
15399
15568
|
} catch {
|
|
15400
15569
|
}
|
|
15401
15570
|
try {
|
|
15402
|
-
|
|
15571
|
+
fs24.unlinkSync(LEGACY_PID_FILE);
|
|
15403
15572
|
} catch {
|
|
15404
15573
|
}
|
|
15405
15574
|
}
|
|
@@ -15527,9 +15696,9 @@ async function promptYesNo(question, defaultYes = true) {
|
|
|
15527
15696
|
async function cmdBinary(rest) {
|
|
15528
15697
|
initLogger5();
|
|
15529
15698
|
const configPath = resolveConfigPath();
|
|
15530
|
-
const raw =
|
|
15531
|
-
const remnicCfg =
|
|
15532
|
-
const config =
|
|
15699
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
15700
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
15701
|
+
const config = parseConfig15(remnicCfg);
|
|
15533
15702
|
const memoryDir = resolveMemoryDir();
|
|
15534
15703
|
const blConfig = {
|
|
15535
15704
|
enabled: config.binaryLifecycleEnabled,
|
|
@@ -15647,7 +15816,7 @@ Clean complete: cleaned=${result.cleaned}`
|
|
|
15647
15816
|
}
|
|
15648
15817
|
async function cmdOpenclawInstall(opts) {
|
|
15649
15818
|
const configPath = resolveOpenclawConfigPath(opts.configPath);
|
|
15650
|
-
const fallbackMemoryDir =
|
|
15819
|
+
const fallbackMemoryDir = path19.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
15651
15820
|
console.log(`OpenClaw config: ${configPath}`);
|
|
15652
15821
|
const existingConfig = readOpenclawConfig(configPath);
|
|
15653
15822
|
const { plugins, entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
|
|
@@ -15718,7 +15887,7 @@ async function cmdOpenclawInstall(opts) {
|
|
|
15718
15887
|
} else if (slotIsActiveLegacy) {
|
|
15719
15888
|
changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
|
|
15720
15889
|
}
|
|
15721
|
-
if (!
|
|
15890
|
+
if (!fs24.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
|
|
15722
15891
|
if (hasLegacy && migrateLegacy) {
|
|
15723
15892
|
changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
|
|
15724
15893
|
}
|
|
@@ -15738,8 +15907,8 @@ async function cmdOpenclawInstall(opts) {
|
|
|
15738
15907
|
Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
|
|
15739
15908
|
return;
|
|
15740
15909
|
}
|
|
15741
|
-
if (
|
|
15742
|
-
const st =
|
|
15910
|
+
if (fs24.existsSync(memoryDir)) {
|
|
15911
|
+
const st = fs24.statSync(memoryDir);
|
|
15743
15912
|
if (!st.isDirectory()) {
|
|
15744
15913
|
throw new Error(
|
|
15745
15914
|
`Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
|
|
@@ -15747,12 +15916,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
|
|
|
15747
15916
|
);
|
|
15748
15917
|
}
|
|
15749
15918
|
} else {
|
|
15750
|
-
|
|
15919
|
+
fs24.mkdirSync(memoryDir, { recursive: true });
|
|
15751
15920
|
console.log(`Created memory directory: ${memoryDir}`);
|
|
15752
15921
|
}
|
|
15753
|
-
const configDir =
|
|
15754
|
-
if (!
|
|
15755
|
-
|
|
15922
|
+
const configDir = path19.dirname(configPath);
|
|
15923
|
+
if (!fs24.existsSync(configDir)) {
|
|
15924
|
+
fs24.mkdirSync(configDir, { recursive: true });
|
|
15756
15925
|
}
|
|
15757
15926
|
atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
|
|
15758
15927
|
console.log("\nDone! Summary of changes:");
|
|
@@ -15779,12 +15948,12 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15779
15948
|
const pluginDir = resolveOpenclawPluginDir(opts.pluginDir);
|
|
15780
15949
|
const managedTargetDir = resolveOpenclawManagedPluginDir();
|
|
15781
15950
|
const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
|
|
15782
|
-
const fallbackMemoryDir =
|
|
15951
|
+
const fallbackMemoryDir = path19.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
|
|
15783
15952
|
const packageSpec = buildOpenclawManagedUpgradePackageSpec(opts.version);
|
|
15784
|
-
const configExistedBefore =
|
|
15953
|
+
const configExistedBefore = fs24.existsSync(configPath);
|
|
15785
15954
|
const existingConfig = readOpenclawConfig(configPath);
|
|
15786
15955
|
const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
|
|
15787
|
-
const preservedMemoryDir = opts.memoryDir ?
|
|
15956
|
+
const preservedMemoryDir = opts.memoryDir ? path19.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
|
|
15788
15957
|
console.log(`OpenClaw config: ${configPath}`);
|
|
15789
15958
|
console.log(`Plugin dir: ${pluginDir}`);
|
|
15790
15959
|
if (legacyPluginDirForBackup) {
|
|
@@ -15792,7 +15961,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15792
15961
|
}
|
|
15793
15962
|
console.log(`Memory dir: ${preservedMemoryDir}`);
|
|
15794
15963
|
console.log(`Package spec: ${packageSpec}`);
|
|
15795
|
-
console.log(`Backup root: ${
|
|
15964
|
+
console.log(`Backup root: ${path19.join(resolveOpenclawStateDir(), "backups")}`);
|
|
15796
15965
|
const plannedActions = [
|
|
15797
15966
|
`backup openclaw.json and the existing ${REMNIC_OPENCLAW_PLUGIN_ID} extension`,
|
|
15798
15967
|
...legacyPluginDirForBackup ? [`backup the existing ${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID} extension without modifying it`] : [],
|
|
@@ -15830,9 +15999,9 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15830
15999
|
assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
|
|
15831
16000
|
}
|
|
15832
16001
|
const backupDir = createOpenclawUpgradeBackupDir();
|
|
15833
|
-
const configBackupPath =
|
|
15834
|
-
const pluginBackupDir =
|
|
15835
|
-
const legacyPluginBackupDir = legacyPluginDirForBackup ?
|
|
16002
|
+
const configBackupPath = path19.join(backupDir, "openclaw.json");
|
|
16003
|
+
const pluginBackupDir = path19.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
|
|
16004
|
+
const legacyPluginBackupDir = legacyPluginDirForBackup ? path19.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
|
|
15836
16005
|
const backupNotes = [];
|
|
15837
16006
|
if (backupPathIfPresent(configPath, configBackupPath)) {
|
|
15838
16007
|
backupNotes.push(`+ Backed up config to ${configBackupPath}`);
|
|
@@ -15882,7 +16051,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15882
16051
|
const managedRollbackDir = publishedInstallError ? publishedInstallError.managedRollbackDir : installResult?.managedRollbackDir;
|
|
15883
16052
|
const managedRollbackTargetDir = publishedInstallError?.managedRollbackTargetDir ?? installResult?.managedRollbackTargetDir ?? managedTargetDir;
|
|
15884
16053
|
const requiresHostManagedRestore = publishedInstallError?.requiresHostManagedRestore ?? installResult?.requiresHostManagedRestore ?? false;
|
|
15885
|
-
const managedRollbackSharesPluginDir = managedRollbackDir &&
|
|
16054
|
+
const managedRollbackSharesPluginDir = managedRollbackDir && path19.resolve(managedRollbackTargetDir) === path19.resolve(pluginDir);
|
|
15886
16055
|
const pluginRollbackDir = managedRollbackSharesPluginDir ? requiresHostManagedRestore ? rollbackDir : rollbackDir ?? managedRollbackDir : rollbackDir;
|
|
15887
16056
|
const shouldRestorePlugin = Boolean(
|
|
15888
16057
|
installResult && !requiresHostManagedRestore || pluginRollbackDir || publishedInstallError?.shouldRestoreBackup
|
|
@@ -15939,7 +16108,7 @@ async function cmdOpenclawUpgrade(opts) {
|
|
|
15939
16108
|
rollbackErrors.push(error);
|
|
15940
16109
|
}
|
|
15941
16110
|
if (pendingConfigRestoreError) rollbackErrors.push(pendingConfigRestoreError);
|
|
15942
|
-
if (managedRollbackDir &&
|
|
16111
|
+
if (managedRollbackDir && path19.resolve(managedRollbackTargetDir) !== path19.resolve(pluginDir) && !requiresHostManagedRestore) {
|
|
15943
16112
|
try {
|
|
15944
16113
|
rollbackNotes.push(
|
|
15945
16114
|
...rollbackOpenclawUpgrade({
|
|
@@ -16005,16 +16174,16 @@ async function cmdOpenclawMigrateEngram(opts) {
|
|
|
16005
16174
|
console.log(" - Re-apply any local source patches to the new package only after verifying the published build.");
|
|
16006
16175
|
}
|
|
16007
16176
|
function createOpenclawUpgradeBackupDir() {
|
|
16008
|
-
const backupsRoot =
|
|
16009
|
-
|
|
16010
|
-
return
|
|
16177
|
+
const backupsRoot = path19.join(resolveOpenclawStateDir(), "backups");
|
|
16178
|
+
fs24.mkdirSync(backupsRoot, { recursive: true });
|
|
16179
|
+
return fs24.mkdtempSync(path19.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
|
|
16011
16180
|
}
|
|
16012
16181
|
async function cmdTaxonomy(rest) {
|
|
16013
16182
|
initLogger5();
|
|
16014
16183
|
const configPath = resolveConfigPath();
|
|
16015
|
-
const raw =
|
|
16016
|
-
const remnicCfg =
|
|
16017
|
-
const config =
|
|
16184
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
16185
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
16186
|
+
const config = parseConfig15(remnicCfg);
|
|
16018
16187
|
if (!config.taxonomyEnabled) {
|
|
16019
16188
|
console.error(
|
|
16020
16189
|
"Taxonomy is disabled in config (taxonomyEnabled = false). Enable it to use taxonomy commands."
|
|
@@ -16049,9 +16218,9 @@ async function cmdTaxonomy(rest) {
|
|
|
16049
16218
|
const doc = generateResolverDocument(taxonomy);
|
|
16050
16219
|
console.log(doc);
|
|
16051
16220
|
if (config.taxonomyAutoGenResolver) {
|
|
16052
|
-
const resolverPath =
|
|
16053
|
-
|
|
16054
|
-
|
|
16221
|
+
const resolverPath = path19.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16222
|
+
fs24.mkdirSync(path19.dirname(resolverPath), { recursive: true });
|
|
16223
|
+
fs24.writeFileSync(resolverPath, doc);
|
|
16055
16224
|
console.error(`Written: ${resolverPath}`);
|
|
16056
16225
|
}
|
|
16057
16226
|
break;
|
|
@@ -16096,8 +16265,8 @@ async function cmdTaxonomy(rest) {
|
|
|
16096
16265
|
console.log(`Added category "${id}" (${name}).`);
|
|
16097
16266
|
if (config.taxonomyAutoGenResolver) {
|
|
16098
16267
|
const doc = generateResolverDocument(taxonomy);
|
|
16099
|
-
const resolverPath =
|
|
16100
|
-
|
|
16268
|
+
const resolverPath = path19.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16269
|
+
fs24.writeFileSync(resolverPath, doc);
|
|
16101
16270
|
console.error(`Regenerated: ${resolverPath}`);
|
|
16102
16271
|
}
|
|
16103
16272
|
break;
|
|
@@ -16127,8 +16296,8 @@ async function cmdTaxonomy(rest) {
|
|
|
16127
16296
|
console.log(`Removed category "${id}".`);
|
|
16128
16297
|
if (config.taxonomyAutoGenResolver) {
|
|
16129
16298
|
const doc = generateResolverDocument(taxonomy);
|
|
16130
|
-
const resolverPath =
|
|
16131
|
-
|
|
16299
|
+
const resolverPath = path19.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
|
|
16300
|
+
fs24.writeFileSync(resolverPath, doc);
|
|
16132
16301
|
console.error(`Regenerated: ${resolverPath}`);
|
|
16133
16302
|
}
|
|
16134
16303
|
break;
|
|
@@ -16319,12 +16488,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
|
|
|
16319
16488
|
`Unknown training-export format "${args.format}". ${validList}`
|
|
16320
16489
|
);
|
|
16321
16490
|
}
|
|
16322
|
-
if (!
|
|
16491
|
+
if (!fs24.existsSync(args.memoryDir)) {
|
|
16323
16492
|
throw new Error(
|
|
16324
16493
|
`--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
|
|
16325
16494
|
);
|
|
16326
16495
|
}
|
|
16327
|
-
if (!
|
|
16496
|
+
if (!fs24.statSync(args.memoryDir).isDirectory()) {
|
|
16328
16497
|
throw new Error(
|
|
16329
16498
|
`--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
|
|
16330
16499
|
);
|
|
@@ -16409,11 +16578,11 @@ async function runTrainingExport(args, stdout = process.stdout) {
|
|
|
16409
16578
|
);
|
|
16410
16579
|
}
|
|
16411
16580
|
const formatted = adapter.formatRecords(records);
|
|
16412
|
-
const outDir =
|
|
16413
|
-
|
|
16581
|
+
const outDir = path19.dirname(args.output);
|
|
16582
|
+
fs24.mkdirSync(outDir, { recursive: true });
|
|
16414
16583
|
const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
|
|
16415
|
-
|
|
16416
|
-
|
|
16584
|
+
fs24.writeFileSync(tmpPath, formatted, "utf-8");
|
|
16585
|
+
fs24.renameSync(tmpPath, args.output);
|
|
16417
16586
|
stdout.write(
|
|
16418
16587
|
`Exported ${records.length} records to ${args.output} (${adapter.name} format)
|
|
16419
16588
|
`
|
|
@@ -16526,7 +16695,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16526
16695
|
case "tree": {
|
|
16527
16696
|
const subAction = rest[0];
|
|
16528
16697
|
const json = rest.includes("--json");
|
|
16529
|
-
const outputDir = resolveFlag(rest, "--output") ??
|
|
16698
|
+
const outputDir = resolveFlag(rest, "--output") ?? path19.join(process.cwd(), ".remnic", "context-tree");
|
|
16530
16699
|
const categoriesFlag = resolveFlag(rest, "--categories");
|
|
16531
16700
|
const categories = categoriesFlag ? categoriesFlag.split(",") : void 0;
|
|
16532
16701
|
const maxPerCategoryRaw = resolveFlag(rest, "--max-per-category");
|
|
@@ -16591,7 +16760,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16591
16760
|
}
|
|
16592
16761
|
}, 500);
|
|
16593
16762
|
};
|
|
16594
|
-
|
|
16763
|
+
fs24.watch(memoryDir, { recursive: true }, (_event, filename) => {
|
|
16595
16764
|
if (filename && filename.startsWith(".")) return;
|
|
16596
16765
|
rebuild();
|
|
16597
16766
|
});
|
|
@@ -16599,12 +16768,12 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
16599
16768
|
});
|
|
16600
16769
|
} else if (subAction === "validate") {
|
|
16601
16770
|
const treeDir = outputDir;
|
|
16602
|
-
if (!
|
|
16771
|
+
if (!fs24.existsSync(treeDir)) {
|
|
16603
16772
|
console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
|
|
16604
16773
|
process.exit(1);
|
|
16605
16774
|
}
|
|
16606
|
-
const indexPath =
|
|
16607
|
-
if (!
|
|
16775
|
+
const indexPath = path19.join(treeDir, "INDEX.md");
|
|
16776
|
+
if (!fs24.existsSync(indexPath)) {
|
|
16608
16777
|
console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
|
|
16609
16778
|
process.exit(1);
|
|
16610
16779
|
}
|
|
@@ -16797,6 +16966,15 @@ Other:
|
|
|
16797
16966
|
case "okf":
|
|
16798
16967
|
await runOkfBinaryCommand(rest);
|
|
16799
16968
|
break;
|
|
16969
|
+
case "export":
|
|
16970
|
+
await runExportOkfBinaryCommand(rest);
|
|
16971
|
+
break;
|
|
16972
|
+
case "standup":
|
|
16973
|
+
await runStandupBinaryCommand(rest);
|
|
16974
|
+
break;
|
|
16975
|
+
case "codegraph":
|
|
16976
|
+
await runCodegraphBinaryCommand(rest);
|
|
16977
|
+
break;
|
|
16800
16978
|
case "external-wiki": {
|
|
16801
16979
|
await runExternalWikiBinaryCommand(rest);
|
|
16802
16980
|
break;
|
|
@@ -16810,10 +16988,10 @@ Other:
|
|
|
16810
16988
|
const targetFactory = async () => {
|
|
16811
16989
|
if (!orchestratorSingleton) {
|
|
16812
16990
|
const configPath = resolveConfigPath();
|
|
16813
|
-
const raw =
|
|
16814
|
-
const remnicCfg =
|
|
16815
|
-
const config =
|
|
16816
|
-
orchestratorSingleton = new
|
|
16991
|
+
const raw = fs24.existsSync(configPath) ? JSON.parse(fs24.readFileSync(configPath, "utf8")) : {};
|
|
16992
|
+
const remnicCfg = resolveRemnicConfigRecord14(raw);
|
|
16993
|
+
const config = parseConfig15(remnicCfg);
|
|
16994
|
+
orchestratorSingleton = new Orchestrator10(config);
|
|
16817
16995
|
await orchestratorSingleton.initialize();
|
|
16818
16996
|
await orchestratorSingleton.deferredReady;
|
|
16819
16997
|
}
|
|
@@ -17014,6 +17192,10 @@ Usage:
|
|
|
17014
17192
|
remnic okf <lint|sweep> [--json]
|
|
17015
17193
|
OKF v0.1 conformance: lint reports missing frontmatter/type findings,
|
|
17016
17194
|
sweep backfills missing type values (okf.sweepEnabled).
|
|
17195
|
+
remnic export okf --out <dir>
|
|
17196
|
+
Write a portable OKF v0.1 knowledge bundle (plaintext interchange).
|
|
17197
|
+
remnic standup [--date YYYY-MM-DD]
|
|
17198
|
+
Deterministic yesterday/today/blockers brief plus an activity grid.
|
|
17017
17199
|
remnic external-wiki search <query...> [--wiki-id <id>] [--limit <1-20>] [--max-chars-per-hit <100-8000>] [--json]
|
|
17018
17200
|
remnic doctor Run diagnostics
|
|
17019
17201
|
remnic config Show current config
|