@remnic/cli 9.21.0 → 9.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +499 -338
  2. package/package.json +32 -28
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ async function persistEnrichmentCandidate(storage, entityName, candidate) {
18
18
  }
19
19
 
20
20
  // src/index.ts
21
- import fs10 from "fs";
21
+ import fs11 from "fs";
22
22
  import os from "os";
23
23
  import path12 from "path";
24
24
  import { createHash as createHash2 } from "crypto";
@@ -26,11 +26,11 @@ import * as childProcess2 from "child_process";
26
26
  import { fileURLToPath as fileURLToPath4 } from "url";
27
27
  import { gzipSync } from "zlib";
28
28
  import {
29
- parseConfig as parseConfig3,
29
+ parseConfig as parseConfig4,
30
30
  isOpenaiApiKeyDisabled,
31
31
  resolveEnvVars,
32
- resolveRemnicConfigRecord as resolveRemnicConfigRecord3,
33
- Orchestrator as Orchestrator2,
32
+ resolveRemnicConfigRecord as resolveRemnicConfigRecord4,
33
+ Orchestrator as Orchestrator3,
34
34
  EngramAccessService as EngramAccessService2,
35
35
  initLogger as initLogger2,
36
36
  onboard,
@@ -139,6 +139,56 @@ import {
139
139
  validateCapabilitiesForMint
140
140
  } from "@remnic/core";
141
141
 
142
+ // src/commands/meetings.ts
143
+ import fs from "fs";
144
+ import {
145
+ Orchestrator,
146
+ parseConfig,
147
+ resolveRemnicConfigRecord,
148
+ runMeetingsCliCommand
149
+ } from "@remnic/core";
150
+ async function runMeetingsBinaryCommand(rest) {
151
+ const meetingsArgs = rest.length === 0 || rest[0] === "--help" || rest[0] === "-h" ? ["help"] : rest;
152
+ let meetingsOrchestrator;
153
+ try {
154
+ let meetingsService;
155
+ try {
156
+ const configPath = resolveConfigPath();
157
+ const raw = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, "utf8")) : {};
158
+ const config = parseConfig(resolveRemnicConfigRecord(raw));
159
+ meetingsOrchestrator = new Orchestrator(config);
160
+ await meetingsOrchestrator.initialize();
161
+ await meetingsOrchestrator.deferredReady;
162
+ meetingsService = await meetingsOrchestrator.getMeetingsService();
163
+ } catch {
164
+ console.error(
165
+ "meetings: failed to load the Remnic config or start the memory engine \u2014 run `remnic doctor` and check the config file for errors"
166
+ );
167
+ process.exitCode = 1;
168
+ return;
169
+ }
170
+ const code = await runMeetingsCliCommand(
171
+ { store: meetingsService.store, builder: meetingsService.builder, config: meetingsService.config },
172
+ meetingsArgs,
173
+ { stdout: process.stdout, stderr: process.stderr }
174
+ );
175
+ if (code !== 0) process.exitCode = code;
176
+ } catch (err) {
177
+ console.error(err instanceof Error ? err.message : String(err));
178
+ process.exitCode = 1;
179
+ } finally {
180
+ if (meetingsOrchestrator) {
181
+ const maybeShutdown = meetingsOrchestrator.shutdown;
182
+ if (typeof maybeShutdown === "function") {
183
+ try {
184
+ await maybeShutdown.call(meetingsOrchestrator);
185
+ } catch {
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+
142
192
  // src/optional-module-loader.ts
143
193
  function isSpecifierNotFoundError(err, specifier) {
144
194
  if (!err || typeof err !== "object") {
@@ -321,8 +371,8 @@ function renderReplayResult(result, targetNamespace, format) {
321
371
  }
322
372
 
323
373
  // src/quarantine-replay.ts
324
- import * as fs from "fs";
325
- import { EngramAccessService, Orchestrator, initLogger, parseConfig, resolveRemnicConfigRecord } from "@remnic/core";
374
+ import * as fs2 from "fs";
375
+ import { EngramAccessService, Orchestrator as Orchestrator2, initLogger, parseConfig as parseConfig2, resolveRemnicConfigRecord as resolveRemnicConfigRecord2 } from "@remnic/core";
326
376
  import { WriteQuarantineStore } from "@remnic/core/write-quarantine.js";
327
377
  function valueFlag(args, flag) {
328
378
  const occurrences = args.filter((a) => a === flag).length;
@@ -370,9 +420,9 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
370
420
  let orchestrator;
371
421
  try {
372
422
  const configPath = resolveConfigPath2();
373
- const raw = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, "utf8")) : {};
374
- const config = parseConfig(resolveRemnicConfigRecord(raw));
375
- orchestrator = new Orchestrator(config);
423
+ const raw = fs2.existsSync(configPath) ? JSON.parse(fs2.readFileSync(configPath, "utf8")) : {};
424
+ const config = parseConfig2(resolveRemnicConfigRecord2(raw));
425
+ orchestrator = new Orchestrator2(config);
376
426
  await orchestrator.initialize();
377
427
  await orchestrator.deferredReady;
378
428
  const service = new EngramAccessService(orchestrator);
@@ -402,15 +452,15 @@ async function runQuarantineReplay(rest, format, resolveConfigPath2) {
402
452
  }
403
453
 
404
454
  // src/offline-impression-rotation.ts
405
- import fs2 from "fs";
406
- import { parseConfig as parseConfig2, resolveRemnicConfigRecord as resolveRemnicConfigRecord2, drainPendingImpressionsForOfflineSync } from "@remnic/core";
455
+ import fs3 from "fs";
456
+ import { parseConfig as parseConfig3, resolveRemnicConfigRecord as resolveRemnicConfigRecord3, drainPendingImpressionsForOfflineSync } from "@remnic/core";
407
457
  import { LastRecallStore } from "@remnic/core/recall-state";
408
458
  function parseConfigQuietly(raw) {
409
459
  const originalWarn = console.warn;
410
460
  console.warn = () => {
411
461
  };
412
462
  try {
413
- return parseConfig2(resolveRemnicConfigRecord2(raw));
463
+ return parseConfig3(resolveRemnicConfigRecord3(raw));
414
464
  } finally {
415
465
  console.warn = originalWarn;
416
466
  }
@@ -424,7 +474,7 @@ var OFFLINE_CONFIG_KEYS = [
424
474
  function pickOfflineConfigRecord(raw) {
425
475
  let resolved;
426
476
  try {
427
- resolved = resolveRemnicConfigRecord2(raw);
477
+ resolved = resolveRemnicConfigRecord3(raw);
428
478
  } catch {
429
479
  resolved = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
430
480
  }
@@ -437,7 +487,7 @@ function pickOfflineConfigRecord(raw) {
437
487
  function resolveOfflineImpressionRotation(configPath) {
438
488
  let raw;
439
489
  try {
440
- raw = fs2.existsSync(configPath) ? JSON.parse(fs2.readFileSync(configPath, "utf8")) : {};
490
+ raw = fs3.existsSync(configPath) ? JSON.parse(fs3.readFileSync(configPath, "utf8")) : {};
441
491
  } catch {
442
492
  throw new Error(
443
493
  `cannot read recall-impression rotation from ${configPath}: config file could not be read as JSON`
@@ -467,7 +517,7 @@ async function drainOfflineSyncImpressions(memoryDir, rotation) {
467
517
 
468
518
  // src/offline-storage-io.ts
469
519
  import { mkdtemp, readdir, lstat, rm } from "fs/promises";
470
- import fs3 from "fs";
520
+ import fs4 from "fs";
471
521
  import path from "path";
472
522
  import { createHash, createDecipheriv } from "crypto";
473
523
  import {
@@ -603,7 +653,7 @@ async function* readOfflineSyncFileChunks(options) {
603
653
  });
604
654
  }
605
655
  async function readFilePrefix(filePath, length) {
606
- const handle = await fs3.promises.open(filePath, "r");
656
+ const handle = await fs4.promises.open(filePath, "r");
607
657
  try {
608
658
  const out = Buffer.alloc(length);
609
659
  const { bytesRead } = await handle.read(out, 0, length, 0);
@@ -613,7 +663,7 @@ async function readFilePrefix(filePath, length) {
613
663
  }
614
664
  }
615
665
  async function* readPlainOfflineFileChunks(filePath, chunkSize) {
616
- const stream = fs3.createReadStream(filePath, { highWaterMark: chunkSize });
666
+ const stream = fs4.createReadStream(filePath, { highWaterMark: chunkSize });
617
667
  for await (const chunk of stream) {
618
668
  yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
619
669
  }
@@ -656,9 +706,9 @@ async function* readEncryptedOfflineFileChunks(options) {
656
706
  });
657
707
  decipher.setAuthTag(authTag);
658
708
  decipher.setAAD(Buffer.concat([secureStoreEnvelopeHeaderAad(salt), aad]));
659
- const output = fs3.createWriteStream(tempPath, { mode: 384 });
709
+ const output = fs4.createWriteStream(tempPath, { mode: 384 });
660
710
  try {
661
- const stream = fs3.createReadStream(options.filePath, {
711
+ const stream = fs4.createReadStream(options.filePath, {
662
712
  start: MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE,
663
713
  highWaterMark: options.chunkSize
664
714
  });
@@ -954,7 +1004,7 @@ function assertBenchModuleFreshForDevelopment() {
954
1004
  }
955
1005
 
956
1006
  // src/daemon-service-candidates.ts
957
- import fs4 from "fs";
1007
+ import fs5 from "fs";
958
1008
  import path4 from "path";
959
1009
  var LAUNCHD_LABEL = "ai.remnic.daemon";
960
1010
  var LEGACY_REMNIC_SERVER_LAUNCHD_LABEL = "ai.remnic.server";
@@ -976,7 +1026,7 @@ function systemdUnitPaths(homeDir) {
976
1026
  function anyFileExists(paths) {
977
1027
  return paths.some((candidate) => {
978
1028
  try {
979
- return fs4.statSync(candidate).isFile();
1029
+ return fs5.statSync(candidate).isFile();
980
1030
  } catch {
981
1031
  return false;
982
1032
  }
@@ -988,7 +1038,7 @@ function commandNames(command) {
988
1038
  }
989
1039
  function isRunnableNodeScript(filePath) {
990
1040
  try {
991
- const text = fs4.readFileSync(filePath, "utf8").slice(0, 4096);
1041
+ const text = fs5.readFileSync(filePath, "utf8").slice(0, 4096);
992
1042
  const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
993
1043
  if (/^#!.*\bnode\b/.test(firstLine)) return true;
994
1044
  if (firstLine.startsWith("#!")) return false;
@@ -1001,7 +1051,7 @@ function isRunnableNodeScript(filePath) {
1001
1051
  function resolveShimNodeScript(filePath) {
1002
1052
  let text;
1003
1053
  try {
1004
- text = fs4.readFileSync(filePath, "utf8").slice(0, 16384);
1054
+ text = fs5.readFileSync(filePath, "utf8").slice(0, 16384);
1005
1055
  } catch {
1006
1056
  return void 0;
1007
1057
  }
@@ -1013,8 +1063,8 @@ function resolveShimNodeScript(filePath) {
1013
1063
  const candidate = raw.replaceAll("${basedir}", basedir).replaceAll("$basedir", basedir).replaceAll("\\ ", " ");
1014
1064
  const resolved = path4.isAbsolute(candidate) ? candidate : path4.resolve(basedir, candidate);
1015
1065
  try {
1016
- if (fs4.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
1017
- return fs4.realpathSync(resolved);
1066
+ if (fs5.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
1067
+ return fs5.realpathSync(resolved);
1018
1068
  }
1019
1069
  } catch {
1020
1070
  }
@@ -1022,7 +1072,7 @@ function resolveShimNodeScript(filePath) {
1022
1072
  return void 0;
1023
1073
  }
1024
1074
  function resolveRunnableNodeScript(filePath) {
1025
- const realPath = fs4.realpathSync(filePath);
1075
+ const realPath = fs5.realpathSync(filePath);
1026
1076
  if (isRunnableNodeScript(realPath)) return realPath;
1027
1077
  return resolveShimNodeScript(realPath);
1028
1078
  }
@@ -1032,9 +1082,9 @@ function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
1032
1082
  for (const name of commandNames(command)) {
1033
1083
  const candidate = path4.join(dir, name);
1034
1084
  try {
1035
- const stat = fs4.statSync(candidate);
1085
+ const stat = fs5.statSync(candidate);
1036
1086
  if (!stat.isFile()) continue;
1037
- if (process.platform !== "win32") fs4.accessSync(candidate, fs4.constants.X_OK);
1087
+ if (process.platform !== "win32") fs5.accessSync(candidate, fs5.constants.X_OK);
1038
1088
  const runnable = resolveRunnableNodeScript(candidate);
1039
1089
  if (runnable) return runnable;
1040
1090
  } catch {
@@ -2389,7 +2439,7 @@ function finalizeBenchStatus(filePath) {
2389
2439
  }
2390
2440
 
2391
2441
  // src/bench-fallback.ts
2392
- import fs5 from "fs";
2442
+ import fs6 from "fs";
2393
2443
  import path7 from "path";
2394
2444
  var FALLBACK_RESULTS_DIRNAME = "fallback-runs";
2395
2445
  function buildBenchRunnerArgs(parsed, benchmarkId, outputDir) {
@@ -2461,7 +2511,7 @@ function createFallbackBenchOutputDir(resultsDir, benchmarkId, pid, startedAtMs
2461
2511
  );
2462
2512
  }
2463
2513
  function resolveFallbackBenchResultPath(outputDir) {
2464
- const entries = fs5.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
2514
+ const entries = fs6.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
2465
2515
  if (entries.length === 0) {
2466
2516
  throw new Error(`Fallback benchmark runner did not write a JSON result artifact in ${outputDir}`);
2467
2517
  }
@@ -2469,7 +2519,7 @@ function resolveFallbackBenchResultPath(outputDir) {
2469
2519
  }
2470
2520
 
2471
2521
  // src/openclaw-upgrade-swap.ts
2472
- import fs6 from "fs";
2522
+ import fs7 from "fs";
2473
2523
  import path8 from "path";
2474
2524
  function describeError(error) {
2475
2525
  return error instanceof Error ? error.message : String(error);
@@ -2481,7 +2531,7 @@ function createSiblingTempFilePath(targetPath, label) {
2481
2531
  function resolveAtomicWriteMode(targetPath, explicitMode) {
2482
2532
  if (explicitMode !== void 0) return explicitMode;
2483
2533
  try {
2484
- return fs6.statSync(targetPath).mode & 4095;
2534
+ return fs7.statSync(targetPath).mode & 4095;
2485
2535
  } catch (error) {
2486
2536
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
2487
2537
  return 384;
@@ -2491,8 +2541,8 @@ function resolveAtomicWriteMode(targetPath, explicitMode) {
2491
2541
  }
2492
2542
  function resolveAtomicReplacementPath(targetPath) {
2493
2543
  try {
2494
- if (fs6.lstatSync(targetPath).isSymbolicLink()) {
2495
- return fs6.realpathSync(targetPath);
2544
+ if (fs7.lstatSync(targetPath).isSymbolicLink()) {
2545
+ return fs7.realpathSync(targetPath);
2496
2546
  }
2497
2547
  } catch (error) {
2498
2548
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -2509,7 +2559,7 @@ function createSiblingSwapPath(targetDir, label) {
2509
2559
  function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
2510
2560
  if (!displacedDir) return void 0;
2511
2561
  try {
2512
- fs6.rmSync(displacedDir, { recursive: true, force: true });
2562
+ fs7.rmSync(displacedDir, { recursive: true, force: true });
2513
2563
  return void 0;
2514
2564
  } catch (error) {
2515
2565
  return `Warning: ${context}, but failed to remove the displaced plugin copy at ${displacedDir}: ${describeError(error)}`;
@@ -2517,55 +2567,55 @@ function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
2517
2567
  }
2518
2568
  function atomicWriteFileSync(targetPath, data, options = {}) {
2519
2569
  const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
2520
- fs6.mkdirSync(path8.dirname(resolvedTargetPath), { recursive: true });
2570
+ fs7.mkdirSync(path8.dirname(resolvedTargetPath), { recursive: true });
2521
2571
  const tempPath = createSiblingTempFilePath(resolvedTargetPath, "write");
2522
2572
  const mode = resolveAtomicWriteMode(resolvedTargetPath, options.mode);
2523
2573
  try {
2524
2574
  if (options.hooks?.writeTempFileSync) {
2525
2575
  options.hooks.writeTempFileSync(tempPath);
2526
2576
  } else {
2527
- fs6.writeFileSync(tempPath, data, { mode });
2577
+ fs7.writeFileSync(tempPath, data, { mode });
2528
2578
  }
2529
- fs6.chmodSync(tempPath, mode);
2530
- const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs6.renameSync;
2579
+ fs7.chmodSync(tempPath, mode);
2580
+ const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs7.renameSync;
2531
2581
  renameTempFileSync(tempPath, resolvedTargetPath);
2532
2582
  } catch (error) {
2533
- fs6.rmSync(tempPath, { force: true });
2583
+ fs7.rmSync(tempPath, { force: true });
2534
2584
  throw error;
2535
2585
  }
2536
2586
  }
2537
2587
  function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
2538
- if (!fs6.existsSync(sourcePath)) return;
2588
+ if (!fs7.existsSync(sourcePath)) return;
2539
2589
  const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
2540
- fs6.mkdirSync(path8.dirname(resolvedTargetPath), { recursive: true });
2590
+ fs7.mkdirSync(path8.dirname(resolvedTargetPath), { recursive: true });
2541
2591
  const tempPath = createSiblingTempFilePath(resolvedTargetPath, "copy");
2542
- const mode = fs6.statSync(sourcePath).mode & 4095;
2592
+ const mode = fs7.statSync(sourcePath).mode & 4095;
2543
2593
  try {
2544
- const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs6.copyFileSync;
2594
+ const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs7.copyFileSync;
2545
2595
  copyTempFileSync(sourcePath, tempPath);
2546
- fs6.chmodSync(tempPath, mode);
2547
- const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs6.renameSync;
2596
+ fs7.chmodSync(tempPath, mode);
2597
+ const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs7.renameSync;
2548
2598
  renameTempFileSync(tempPath, resolvedTargetPath);
2549
2599
  } catch (error) {
2550
- fs6.rmSync(tempPath, { force: true });
2600
+ fs7.rmSync(tempPath, { force: true });
2551
2601
  throw error;
2552
2602
  }
2553
2603
  }
2554
2604
  function swapDirectoryWithRollback(stagedDir, targetDir, rollbackDir) {
2555
2605
  let hasRollbackCopy = false;
2556
- fs6.mkdirSync(path8.dirname(targetDir), { recursive: true });
2557
- fs6.rmSync(rollbackDir, { recursive: true, force: true });
2558
- if (fs6.existsSync(targetDir)) {
2559
- fs6.renameSync(targetDir, rollbackDir);
2606
+ fs7.mkdirSync(path8.dirname(targetDir), { recursive: true });
2607
+ fs7.rmSync(rollbackDir, { recursive: true, force: true });
2608
+ if (fs7.existsSync(targetDir)) {
2609
+ fs7.renameSync(targetDir, rollbackDir);
2560
2610
  hasRollbackCopy = true;
2561
2611
  }
2562
2612
  try {
2563
- fs6.renameSync(stagedDir, targetDir);
2613
+ fs7.renameSync(stagedDir, targetDir);
2564
2614
  } catch (swapError) {
2565
- fs6.rmSync(targetDir, { recursive: true, force: true });
2566
- if (hasRollbackCopy && fs6.existsSync(rollbackDir)) {
2615
+ fs7.rmSync(targetDir, { recursive: true, force: true });
2616
+ if (hasRollbackCopy && fs7.existsSync(rollbackDir)) {
2567
2617
  try {
2568
- fs6.renameSync(rollbackDir, targetDir);
2618
+ fs7.renameSync(rollbackDir, targetDir);
2569
2619
  hasRollbackCopy = false;
2570
2620
  } catch (restoreError) {
2571
2621
  throw new AggregateError(
@@ -2580,7 +2630,7 @@ function swapDirectoryWithRollback(stagedDir, targetDir, rollbackDir) {
2580
2630
  }
2581
2631
  function cleanupRollbackDirectory(rollbackDir) {
2582
2632
  if (!rollbackDir) return;
2583
- fs6.rmSync(rollbackDir, { recursive: true, force: true });
2633
+ fs7.rmSync(rollbackDir, { recursive: true, force: true });
2584
2634
  }
2585
2635
  function cleanupRollbackDirectoryBestEffort(rollbackDir) {
2586
2636
  if (!rollbackDir) return void 0;
@@ -2592,20 +2642,20 @@ function cleanupRollbackDirectoryBestEffort(rollbackDir) {
2592
2642
  }
2593
2643
  }
2594
2644
  function restoreDirectoryFromRollback(targetDir, rollbackDir) {
2595
- if (!fs6.existsSync(rollbackDir)) {
2645
+ if (!fs7.existsSync(rollbackDir)) {
2596
2646
  throw new Error(`Rollback directory is missing: ${rollbackDir}`);
2597
2647
  }
2598
- fs6.mkdirSync(path8.dirname(targetDir), { recursive: true });
2599
- const displacedDir = fs6.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
2648
+ fs7.mkdirSync(path8.dirname(targetDir), { recursive: true });
2649
+ const displacedDir = fs7.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
2600
2650
  if (displacedDir) {
2601
- fs6.renameSync(targetDir, displacedDir);
2651
+ fs7.renameSync(targetDir, displacedDir);
2602
2652
  }
2603
2653
  try {
2604
- fs6.renameSync(rollbackDir, targetDir);
2654
+ fs7.renameSync(rollbackDir, targetDir);
2605
2655
  } catch (restoreError) {
2606
- if (displacedDir && fs6.existsSync(displacedDir)) {
2656
+ if (displacedDir && fs7.existsSync(displacedDir)) {
2607
2657
  try {
2608
- fs6.renameSync(displacedDir, targetDir);
2658
+ fs7.renameSync(displacedDir, targetDir);
2609
2659
  } catch (revertError) {
2610
2660
  throw new AggregateError(
2611
2661
  [restoreError, revertError],
@@ -2624,23 +2674,23 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
2624
2674
  );
2625
2675
  }
2626
2676
  function restoreDirectoryFromBackup(targetDir, backupDir) {
2627
- if (!fs6.existsSync(backupDir)) {
2677
+ if (!fs7.existsSync(backupDir)) {
2628
2678
  throw new Error(`Plugin backup directory is missing: ${backupDir}`);
2629
2679
  }
2630
- fs6.mkdirSync(path8.dirname(targetDir), { recursive: true });
2680
+ fs7.mkdirSync(path8.dirname(targetDir), { recursive: true });
2631
2681
  const stagedDir = createSiblingSwapPath(targetDir, "backup-restore");
2632
- const displacedDir = fs6.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
2633
- fs6.cpSync(backupDir, stagedDir, { recursive: true });
2682
+ const displacedDir = fs7.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
2683
+ fs7.cpSync(backupDir, stagedDir, { recursive: true });
2634
2684
  if (displacedDir) {
2635
- fs6.renameSync(targetDir, displacedDir);
2685
+ fs7.renameSync(targetDir, displacedDir);
2636
2686
  }
2637
2687
  try {
2638
- fs6.renameSync(stagedDir, targetDir);
2688
+ fs7.renameSync(stagedDir, targetDir);
2639
2689
  } catch (restoreError) {
2640
- fs6.rmSync(targetDir, { recursive: true, force: true });
2641
- if (displacedDir && fs6.existsSync(displacedDir)) {
2690
+ fs7.rmSync(targetDir, { recursive: true, force: true });
2691
+ if (displacedDir && fs7.existsSync(displacedDir)) {
2642
2692
  try {
2643
- fs6.renameSync(displacedDir, targetDir);
2693
+ fs7.renameSync(displacedDir, targetDir);
2644
2694
  } catch (revertError) {
2645
2695
  throw new AggregateError(
2646
2696
  [restoreError, revertError],
@@ -2648,7 +2698,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
2648
2698
  );
2649
2699
  }
2650
2700
  }
2651
- fs6.rmSync(stagedDir, { recursive: true, force: true });
2701
+ fs7.rmSync(stagedDir, { recursive: true, force: true });
2652
2702
  throw new Error(
2653
2703
  `Failed to restore the plugin backup into ${targetDir}. The durable backup remains preserved at ${backupDir}.`,
2654
2704
  { cause: restoreError }
@@ -2674,7 +2724,7 @@ function rollbackOpenclawUpgrade({
2674
2724
  let rollbackRestoreError;
2675
2725
  let pluginRestored = false;
2676
2726
  try {
2677
- if (rollbackDir && fs6.existsSync(rollbackDir)) {
2727
+ if (rollbackDir && fs7.existsSync(rollbackDir)) {
2678
2728
  const cleanupWarning = restoreDirectoryFromRollback(pluginDir, rollbackDir);
2679
2729
  notes.push(`Restored previous plugin from rollback copy at ${rollbackDir}`);
2680
2730
  if (cleanupWarning) notes.push(cleanupWarning);
@@ -2684,7 +2734,7 @@ function rollbackOpenclawUpgrade({
2684
2734
  rollbackRestoreError = error instanceof Error ? error.message : String(error);
2685
2735
  }
2686
2736
  try {
2687
- if (!pluginRestored && pluginBackupDir && fs6.existsSync(pluginBackupDir)) {
2737
+ if (!pluginRestored && pluginBackupDir && fs7.existsSync(pluginBackupDir)) {
2688
2738
  const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
2689
2739
  if (rollbackRestoreError) {
2690
2740
  notes.push(
@@ -2711,7 +2761,7 @@ function rollbackOpenclawUpgrade({
2711
2761
  notes.push("No previous plugin copy was available for automatic restore");
2712
2762
  }
2713
2763
  try {
2714
- if (configBackupPath && fs6.existsSync(configBackupPath)) {
2764
+ if (configBackupPath && fs7.existsSync(configBackupPath)) {
2715
2765
  restoreFileFromBackup(configPath, configBackupPath);
2716
2766
  notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
2717
2767
  }
@@ -2751,7 +2801,7 @@ Run this manually when you're ready:
2751
2801
  }
2752
2802
 
2753
2803
  // src/daemon-service.ts
2754
- import fs7 from "fs";
2804
+ import fs8 from "fs";
2755
2805
  import path9 from "path";
2756
2806
  import * as childProcess from "child_process";
2757
2807
  import { fileURLToPath as fileURLToPath3 } from "url";
@@ -2763,7 +2813,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
2763
2813
  processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
2764
2814
  }
2765
2815
  function resolveServerBinDetails(options = {}) {
2766
- const existsSync4 = options.existsSync ?? fs7.existsSync;
2816
+ const existsSync4 = options.existsSync ?? fs8.existsSync;
2767
2817
  const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
2768
2818
  const moduleDir = options.moduleDir ?? thisModuleDir;
2769
2819
  const packageResolve = options.packageResolve ?? resolveImportSpecifier;
@@ -2822,8 +2872,8 @@ function resolveServerBin(options = {}) {
2822
2872
  return resolveServerBinDetails(options).path;
2823
2873
  }
2824
2874
  function readVerifiedDaemonPid(options) {
2825
- const readFileSync4 = options.readFileSync ?? fs7.readFileSync;
2826
- const unlinkSync = options.unlinkSync ?? fs7.unlinkSync;
2875
+ const readFileSync4 = options.readFileSync ?? fs8.readFileSync;
2876
+ const unlinkSync = options.unlinkSync ?? fs8.unlinkSync;
2827
2877
  const processKill = options.processKill ?? process.kill;
2828
2878
  const platform = options.platform ?? process.platform;
2829
2879
  const execFileSync3 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
@@ -2923,8 +2973,8 @@ function removePidFileBestEffort(file, unlinkSync) {
2923
2973
  }
2924
2974
  }
2925
2975
  function inspectLaunchdPlist(plistPath, options = {}) {
2926
- const existsSync4 = options.existsSync ?? fs7.existsSync;
2927
- const readFileSync4 = options.readFileSync ?? fs7.readFileSync;
2976
+ const existsSync4 = options.existsSync ?? fs8.existsSync;
2977
+ const readFileSync4 = options.readFileSync ?? fs8.readFileSync;
2928
2978
  if (!existsSync4(plistPath)) {
2929
2979
  return {
2930
2980
  installed: false,
@@ -3158,7 +3208,7 @@ function stripConfigArgv(args) {
3158
3208
  }
3159
3209
 
3160
3210
  // src/import-dispatch.ts
3161
- import fs8 from "fs";
3211
+ import fs9 from "fs";
3162
3212
  import {
3163
3213
  runImporter,
3164
3214
  validateImportBatchSize,
@@ -3672,7 +3722,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
3672
3722
  let materializedTarget;
3673
3723
  let materializePromise;
3674
3724
  const io = {
3675
- readFile: ioOverrides.readFile ?? (async (p) => fs8.promises.readFile(p, "utf-8")),
3725
+ readFile: ioOverrides.readFile ?? (async (p) => fs9.promises.readFile(p, "utf-8")),
3676
3726
  loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
3677
3727
  runImporter: ioOverrides.runImporter ?? runImporter,
3678
3728
  getWriteTarget: async () => {
@@ -3744,8 +3794,48 @@ function takeOptionalValue(args, flag) {
3744
3794
  return takeValue(args, flag);
3745
3795
  }
3746
3796
 
3797
+ // src/capture-dispatch.ts
3798
+ var SPECIFIER3 = "@remnic/capture-audio";
3799
+ var INSTALL_HINT = "`remnic capture audio` requires the optional @remnic/capture-audio package. Install it with: npm install @remnic/capture-audio";
3800
+ var USAGE = "usage: remnic capture audio <init|start|stop|status|devices|logs|download-model|janitor|enroll-self> [options]";
3801
+ function translateCaptureLoadError(err) {
3802
+ if (isSpecifierNotFoundError(err, SPECIFIER3)) return new Error(INSTALL_HINT);
3803
+ return err instanceof Error ? err : new Error(String(err));
3804
+ }
3805
+ async function defaultLoadCaptureAudio() {
3806
+ try {
3807
+ return await import(SPECIFIER3);
3808
+ } catch (err) {
3809
+ throw translateCaptureLoadError(err);
3810
+ }
3811
+ }
3812
+ async function cmdCapture(rest, io) {
3813
+ if (rest.length === 0 || rest[0] === "--help" || rest[0] === "-h") {
3814
+ io.stdout(USAGE);
3815
+ return rest.length === 0 ? 2 : 0;
3816
+ }
3817
+ if (rest[0] !== "audio") {
3818
+ io.stderr(`unknown capture subgroup '${rest[0]}'. ${USAGE}`);
3819
+ return 2;
3820
+ }
3821
+ const forwarded = rest.slice(1);
3822
+ let mod;
3823
+ try {
3824
+ mod = await (io.loadCaptureAudio ?? defaultLoadCaptureAudio)();
3825
+ } catch (err) {
3826
+ io.stderr(err instanceof Error ? err.message : String(err));
3827
+ return 2;
3828
+ }
3829
+ return mod.runCapture({
3830
+ argv: forwarded,
3831
+ stdout: io.stdout,
3832
+ stderr: io.stderr,
3833
+ spawnArgvPrefix: [process.argv[1], "capture", "audio"]
3834
+ });
3835
+ }
3836
+
3747
3837
  // src/import-lossless-claw-cmd.ts
3748
- import fs9 from "fs";
3838
+ import fs10 from "fs";
3749
3839
  import path11 from "path";
3750
3840
  import {
3751
3841
  applyLcmSchema,
@@ -3831,13 +3921,13 @@ function parseImportLosslessClawArgs(argv) {
3831
3921
  }
3832
3922
 
3833
3923
  // src/optional-import-lossless-claw.ts
3834
- var SPECIFIER3 = "@remnic/import-lossless-claw";
3924
+ var SPECIFIER4 = "@remnic/import-lossless-claw";
3835
3925
  var cached4;
3836
3926
  async function tryImport() {
3837
3927
  try {
3838
- return await import(SPECIFIER3);
3928
+ return await import(SPECIFIER4);
3839
3929
  } catch (err) {
3840
- if (isSpecifierNotFoundError(err, SPECIFIER3)) {
3930
+ if (isSpecifierNotFoundError(err, SPECIFIER4)) {
3841
3931
  return null;
3842
3932
  }
3843
3933
  throw err;
@@ -3857,15 +3947,15 @@ async function loadImportLosslessClawModule() {
3857
3947
 
3858
3948
  // src/import-lossless-claw-cmd.ts
3859
3949
  function assertDirectoryOrAbsent(p, label) {
3860
- if (fs9.existsSync(p) && !fs9.statSync(p).isDirectory()) {
3950
+ if (fs10.existsSync(p) && !fs10.statSync(p).isDirectory()) {
3861
3951
  throw new Error(`${label} is not a directory: ${p}`);
3862
3952
  }
3863
3953
  }
3864
3954
  function assertFile(p, label) {
3865
- if (!fs9.existsSync(p)) {
3955
+ if (!fs10.existsSync(p)) {
3866
3956
  throw new Error(`${label} does not exist: ${p}`);
3867
3957
  }
3868
- if (!fs9.statSync(p).isFile()) {
3958
+ if (!fs10.statSync(p).isFile()) {
3869
3959
  throw new Error(`${label} is not a file: ${p}`);
3870
3960
  }
3871
3961
  }
@@ -3897,7 +3987,7 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
3897
3987
  try {
3898
3988
  if (parsed.dryRun) {
3899
3989
  const lcmPath = path11.join(memoryDir, "state", "lcm.sqlite");
3900
- if (fs9.existsSync(lcmPath)) {
3990
+ if (fs10.existsSync(lcmPath)) {
3901
3991
  destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
3902
3992
  } else {
3903
3993
  destDb = mod.openInMemoryDestinationDatabase();
@@ -3946,6 +4036,74 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
3946
4036
  }
3947
4037
  }
3948
4038
 
4039
+ // src/bench-output-printer.ts
4040
+ function printStoredBenchResultSummary(result, summary) {
4041
+ console.log(`Run id: ${summary.id}`);
4042
+ printBenchPackageSummary(result, summary.path, "Stored result");
4043
+ }
4044
+ function printBenchStatusLine(jsonMode, message) {
4045
+ if (jsonMode) {
4046
+ console.error(message);
4047
+ } else {
4048
+ console.log(message);
4049
+ }
4050
+ }
4051
+ function printBenchPackageSummary(result, outputPath, outputLabel = "Results saved") {
4052
+ console.log(`Benchmark: ${result.meta.benchmark}`);
4053
+ console.log(`Mode: ${result.meta.mode}`);
4054
+ if (result.config.runtimeProfile) {
4055
+ console.log(`Runtime profile: ${result.config.runtimeProfile}`);
4056
+ }
4057
+ console.log(`Tasks: ${result.results.tasks.length}`);
4058
+ console.log(`Mean query latency: ${result.cost.meanQueryLatencyMs.toFixed(1)}ms`);
4059
+ for (const [metric, aggregate] of Object.entries(result.results.aggregates).sort()) {
4060
+ console.log(` ${metric.padEnd(20)} ${aggregate.mean.toFixed(4)}`);
4061
+ }
4062
+ console.log(`${outputLabel}: ${outputPath}`);
4063
+ }
4064
+ function printStoredBenchResultDetails(result, summary) {
4065
+ printStoredBenchResultSummary(result, summary);
4066
+ if (result.results.tasks.length === 0) {
4067
+ console.log("Tasks: none");
4068
+ return;
4069
+ }
4070
+ console.log("Task breakdown:");
4071
+ for (const task of result.results.tasks) {
4072
+ const scores = Object.entries(task.scores ?? {}).sort(([left], [right]) => left.localeCompare(right)).map(([metric, value]) => `${metric}=${value.toFixed(4)}`).join(", ");
4073
+ const taskLabel = task.taskId ?? "(unknown task)";
4074
+ const taskLatency = typeof task.latencyMs === "number" ? task.latencyMs.toFixed(1) : "?";
4075
+ console.log(
4076
+ ` ${taskLabel}: ${taskLatency}ms${scores.length > 0 ? ` [${scores}]` : ""}`
4077
+ );
4078
+ }
4079
+ }
4080
+ function printBenchComparisonSummary(comparison, baseline, candidate) {
4081
+ console.log(`Benchmark: ${comparison.benchmark}`);
4082
+ console.log(`Baseline: ${baseline.id} (${baseline.path})`);
4083
+ console.log(`Candidate: ${candidate.id} (${candidate.path})`);
4084
+ console.log(`Verdict: ${comparison.verdict}`);
4085
+ const metrics = Object.entries(comparison.metricDeltas).sort(
4086
+ ([left], [right]) => left.localeCompare(right)
4087
+ );
4088
+ if (metrics.length === 0) {
4089
+ console.log("No overlapping metrics were found between the two results.");
4090
+ return;
4091
+ }
4092
+ console.log("Metrics:");
4093
+ for (const [metric, delta] of metrics) {
4094
+ const percent = Number.isFinite(delta.percentChange) ? `${(delta.percentChange * 100).toFixed(2)}%` : delta.percentChange > 0 ? "+Infinity%" : "-Infinity%";
4095
+ const direction = delta.delta >= 0 ? "+" : "";
4096
+ console.log(
4097
+ ` ${metric.padEnd(18)} ${delta.baseline.toFixed(4)} -> ${delta.candidate.toFixed(4)} (${direction}${delta.delta.toFixed(4)}, ${percent}, d=${delta.effectSize.cohensD.toFixed(3)} ${delta.effectSize.interpretation})`
4098
+ );
4099
+ if (delta.ciOnDelta) {
4100
+ console.log(
4101
+ ` 95% CI on delta: [${delta.ciOnDelta.lower.toFixed(4)}, ${delta.ciOnDelta.upper.toFixed(4)}]`
4102
+ );
4103
+ }
4104
+ }
4105
+ }
4106
+
3949
4107
  // src/index.ts
3950
4108
  var LazyPluginPiPublisher = class {
3951
4109
  constructor(hostId, select) {
@@ -4330,7 +4488,7 @@ async function resolveAllBenchmarks() {
4330
4488
  if (packageBenchmarks) {
4331
4489
  return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
4332
4490
  }
4333
- if (!fs10.existsSync(EVAL_RUNNER_PATH)) {
4491
+ if (!fs11.existsSync(EVAL_RUNNER_PATH)) {
4334
4492
  return [];
4335
4493
  }
4336
4494
  return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
@@ -4378,7 +4536,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
4378
4536
  `Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
4379
4537
  );
4380
4538
  }
4381
- if (!fs10.existsSync(EVAL_RUNNER_PATH)) {
4539
+ if (!fs11.existsSync(EVAL_RUNNER_PATH)) {
4382
4540
  console.error(
4383
4541
  "Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
4384
4542
  );
@@ -4388,7 +4546,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
4388
4546
  path12.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
4389
4547
  path12.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
4390
4548
  ];
4391
- const tsxCmd = tsxCandidates.find((candidate) => fs10.existsSync(candidate)) ?? "tsx";
4549
+ const tsxCmd = tsxCandidates.find((candidate) => fs11.existsSync(candidate)) ?? "tsx";
4392
4550
  const fallbackOutputDir = createFallbackBenchOutputDir(
4393
4551
  parsed.resultsDir ?? resolveBenchOutputDir(),
4394
4552
  benchmarkId,
@@ -4533,9 +4691,9 @@ var PERSONAMEM_COMPLETION_MARKER = path12.join(
4533
4691
  );
4534
4692
  function resolveRealpathWithinDataset(datasetPath, relativePath) {
4535
4693
  try {
4536
- const datasetRoot = fs10.realpathSync(datasetPath);
4694
+ const datasetRoot = fs11.realpathSync(datasetPath);
4537
4695
  const candidatePath = path12.resolve(datasetRoot, relativePath);
4538
- const candidateRealPath = fs10.realpathSync(candidatePath);
4696
+ const candidateRealPath = fs11.realpathSync(candidatePath);
4539
4697
  const relativeToRoot = path12.relative(datasetRoot, candidateRealPath);
4540
4698
  if (relativeToRoot.startsWith("..") || path12.isAbsolute(relativeToRoot)) {
4541
4699
  return null;
@@ -4594,14 +4752,14 @@ function parseCsvRows(raw) {
4594
4752
  function isPersonaMemDatasetComplete(datasetPath) {
4595
4753
  try {
4596
4754
  const completionMarkerPath = path12.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
4597
- if (fs10.statSync(completionMarkerPath).isFile()) {
4755
+ if (fs11.statSync(completionMarkerPath).isFile()) {
4598
4756
  return true;
4599
4757
  }
4600
4758
  } catch {
4601
4759
  }
4602
4760
  const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
4603
4761
  try {
4604
- return fs10.statSync(path12.join(datasetPath, candidate)).isFile();
4762
+ return fs11.statSync(path12.join(datasetPath, candidate)).isFile();
4605
4763
  } catch {
4606
4764
  return false;
4607
4765
  }
@@ -4610,7 +4768,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
4610
4768
  return false;
4611
4769
  }
4612
4770
  try {
4613
- const rows = parseCsvRows(fs10.readFileSync(path12.join(datasetPath, datasetFile), "utf8"));
4771
+ const rows = parseCsvRows(fs11.readFileSync(path12.join(datasetPath, datasetFile), "utf8"));
4614
4772
  if (rows.length < 2) {
4615
4773
  return false;
4616
4774
  }
@@ -4625,7 +4783,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
4625
4783
  }
4626
4784
  return historyPaths.every((relativePath) => {
4627
4785
  const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
4628
- return resolvedPath !== null && fs10.statSync(resolvedPath).isFile();
4786
+ return resolvedPath !== null && fs11.statSync(resolvedPath).isFile();
4629
4787
  });
4630
4788
  } catch {
4631
4789
  return false;
@@ -4633,7 +4791,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
4633
4791
  }
4634
4792
  function hasDatasetFile(datasetPath, relativePath) {
4635
4793
  try {
4636
- return fs10.statSync(path12.join(datasetPath, relativePath)).isFile();
4794
+ return fs11.statSync(path12.join(datasetPath, relativePath)).isFile();
4637
4795
  } catch {
4638
4796
  return false;
4639
4797
  }
@@ -4653,10 +4811,10 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
4653
4811
  return candidateFilenames.some((filename) => {
4654
4812
  const filePath = path12.join(datasetPath, filename);
4655
4813
  try {
4656
- if (!fs10.statSync(filePath).isFile()) {
4814
+ if (!fs11.statSync(filePath).isFile()) {
4657
4815
  return false;
4658
4816
  }
4659
- const raw = fs10.readFileSync(filePath, "utf8");
4817
+ const raw = fs11.readFileSync(filePath, "utf8");
4660
4818
  return /"source"\s*:\s*"recsys[_-]/i.test(raw);
4661
4819
  } catch {
4662
4820
  return false;
@@ -4672,7 +4830,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
4672
4830
  function isDatasetDownloaded(datasetPath, benchmarkId) {
4673
4831
  let stats;
4674
4832
  try {
4675
- stats = fs10.statSync(datasetPath);
4833
+ stats = fs11.statSync(datasetPath);
4676
4834
  } catch {
4677
4835
  return false;
4678
4836
  }
@@ -4682,7 +4840,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4682
4840
  const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
4683
4841
  if (!marker) {
4684
4842
  try {
4685
- return fs10.readdirSync(datasetPath).length > 0;
4843
+ return fs11.readdirSync(datasetPath).length > 0;
4686
4844
  } catch {
4687
4845
  return false;
4688
4846
  }
@@ -4690,7 +4848,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4690
4848
  if (marker.allOf) {
4691
4849
  const hasAllRequiredFiles = marker.allOf.every((name) => {
4692
4850
  try {
4693
- return fs10.statSync(path12.join(datasetPath, name)).isFile();
4851
+ return fs11.statSync(path12.join(datasetPath, name)).isFile();
4694
4852
  } catch {
4695
4853
  return false;
4696
4854
  }
@@ -4702,7 +4860,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4702
4860
  if (marker.anyOf) {
4703
4861
  const hasMarkerFile = marker.anyOf.some((name) => {
4704
4862
  try {
4705
- return fs10.statSync(path12.join(datasetPath, name)).isFile();
4863
+ return fs11.statSync(path12.join(datasetPath, name)).isFile();
4706
4864
  } catch {
4707
4865
  return false;
4708
4866
  }
@@ -4720,7 +4878,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4720
4878
  }
4721
4879
  if (marker.ext) {
4722
4880
  try {
4723
- return fs10.readdirSync(datasetPath).some(
4881
+ return fs11.readdirSync(datasetPath).some(
4724
4882
  (name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
4725
4883
  );
4726
4884
  } catch {
@@ -4732,7 +4890,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4732
4890
  async function launchBenchUi(resultsDir) {
4733
4891
  const benchUiDir = path12.join(CLI_REPO_ROOT, "packages", "bench-ui");
4734
4892
  const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
4735
- if (!fs10.existsSync(path12.join(benchUiDir, "package.json"))) {
4893
+ if (!fs11.existsSync(path12.join(benchUiDir, "package.json"))) {
4736
4894
  console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
4737
4895
  process.exit(1);
4738
4896
  }
@@ -4770,13 +4928,13 @@ function listDownloadableBenchmarks() {
4770
4928
  }
4771
4929
  function resolveDatasetDownloadScriptPath() {
4772
4930
  const bundled = path12.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
4773
- if (fs10.existsSync(bundled)) {
4931
+ if (fs11.existsSync(bundled)) {
4774
4932
  return bundled;
4775
4933
  }
4776
4934
  return path12.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
4777
4935
  }
4778
4936
  function isRepoCheckout() {
4779
- return fs10.existsSync(path12.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs10.existsSync(path12.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
4937
+ return fs11.existsSync(path12.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs11.existsSync(path12.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
4780
4938
  }
4781
4939
  function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
4782
4940
  const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
@@ -4848,6 +5006,8 @@ var __benchDatasetTestHooks = {
4848
5006
  isDatasetDownloaded,
4849
5007
  resolveBenchDatasetDir,
4850
5008
  resolveDownloadedBenchDatasetDir,
5009
+ pairedAnswerReplayCacheForBenchmark,
5010
+ orderPairedLoCoMoWorkItemsForTest: orderPairedLoCoMoWorkItems,
4851
5011
  buildPublishedBenchmarkOptionsForTest(benchmarkId, args, taskSelector) {
4852
5012
  return buildPublishedBenchmarkOptions(benchmarkId, args, taskSelector);
4853
5013
  },
@@ -4876,72 +5036,9 @@ var __benchDatasetTestHooks = {
4876
5036
  taskSelector
4877
5037
  );
4878
5038
  },
4879
- printBenchStatusLineForTest: printBenchStatusLine
5039
+ printBenchStatusLineForTest: printBenchStatusLine,
5040
+ clearPairedAnswerReplayCacheOnFailureForTest: clearPairedAnswerReplayCacheOnFailure
4880
5041
  };
4881
- function printBenchPackageSummary(result, outputPath, outputLabel = "Results saved") {
4882
- console.log(`Benchmark: ${result.meta.benchmark}`);
4883
- console.log(`Mode: ${result.meta.mode}`);
4884
- if (result.config.runtimeProfile) {
4885
- console.log(`Runtime profile: ${result.config.runtimeProfile}`);
4886
- }
4887
- console.log(`Tasks: ${result.results.tasks.length}`);
4888
- console.log(`Mean query latency: ${result.cost.meanQueryLatencyMs.toFixed(1)}ms`);
4889
- for (const [metric, aggregate] of Object.entries(result.results.aggregates).sort()) {
4890
- console.log(` ${metric.padEnd(20)} ${aggregate.mean.toFixed(4)}`);
4891
- }
4892
- console.log(`${outputLabel}: ${outputPath}`);
4893
- }
4894
- function printBenchStatusLine(jsonMode, message) {
4895
- if (jsonMode) {
4896
- console.error(message);
4897
- } else {
4898
- console.log(message);
4899
- }
4900
- }
4901
- function printStoredBenchResultSummary(result, summary) {
4902
- printBenchPackageSummary(result, summary.path, "Stored result");
4903
- console.log(`Run id: ${summary.id}`);
4904
- }
4905
- function printStoredBenchResultDetails(result, summary) {
4906
- printStoredBenchResultSummary(result, summary);
4907
- if (result.results.tasks.length === 0) {
4908
- console.log("Tasks: none");
4909
- return;
4910
- }
4911
- console.log("Task breakdown:");
4912
- for (const task of result.results.tasks) {
4913
- const scores = Object.entries(task.scores).sort(([left], [right]) => left.localeCompare(right)).map(([metric, value]) => `${metric}=${value.toFixed(4)}`).join(", ");
4914
- console.log(
4915
- ` ${task.taskId}: ${task.latencyMs.toFixed(1)}ms${scores.length > 0 ? ` [${scores}]` : ""}`
4916
- );
4917
- }
4918
- }
4919
- function printBenchComparisonSummary(comparison, baseline, candidate) {
4920
- console.log(`Benchmark: ${comparison.benchmark}`);
4921
- console.log(`Baseline: ${baseline.id} (${baseline.path})`);
4922
- console.log(`Candidate: ${candidate.id} (${candidate.path})`);
4923
- console.log(`Verdict: ${comparison.verdict}`);
4924
- const metrics = Object.entries(comparison.metricDeltas).sort(
4925
- ([left], [right]) => left.localeCompare(right)
4926
- );
4927
- if (metrics.length === 0) {
4928
- console.log("No overlapping metrics were found between the two results.");
4929
- return;
4930
- }
4931
- console.log("Metrics:");
4932
- for (const [metric, delta] of metrics) {
4933
- const percent = Number.isFinite(delta.percentChange) ? `${(delta.percentChange * 100).toFixed(2)}%` : delta.percentChange > 0 ? "+Infinity%" : "-Infinity%";
4934
- const direction = delta.delta >= 0 ? "+" : "";
4935
- console.log(
4936
- ` ${metric.padEnd(18)} ${delta.baseline.toFixed(4)} -> ${delta.candidate.toFixed(4)} (${direction}${delta.delta.toFixed(4)}, ${percent}, d=${delta.effectSize.cohensD.toFixed(3)} ${delta.effectSize.interpretation})`
4937
- );
4938
- if (delta.ciOnDelta) {
4939
- console.log(
4940
- ` CI95 delta: [${delta.ciOnDelta.lower.toFixed(4)}, ${delta.ciOnDelta.upper.toFixed(4)}]`
4941
- );
4942
- }
4943
- }
4944
- }
4945
5042
  async function compareBenchPackageResults(parsed) {
4946
5043
  const refs = parsed.benchmarks;
4947
5044
  if (refs.length !== 2) {
@@ -5150,8 +5247,8 @@ async function exportBenchPackageResult(parsed) {
5150
5247
  ...reportCardProvenance ? { reportCardProvenance } : {}
5151
5248
  });
5152
5249
  if (parsed.output) {
5153
- fs10.mkdirSync(path12.dirname(parsed.output), { recursive: true });
5154
- fs10.writeFileSync(parsed.output, rendered);
5250
+ fs11.mkdirSync(path12.dirname(parsed.output), { recursive: true });
5251
+ fs11.writeFileSync(parsed.output, rendered);
5155
5252
  console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
5156
5253
  return;
5157
5254
  }
@@ -5196,7 +5293,7 @@ async function manageBenchDatasets(parsed) {
5196
5293
  process.exit(1);
5197
5294
  }
5198
5295
  const scriptPath = resolveDatasetDownloadScriptPath();
5199
- if (!fs10.existsSync(scriptPath)) {
5296
+ if (!fs11.existsSync(scriptPath)) {
5200
5297
  console.error(`ERROR: dataset download script not found: ${scriptPath}`);
5201
5298
  process.exit(1);
5202
5299
  }
@@ -5396,7 +5493,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
5396
5493
  );
5397
5494
  process.exit(1);
5398
5495
  }
5399
- const sourceResultSha256 = createHash2("sha256").update(fs10.readFileSync(latest.path)).digest("hex");
5496
+ const sourceResultSha256 = createHash2("sha256").update(fs11.readFileSync(latest.path)).digest("hex");
5400
5497
  const expandedManifestPath = expandTilde(manifestPath);
5401
5498
  if (!bench.resolveLocalLabJudgeProviderConfig) {
5402
5499
  console.error(
@@ -5705,16 +5802,23 @@ async function runBenchPublished(parsed) {
5705
5802
  }
5706
5803
  return;
5707
5804
  }
5708
- const runtimeProfiles = resolveBenchRunProfiles(parsed);
5709
5805
  const benchmarkId = parsed.publishedName;
5806
+ const runtimeProfiles = orderPairedLoCoMoWorkItems(
5807
+ resolveBenchRunProfiles(parsed).map((runtimeProfile) => ({
5808
+ benchmarkId,
5809
+ runtimeProfile
5810
+ }))
5811
+ ).map((item) => item.runtimeProfile);
5710
5812
  const writtenPaths = [];
5813
+ const pairedAnswerReplayCache = benchmarkId === "locomo" && runtimeProfiles.includes("baseline") && runtimeProfiles.includes("real") ? /* @__PURE__ */ new Map() : void 0;
5711
5814
  for (const runtimeProfile of runtimeProfiles) {
5712
5815
  const result = await runBenchViaPackage(
5713
5816
  parsed,
5714
5817
  benchmarkId,
5715
5818
  runtimeProfile,
5716
5819
  void 0,
5717
- taskSelector
5820
+ taskSelector,
5821
+ pairedAnswerReplayCache
5718
5822
  );
5719
5823
  if (!result.ok) {
5720
5824
  console.error(
@@ -5804,7 +5908,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
5804
5908
  }
5805
5909
  let decoded;
5806
5910
  try {
5807
- decoded = JSON.parse(fs10.readFileSync(parsed.taskIdsFile, "utf8"));
5911
+ decoded = JSON.parse(fs11.readFileSync(parsed.taskIdsFile, "utf8"));
5808
5912
  } catch (error) {
5809
5913
  throw new Error(
5810
5914
  `Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
@@ -5969,7 +6073,29 @@ async function preflightLocalLabEndpointsIfNeeded(benchModule, plan) {
5969
6073
  );
5970
6074
  }
5971
6075
  }
5972
- async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStatusPath, taskSelector) {
6076
+ function pairedAnswerReplayCacheForBenchmark(benchmarkId, pairedAnswerReplayCache) {
6077
+ return benchmarkId === "locomo" ? pairedAnswerReplayCache : void 0;
6078
+ }
6079
+ function clearPairedAnswerReplayCacheOnFailure(runtimeProfile, benchmarkId, pairedAnswerReplayCache) {
6080
+ if (runtimeProfile !== "baseline" || benchmarkId !== "locomo") return;
6081
+ pairedAnswerReplayCache?.clear();
6082
+ }
6083
+ function orderPairedLoCoMoWorkItems(workItems) {
6084
+ const baselineIndex = workItems.findIndex(
6085
+ (item) => item.benchmarkId === "locomo" && item.runtimeProfile === "baseline"
6086
+ );
6087
+ const realIndex = workItems.findIndex(
6088
+ (item) => item.benchmarkId === "locomo" && item.runtimeProfile === "real"
6089
+ );
6090
+ if (baselineIndex < 0 || realIndex < 0 || baselineIndex < realIndex) {
6091
+ return [...workItems];
6092
+ }
6093
+ const ordered = [...workItems];
6094
+ const [baseline] = ordered.splice(baselineIndex, 1);
6095
+ ordered.splice(realIndex, 0, baseline);
6096
+ return ordered;
6097
+ }
6098
+ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStatusPath, taskSelector, pairedAnswerReplayCache) {
5973
6099
  const loaded = await tryLoadBenchModule();
5974
6100
  if (!loaded) return { ok: false };
5975
6101
  assertBenchModuleFreshForDevelopment();
@@ -6039,6 +6165,10 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
6039
6165
  if (benchmarkId === "memcorrect-v1" && parsed.adapter === "mcp") {
6040
6166
  benchmarkOptions = { ...benchmarkOptions ?? {}, adapter: system };
6041
6167
  }
6168
+ const locomoPairedAnswerReplayCache = pairedAnswerReplayCacheForBenchmark(
6169
+ benchmarkId,
6170
+ pairedAnswerReplayCache
6171
+ );
6042
6172
  const result = await benchModule.runBenchmark(benchmarkId, {
6043
6173
  mode: parsed.quick ? "quick" : "full",
6044
6174
  datasetDir,
@@ -6055,6 +6185,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
6055
6185
  // Issue #1573 PR1: judge-result cache controls from the CLI flags.
6056
6186
  ...parsed.noJudgeCache ? { noJudgeCache: true } : {},
6057
6187
  ...parsed.judgeCacheDir ? { judgeCacheDir: parsed.judgeCacheDir } : {},
6188
+ ...locomoPairedAnswerReplayCache ? { pairedAnswerReplayCache: locomoPairedAnswerReplayCache } : {},
6058
6189
  ...benchmarkOptions ? { benchmarkOptions } : {},
6059
6190
  ...amaBenchProtocol.judgeProtocol ? { amaBenchJudgeProtocol: amaBenchProtocol.judgeProtocol } : {},
6060
6191
  ...amaBenchProtocol.crossJudge ? { amaBenchCrossJudge: amaBenchProtocol.crossJudge } : {},
@@ -6092,6 +6223,11 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
6092
6223
  }
6093
6224
  return { ok: true, writtenPath };
6094
6225
  } catch (err) {
6226
+ clearPairedAnswerReplayCacheOnFailure(
6227
+ runtimeProfile,
6228
+ benchmarkId,
6229
+ pairedAnswerReplayCache
6230
+ );
6095
6231
  if (partialTasks.length > 0) {
6096
6232
  const remnicVersion = await benchModule.getRemnicVersion?.() ?? "unknown";
6097
6233
  const partialResult = buildPartialBenchmarkResult(
@@ -6444,7 +6580,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
6444
6580
  return void 0;
6445
6581
  }
6446
6582
  try {
6447
- return fs10.realpathSync(datasetDir);
6583
+ return fs11.realpathSync(datasetDir);
6448
6584
  } catch {
6449
6585
  return datasetDir;
6450
6586
  }
@@ -6507,13 +6643,13 @@ function resolveConfigPath(cliPath) {
6507
6643
  path12.join(resolveHomeDir(), ".config", "engram", "config.json")
6508
6644
  ];
6509
6645
  for (const candidate of candidates) {
6510
- if (fs10.existsSync(candidate)) return candidate;
6646
+ if (fs11.existsSync(candidate)) return candidate;
6511
6647
  }
6512
6648
  return path12.join(resolveHomeDir(), ".config", "remnic", "config.json");
6513
6649
  }
6514
6650
  function resolveExistingBenchRemnicConfigPath(cliPath) {
6515
6651
  const configPath = resolveConfigPath(cliPath);
6516
- if (fs10.existsSync(configPath)) {
6652
+ if (fs11.existsSync(configPath)) {
6517
6653
  return configPath;
6518
6654
  }
6519
6655
  if (cliPath) {
@@ -6523,7 +6659,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
6523
6659
  }
6524
6660
  function resolveExistingBenchOpenclawConfigPath(cliPath) {
6525
6661
  const configPath = resolveOpenclawConfigPath(cliPath);
6526
- if (fs10.existsSync(configPath)) {
6662
+ if (fs11.existsSync(configPath)) {
6527
6663
  return configPath;
6528
6664
  }
6529
6665
  if (cliPath) {
@@ -6630,8 +6766,8 @@ function resolveMemoryDir() {
6630
6766
  const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
6631
6767
  if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
6632
6768
  const configPath = resolveConfigPath();
6633
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
6634
- const remnicCfg = resolveRemnicConfigRecord3(raw);
6769
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
6770
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
6635
6771
  if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
6636
6772
  return normalizeMemoryDirPath(remnicCfg.memoryDir);
6637
6773
  }
@@ -6639,18 +6775,18 @@ function resolveMemoryDir() {
6639
6775
  const standalonePath = path12.join(home, ".remnic", "memory");
6640
6776
  const legacyStandalonePath = path12.join(home, ".engram", "memory");
6641
6777
  const openclawPath = path12.join(home, ".openclaw", "workspace", "memory", "local");
6642
- if (fs10.existsSync(standalonePath)) return standalonePath;
6643
- if (fs10.existsSync(legacyStandalonePath)) return legacyStandalonePath;
6778
+ if (fs11.existsSync(standalonePath)) return standalonePath;
6779
+ if (fs11.existsSync(legacyStandalonePath)) return legacyStandalonePath;
6644
6780
  return openclawPath;
6645
6781
  })();
6646
6782
  const manifestPath = getManifestPath();
6647
- if (fs10.existsSync(manifestPath)) {
6783
+ if (fs11.existsSync(manifestPath)) {
6648
6784
  try {
6649
6785
  const active = getActiveSpace();
6650
6786
  if (active?.memoryDir) {
6651
6787
  const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
6652
- if (!fs10.existsSync(activeMemoryDir)) {
6653
- fs10.mkdirSync(activeMemoryDir, { recursive: true });
6788
+ if (!fs11.existsSync(activeMemoryDir)) {
6789
+ fs11.mkdirSync(activeMemoryDir, { recursive: true });
6654
6790
  }
6655
6791
  return activeMemoryDir;
6656
6792
  }
@@ -6696,13 +6832,13 @@ function resolveOpenclawConfigPath(cliPath) {
6696
6832
  const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
6697
6833
  if (envPath) return path12.resolve(expandTilde(envPath));
6698
6834
  for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
6699
- if (fs10.existsSync(candidate)) return candidate;
6835
+ if (fs11.existsSync(candidate)) return candidate;
6700
6836
  }
6701
6837
  return path12.join(resolveHomeDir(), ".openclaw", "openclaw.json");
6702
6838
  }
6703
6839
  function readOpenclawConfig(configPath) {
6704
- if (!fs10.existsSync(configPath)) return {};
6705
- const raw = fs10.readFileSync(configPath, "utf-8");
6840
+ if (!fs11.existsSync(configPath)) return {};
6841
+ const raw = fs11.readFileSync(configPath, "utf-8");
6706
6842
  let parsed;
6707
6843
  try {
6708
6844
  parsed = JSON.parse(raw);
@@ -6801,14 +6937,14 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
6801
6937
  return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
6802
6938
  }
6803
6939
  function backupPathIfPresent(sourcePath, backupPath) {
6804
- if (!fs10.existsSync(sourcePath)) return false;
6805
- fs10.mkdirSync(path12.dirname(backupPath), { recursive: true });
6806
- fs10.cpSync(sourcePath, backupPath, { recursive: true });
6940
+ if (!fs11.existsSync(sourcePath)) return false;
6941
+ fs11.mkdirSync(path12.dirname(backupPath), { recursive: true });
6942
+ fs11.cpSync(sourcePath, backupPath, { recursive: true });
6807
6943
  return true;
6808
6944
  }
6809
6945
  function assertDirectoryPathOrMissing(targetPath, label) {
6810
- if (!fs10.existsSync(targetPath)) return;
6811
- const stat = fs10.statSync(targetPath);
6946
+ if (!fs11.existsSync(targetPath)) return;
6947
+ const stat = fs11.statSync(targetPath);
6812
6948
  if (!stat.isDirectory()) {
6813
6949
  throw new Error(`${label} must be a directory when it already exists: ${targetPath}`);
6814
6950
  }
@@ -6833,7 +6969,7 @@ var PublishedOpenclawPluginInstallError = class extends Error {
6833
6969
  }
6834
6970
  };
6835
6971
  function installPublishedOpenclawPlugin(spec, pluginDir) {
6836
- const tempRoot = fs10.mkdtempSync(path12.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
6972
+ const tempRoot = fs11.mkdtempSync(path12.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
6837
6973
  const stagedDir = `${pluginDir}.next-${process.pid}-${Date.now()}`;
6838
6974
  const rollbackDir = `${pluginDir}.rollback-${process.pid}-${Date.now()}`;
6839
6975
  let swapRollbackDir;
@@ -6849,16 +6985,16 @@ function installPublishedOpenclawPlugin(spec, pluginDir) {
6849
6985
  throw new Error(`npm pack ${spec} did not return a tarball name`);
6850
6986
  }
6851
6987
  const unpackDir = path12.join(tempRoot, "unpacked");
6852
- fs10.mkdirSync(unpackDir, { recursive: true });
6988
+ fs11.mkdirSync(unpackDir, { recursive: true });
6853
6989
  childProcess2.execFileSync("tar", ["-xzf", path12.join(tempRoot, tarballName), "-C", unpackDir], {
6854
6990
  stdio: ["ignore", "pipe", "pipe"]
6855
6991
  });
6856
6992
  const packagedDir = path12.join(unpackDir, "package");
6857
- if (!fs10.existsSync(packagedDir)) {
6993
+ if (!fs11.existsSync(packagedDir)) {
6858
6994
  throw new Error(`npm pack ${spec} did not contain a package/ directory`);
6859
6995
  }
6860
- fs10.rmSync(stagedDir, { recursive: true, force: true });
6861
- fs10.cpSync(packagedDir, stagedDir, { recursive: true });
6996
+ fs11.rmSync(stagedDir, { recursive: true, force: true });
6997
+ fs11.cpSync(packagedDir, stagedDir, { recursive: true });
6862
6998
  childProcess2.execFileSync("npm", ["install", "--omit=dev"], {
6863
6999
  cwd: stagedDir,
6864
7000
  stdio: ["ignore", "pipe", "pipe"]
@@ -6874,7 +7010,7 @@ function installPublishedOpenclawPlugin(spec, pluginDir) {
6874
7010
  })();
6875
7011
  swapRollbackDir = swapResult.rollbackDir;
6876
7012
  const installedPackageJsonPath = path12.join(pluginDir, "package.json");
6877
- const installedPackage = fs10.existsSync(installedPackageJsonPath) ? JSON.parse(fs10.readFileSync(installedPackageJsonPath, "utf8")) : {};
7013
+ const installedPackage = fs11.existsSync(installedPackageJsonPath) ? JSON.parse(fs11.readFileSync(installedPackageJsonPath, "utf8")) : {};
6878
7014
  return {
6879
7015
  rollbackDir: swapRollbackDir,
6880
7016
  version: typeof installedPackage.version === "string" ? installedPackage.version : void 0
@@ -6889,8 +7025,8 @@ function installPublishedOpenclawPlugin(spec, pluginDir) {
6889
7025
  }
6890
7026
  );
6891
7027
  } finally {
6892
- fs10.rmSync(stagedDir, { recursive: true, force: true });
6893
- fs10.rmSync(tempRoot, { recursive: true, force: true });
7028
+ fs11.rmSync(stagedDir, { recursive: true, force: true });
7029
+ fs11.rmSync(tempRoot, { recursive: true, force: true });
6894
7030
  }
6895
7031
  }
6896
7032
  function restartOpenclawGateway() {
@@ -6909,7 +7045,7 @@ function restartOpenclawGateway() {
6909
7045
  }
6910
7046
  function cmdInit() {
6911
7047
  const configPath = path12.join(process.cwd(), "remnic.config.json");
6912
- if (fs10.existsSync(configPath)) {
7048
+ if (fs11.existsSync(configPath)) {
6913
7049
  console.log(`Config already exists: ${configPath}`);
6914
7050
  return;
6915
7051
  }
@@ -6925,7 +7061,7 @@ function cmdInit() {
6925
7061
  authToken: "${REMNIC_AUTH_TOKEN}"
6926
7062
  }
6927
7063
  };
6928
- fs10.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
7064
+ fs11.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
6929
7065
  console.log(`Created ${configPath}`);
6930
7066
  console.log("\nSet these environment variables:");
6931
7067
  console.log(" export OPENAI_API_KEY=sk-...");
@@ -6995,7 +7131,7 @@ async function cmdStatus(json) {
6995
7131
  }
6996
7132
  function oauthReadConfigRecord(configPath) {
6997
7133
  try {
6998
- const parsed = JSON.parse(fs10.readFileSync(configPath, "utf8"));
7134
+ const parsed = JSON.parse(fs11.readFileSync(configPath, "utf8"));
6999
7135
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
7000
7136
  return parsed;
7001
7137
  }
@@ -7411,10 +7547,10 @@ async function cmdQuery(queryText, json, explain) {
7411
7547
  }
7412
7548
  initLogger2();
7413
7549
  const configPath = resolveConfigPath();
7414
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
7415
- const remnicCfg = resolveRemnicConfigRecord3(raw);
7416
- const config = parseConfig3(remnicCfg);
7417
- const orchestrator = new Orchestrator2(config);
7550
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
7551
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
7552
+ const config = parseConfig4(remnicCfg);
7553
+ const orchestrator = new Orchestrator3(config);
7418
7554
  await orchestrator.initialize();
7419
7555
  const service = new EngramAccessService2(orchestrator);
7420
7556
  const recallRequest = buildQueryRecallRequest(queryText);
@@ -7582,10 +7718,10 @@ async function cmdXray(rest) {
7582
7718
  parseXrayCliOptions(rawQuery, options);
7583
7719
  initLogger2();
7584
7720
  const configPath = resolveConfigPath();
7585
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
7586
- const remnicCfg = resolveRemnicConfigRecord3(raw);
7587
- const config = parseConfig3(remnicCfg);
7588
- const orchestrator = new Orchestrator2(config);
7721
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
7722
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
7723
+ const config = parseConfig4(remnicCfg);
7724
+ const orchestrator = new Orchestrator3(config);
7589
7725
  await orchestrator.initialize();
7590
7726
  await orchestrator.deferredReady;
7591
7727
  const service = new EngramAccessService2(orchestrator);
@@ -7605,9 +7741,9 @@ async function cmdXray(rest) {
7605
7741
  async function cmdVersions(rest) {
7606
7742
  initLogger2();
7607
7743
  const configPath = resolveConfigPath();
7608
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
7609
- const remnicCfg = resolveRemnicConfigRecord3(raw);
7610
- const config = parseConfig3(remnicCfg);
7744
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
7745
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
7746
+ const config = parseConfig4(remnicCfg);
7611
7747
  if (!config.versioningEnabled) {
7612
7748
  console.error("Page versioning is disabled (versioningEnabled = false).");
7613
7749
  process.exit(1);
@@ -7721,9 +7857,9 @@ Options:
7721
7857
  async function cmdEnrich(rest) {
7722
7858
  initLogger2();
7723
7859
  const configPath = resolveConfigPath();
7724
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
7725
- const remnicCfg = resolveRemnicConfigRecord3(raw);
7726
- const config = parseConfig3(remnicCfg);
7860
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
7861
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
7862
+ const config = parseConfig4(remnicCfg);
7727
7863
  const subcommand = rest[0];
7728
7864
  if (subcommand === "audit") {
7729
7865
  const memoryDir2 = expandTilde(config.memoryDir);
@@ -7751,7 +7887,7 @@ async function cmdEnrich(rest) {
7751
7887
  pipelineConfig2.providers = [
7752
7888
  { id: "web-search", enabled: true, costTier: "cheap" }
7753
7889
  ];
7754
- const orchestrator2 = new Orchestrator2(config);
7890
+ const orchestrator2 = new Orchestrator3(config);
7755
7891
  await orchestrator2.initialize();
7756
7892
  await orchestrator2.deferredReady;
7757
7893
  const searchBackend2 = orchestrator2.qmd;
@@ -7787,7 +7923,7 @@ Registered providers:`);
7787
7923
  console.error("Usage: remnic enrich <entity-name> | --all | --dry-run | audit | providers");
7788
7924
  process.exit(1);
7789
7925
  }
7790
- const orchestrator = new Orchestrator2(config);
7926
+ const orchestrator = new Orchestrator3(config);
7791
7927
  await orchestrator.initialize();
7792
7928
  await orchestrator.deferredReady;
7793
7929
  const storage = await orchestrator.getStorage(config.defaultNamespace);
@@ -7966,9 +8102,9 @@ Shared with:
7966
8102
  process.exit(1);
7967
8103
  }
7968
8104
  const configPath = resolveConfigPath();
7969
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
7970
- const remnicCfg = resolveRemnicConfigRecord3(raw);
7971
- const config = parseConfig3(remnicCfg);
8105
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
8106
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
8107
+ const config = parseConfig4(remnicCfg);
7972
8108
  const memoryDir = expandTilde(
7973
8109
  typeof memoryDirOverride === "string" && memoryDirOverride.length > 0 ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
7974
8110
  );
@@ -7983,9 +8119,9 @@ Shared with:
7983
8119
  async function cmdExtensions(action, rest) {
7984
8120
  initLogger2();
7985
8121
  const configPath = resolveConfigPath();
7986
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
7987
- const remnicCfg = resolveRemnicConfigRecord3(raw);
7988
- const config = parseConfig3(remnicCfg);
8122
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
8123
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
8124
+ const config = parseConfig4(remnicCfg);
7989
8125
  const root = resolveExtensionsRoot(config);
7990
8126
  const noopLog = { warn: () => {
7991
8127
  }, debug: () => {
@@ -8034,7 +8170,7 @@ Root: ${root}`);
8034
8170
  const extensions = await discoverMemoryExtensions(root, warnLog);
8035
8171
  let entries = [];
8036
8172
  try {
8037
- entries = fs10.readdirSync(root);
8173
+ entries = fs11.readdirSync(root);
8038
8174
  } catch {
8039
8175
  console.log(`Extensions root does not exist: ${root}`);
8040
8176
  process.exitCode = 0;
@@ -8045,7 +8181,7 @@ Root: ${root}`);
8045
8181
  for (const entry of entries) {
8046
8182
  const entryPath = path12.join(root, entry);
8047
8183
  try {
8048
- if (!fs10.statSync(entryPath).isDirectory()) continue;
8184
+ if (!fs11.statSync(entryPath).isDirectory()) continue;
8049
8185
  } catch {
8050
8186
  continue;
8051
8187
  }
@@ -8077,9 +8213,9 @@ Root: ${root}`);
8077
8213
  async function cmdBriefing(rest) {
8078
8214
  initLogger2();
8079
8215
  const configPath = resolveConfigPath();
8080
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
8081
- const remnicCfg = resolveRemnicConfigRecord3(raw);
8082
- const config = parseConfig3(remnicCfg);
8216
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
8217
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
8218
+ const config = parseConfig4(remnicCfg);
8083
8219
  if (!config.briefing.enabled) {
8084
8220
  console.error("Briefing is disabled in config (briefing.enabled = false).");
8085
8221
  process.exit(1);
@@ -8132,7 +8268,7 @@ async function cmdBriefing(rest) {
8132
8268
  process.exit(1);
8133
8269
  }
8134
8270
  const format = effectiveFormatFlag === "json" ? "json" : effectiveFormatFlag === "markdown" ? "markdown" : config.briefing.defaultFormat;
8135
- const orchestrator = new Orchestrator2(config);
8271
+ const orchestrator = new Orchestrator3(config);
8136
8272
  await orchestrator.initialize();
8137
8273
  const storage = await orchestrator.getStorage(config.defaultNamespace);
8138
8274
  const calendarSource = config.briefing.calendarSource ? new FileCalendarSource(config.briefing.calendarSource) : void 0;
@@ -8157,10 +8293,10 @@ async function cmdBriefing(rest) {
8157
8293
  if (save) {
8158
8294
  try {
8159
8295
  const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
8160
- fs10.mkdirSync(saveDir, { recursive: true });
8296
+ fs11.mkdirSync(saveDir, { recursive: true });
8161
8297
  const filename = briefingFilename(new Date(result.window.to), format);
8162
8298
  const filePath = path12.join(saveDir, filename);
8163
- fs10.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
8299
+ fs11.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
8164
8300
  console.error(`Saved briefing: ${filePath}`);
8165
8301
  } catch (err) {
8166
8302
  console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
@@ -8178,7 +8314,7 @@ async function cmdDoctor() {
8178
8314
  detail: `${nodeVersion} (requires >= 22.12.0)`
8179
8315
  });
8180
8316
  const configPath = resolveConfigPath();
8181
- const configExists = fs10.existsSync(configPath);
8317
+ const configExists = fs11.existsSync(configPath);
8182
8318
  checks.push({ name: "Config file", ok: configExists, detail: configPath });
8183
8319
  let standaloneConfig;
8184
8320
  let standaloneConfigError;
@@ -8186,11 +8322,11 @@ async function cmdDoctor() {
8186
8322
  let configuredNs = { invalid: false };
8187
8323
  if (configExists) {
8188
8324
  try {
8189
- const raw = JSON.parse(fs10.readFileSync(configPath, "utf8"));
8190
- const remnicCfg = resolveRemnicConfigRecord3(raw);
8325
+ const raw = JSON.parse(fs11.readFileSync(configPath, "utf8"));
8326
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
8191
8327
  standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
8192
8328
  configuredNs = readConfiguredNamespace(remnicCfg);
8193
- standaloneConfig = parseConfig3(remnicCfg);
8329
+ standaloneConfig = parseConfig4(remnicCfg);
8194
8330
  } catch (err) {
8195
8331
  standaloneConfigError = err instanceof Error ? err.message : String(err);
8196
8332
  }
@@ -8199,10 +8335,10 @@ async function cmdDoctor() {
8199
8335
  try {
8200
8336
  memoryDir = resolveMemoryDir();
8201
8337
  } catch {
8202
- memoryDir = parseConfig3({}).memoryDir;
8338
+ memoryDir = parseConfig4({}).memoryDir;
8203
8339
  }
8204
8340
  try {
8205
- fs10.mkdirSync(memoryDir, { recursive: true });
8341
+ fs11.mkdirSync(memoryDir, { recursive: true });
8206
8342
  checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
8207
8343
  } catch {
8208
8344
  checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
@@ -8231,7 +8367,7 @@ async function cmdDoctor() {
8231
8367
  });
8232
8368
  if (nsPolicyCheck) checks.push(nsPolicyCheck);
8233
8369
  const openclawConfigPath = resolveOpenclawConfigPath();
8234
- const openclawConfigExists = fs10.existsSync(openclawConfigPath);
8370
+ const openclawConfigExists = fs11.existsSync(openclawConfigPath);
8235
8371
  let openclawConfig = {};
8236
8372
  let openclawConfigValid = false;
8237
8373
  let openclawPluginModeConfigured = false;
@@ -8239,7 +8375,7 @@ async function cmdDoctor() {
8239
8375
  let activeOpenclawEntryConfig = null;
8240
8376
  if (openclawConfigExists) {
8241
8377
  try {
8242
- const parsed = JSON.parse(fs10.readFileSync(openclawConfigPath, "utf-8"));
8378
+ const parsed = JSON.parse(fs11.readFileSync(openclawConfigPath, "utf-8"));
8243
8379
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
8244
8380
  openclawConfig = parsed;
8245
8381
  openclawConfigValid = true;
@@ -8319,9 +8455,9 @@ async function cmdDoctor() {
8319
8455
  let memDirOk = false;
8320
8456
  let memDirDetail = `${resolvedMemDir} (not found)`;
8321
8457
  let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
8322
- if (fs10.existsSync(resolvedMemDir)) {
8458
+ if (fs11.existsSync(resolvedMemDir)) {
8323
8459
  try {
8324
- const stat = fs10.statSync(resolvedMemDir);
8460
+ const stat = fs11.statSync(resolvedMemDir);
8325
8461
  if (stat.isDirectory()) {
8326
8462
  memDirOk = true;
8327
8463
  memDirDetail = resolvedMemDir;
@@ -8463,12 +8599,12 @@ async function cmdDoctor() {
8463
8599
  }
8464
8600
  function cmdConfig() {
8465
8601
  const configPath = resolveConfigPath();
8466
- if (!fs10.existsSync(configPath)) {
8602
+ if (!fs11.existsSync(configPath)) {
8467
8603
  console.log("No config file found. Run `remnic init` to create one.");
8468
8604
  return;
8469
8605
  }
8470
8606
  console.log(`Config: ${configPath}`);
8471
- const rawConfig = fs10.readFileSync(configPath, "utf8");
8607
+ const rawConfig = fs11.readFileSync(configPath, "utf8");
8472
8608
  const redacted = rawConfig.replace(
8473
8609
  /("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
8474
8610
  "$1[REDACTED]$3"
@@ -8576,9 +8712,9 @@ async function cmdReview(action, rest) {
8576
8712
  const configPath = resolveConfigPath();
8577
8713
  let tombstonesConfig = null;
8578
8714
  try {
8579
- const rawCfg = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
8580
- const remnicCfg = resolveRemnicConfigRecord3(rawCfg);
8581
- const config = parseConfig3(remnicCfg);
8715
+ const rawCfg = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
8716
+ const remnicCfg = resolveRemnicConfigRecord4(rawCfg);
8717
+ const config = parseConfig4(remnicCfg);
8582
8718
  tombstonesConfig = {
8583
8719
  enabled: config.tombstonesEnabled,
8584
8720
  semanticMatch: config.tombstonesSemanticMatch,
@@ -9329,7 +9465,7 @@ async function pushOfflineFileContent(args) {
9329
9465
  }
9330
9466
  async function pushOfflineFileContentFromChunkReader(args) {
9331
9467
  const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
9332
- const stat = fs10.statSync(filePath);
9468
+ const stat = fs11.statSync(filePath);
9333
9469
  if (stat.mtimeMs !== args.file.mtimeMs) {
9334
9470
  throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
9335
9471
  }
@@ -9820,7 +9956,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
9820
9956
  return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
9821
9957
  }
9822
9958
  async function runOfflineSyncOnce(options) {
9823
- fs10.mkdirSync(options.memoryDir, { recursive: true });
9959
+ fs11.mkdirSync(options.memoryDir, { recursive: true });
9824
9960
  let activeStatePath = options.statePath;
9825
9961
  let priorState = await readOfflineSyncState(activeStatePath);
9826
9962
  let syncNamespace = options.namespace ?? priorState?.namespace;
@@ -10446,7 +10582,7 @@ Environment fallbacks:
10446
10582
  const configPath = resolveConfigPath();
10447
10583
  let config;
10448
10584
  try {
10449
- const rawConfig = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
10585
+ const rawConfig = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
10450
10586
  config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
10451
10587
  } catch {
10452
10588
  throw new Error(
@@ -10461,7 +10597,7 @@ Environment fallbacks:
10461
10597
  const statePath = statePathExplicit ? path12.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
10462
10598
  if (action === "prepare") {
10463
10599
  if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
10464
- fs10.mkdirSync(memoryDir, { recursive: true });
10600
+ fs11.mkdirSync(memoryDir, { recursive: true });
10465
10601
  const remoteSnapshot = await fetchOfflineSnapshot({
10466
10602
  remoteUrl,
10467
10603
  token,
@@ -10559,7 +10695,7 @@ Environment fallbacks:
10559
10695
  return;
10560
10696
  }
10561
10697
  if (action === "status") {
10562
- fs10.mkdirSync(memoryDir, { recursive: true });
10698
+ fs11.mkdirSync(memoryDir, { recursive: true });
10563
10699
  const state = statePath ? await readOfflineSyncState(statePath) : null;
10564
10700
  if (state && remoteUrl && statePath) {
10565
10701
  assertOfflineStateMatches({
@@ -10697,7 +10833,7 @@ function cmdDedup(json) {
10697
10833
  function readInstalledConnectorConfig(configPath, fallback) {
10698
10834
  if (!configPath) return fallback;
10699
10835
  try {
10700
- const parsed = JSON.parse(fs10.readFileSync(configPath, "utf8"));
10836
+ const parsed = JSON.parse(fs11.readFileSync(configPath, "utf8"));
10701
10837
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
10702
10838
  const { token: _token, ...config } = parsed;
10703
10839
  return config;
@@ -10875,7 +11011,7 @@ async function cmdConnectors(action, rest, json) {
10875
11011
  const pub = factory();
10876
11012
  const available = await pub.isHostAvailable();
10877
11013
  const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
10878
- const extensionExists = available && extRoot ? fs10.existsSync(extRoot) : false;
11014
+ const extensionExists = available && extRoot ? fs11.existsSync(extRoot) : false;
10879
11015
  publisherChecks.push({
10880
11016
  name: `Publisher: ${targetHostId}`,
10881
11017
  ok: !available || extensionExists,
@@ -10949,7 +11085,7 @@ async function cmdConnectors(action, rest, json) {
10949
11085
  let connectorsCfg;
10950
11086
  const configPath = resolveConfigPath();
10951
11087
  try {
10952
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
11088
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
10953
11089
  connectorsCfg = parseConfigQuietly(raw).connectors;
10954
11090
  } catch {
10955
11091
  process.stderr.write(
@@ -11025,10 +11161,10 @@ async function cmdConnectors(action, rest, json) {
11025
11161
  }
11026
11162
  initLogger2();
11027
11163
  const configPath = resolveConfigPath();
11028
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
11029
- const remnicCfg = resolveRemnicConfigRecord3(raw);
11030
- const config = parseConfig3(remnicCfg);
11031
- const orchestrator = new Orchestrator2(config);
11164
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
11165
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
11166
+ const config = parseConfig4(remnicCfg);
11167
+ const orchestrator = new Orchestrator3(config);
11032
11168
  try {
11033
11169
  await orchestrator.initialize();
11034
11170
  await orchestrator.deferredReady;
@@ -11150,9 +11286,9 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
11150
11286
  console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
11151
11287
  process.exit(1);
11152
11288
  }
11153
- const rawConfig = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
11154
- const pluginConfig = resolveRemnicConfigRecord3(rawConfig);
11155
- const config = parseConfig3(pluginConfig);
11289
+ const rawConfig = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
11290
+ const pluginConfig = resolveRemnicConfigRecord4(rawConfig);
11291
+ const config = parseConfig4(pluginConfig);
11156
11292
  if (subAction === "generate") {
11157
11293
  let outputDir;
11158
11294
  try {
@@ -11172,13 +11308,13 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
11172
11308
  } else if (subAction === "validate") {
11173
11309
  const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path12.join(process.cwd(), "marketplace.json");
11174
11310
  const resolved = path12.resolve(targetPath);
11175
- if (!fs10.existsSync(resolved)) {
11311
+ if (!fs11.existsSync(resolved)) {
11176
11312
  console.error(`File not found: ${resolved}`);
11177
11313
  process.exit(1);
11178
11314
  }
11179
11315
  let parsed;
11180
11316
  try {
11181
- parsed = JSON.parse(fs10.readFileSync(resolved, "utf8"));
11317
+ parsed = JSON.parse(fs11.readFileSync(resolved, "utf8"));
11182
11318
  } catch {
11183
11319
  console.error(`Invalid JSON in ${resolved}`);
11184
11320
  process.exit(1);
@@ -11379,10 +11515,10 @@ async function cmdSpace(action, rest, json) {
11379
11515
  async function cmdLegacyBenchmark(action, rest, json) {
11380
11516
  initLogger2();
11381
11517
  const configPath = resolveConfigPath();
11382
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
11383
- const remnicCfg = resolveRemnicConfigRecord3(raw);
11384
- const config = parseConfig3(remnicCfg);
11385
- const orchestrator = new Orchestrator2(config);
11518
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
11519
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
11520
+ const config = parseConfig4(remnicCfg);
11521
+ const orchestrator = new Orchestrator3(config);
11386
11522
  const service = new EngramAccessService2(orchestrator);
11387
11523
  const { runBenchSuite, loadBaseline, checkRegression } = await loadBenchModule();
11388
11524
  const benchConfig = {
@@ -11623,8 +11759,13 @@ async function cmdBench(rest) {
11623
11759
  } catch {
11624
11760
  }
11625
11761
  const writtenPaths = [];
11762
+ const pairedAnswerReplayCache = selectedWorkItems.some(
11763
+ (item) => item.benchmarkId === "locomo" && item.runtimeProfile === "baseline"
11764
+ ) && selectedWorkItems.some(
11765
+ (item) => item.benchmarkId === "locomo" && item.runtimeProfile === "real"
11766
+ ) ? /* @__PURE__ */ new Map() : void 0;
11626
11767
  try {
11627
- for (const { benchmarkId, runtimeProfile } of selectedWorkItems) {
11768
+ for (const { benchmarkId, runtimeProfile } of orderPairedLoCoMoWorkItems(selectedWorkItems)) {
11628
11769
  const statusId = runtimeProfiles.length > 1 ? `${benchmarkId} [${runtimeProfile}]` : benchmarkId;
11629
11770
  try {
11630
11771
  await updateBenchmarkStarted(benchStatusPath, statusId);
@@ -11636,7 +11777,8 @@ async function cmdBench(rest) {
11636
11777
  benchmarkId,
11637
11778
  runtimeProfile,
11638
11779
  benchStatusPath,
11639
- taskSelector
11780
+ taskSelector,
11781
+ pairedAnswerReplayCache
11640
11782
  );
11641
11783
  if (handledByPackage.ok) {
11642
11784
  if (handledByPackage.writtenPath) {
@@ -11772,7 +11914,7 @@ function readPid() {
11772
11914
  function inferPort() {
11773
11915
  try {
11774
11916
  const configPath = resolveConfigPath();
11775
- const raw = JSON.parse(fs10.readFileSync(configPath, "utf8"));
11917
+ const raw = JSON.parse(fs11.readFileSync(configPath, "utf8"));
11776
11918
  return raw.server?.port ?? 4318;
11777
11919
  } catch {
11778
11920
  return 4318;
@@ -11867,13 +12009,13 @@ function daemonInstall() {
11867
12009
  process.exit(1);
11868
12010
  }
11869
12011
  const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
11870
- fs10.mkdirSync(LOGS_DIR, { recursive: true });
12012
+ fs11.mkdirSync(LOGS_DIR, { recursive: true });
11871
12013
  if (isMacOS()) {
11872
12014
  const templatePath = path12.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
11873
- const template = fs10.readFileSync(templatePath, "utf8");
12015
+ const template = fs11.readFileSync(templatePath, "utf8");
11874
12016
  const plist = renderTemplate(template, vars);
11875
- fs10.mkdirSync(path12.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
11876
- fs10.writeFileSync(LAUNCHD_PLIST_PATH, plist);
12017
+ fs11.mkdirSync(path12.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
12018
+ fs11.writeFileSync(LAUNCHD_PLIST_PATH, plist);
11877
12019
  try {
11878
12020
  launchdLoadPlist(LAUNCHD_PLIST_PATH);
11879
12021
  } catch (err) {
@@ -11890,10 +12032,10 @@ function daemonInstall() {
11890
12032
  console.log(` Logs: ${LOGS_DIR}/daemon.log`);
11891
12033
  } else if (isLinux()) {
11892
12034
  const templatePath = path12.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
11893
- const template = fs10.readFileSync(templatePath, "utf8");
12035
+ const template = fs11.readFileSync(templatePath, "utf8");
11894
12036
  const unit = renderTemplate(template, vars);
11895
- fs10.mkdirSync(path12.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
11896
- fs10.writeFileSync(SYSTEMD_UNIT_PATH, unit);
12037
+ fs11.mkdirSync(path12.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
12038
+ fs11.writeFileSync(SYSTEMD_UNIT_PATH, unit);
11897
12039
  try {
11898
12040
  childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
11899
12041
  } catch (err) {
@@ -11929,7 +12071,7 @@ function daemonUninstall() {
11929
12071
  } catch {
11930
12072
  }
11931
12073
  try {
11932
- fs10.unlinkSync(plistPath);
12074
+ fs11.unlinkSync(plistPath);
11933
12075
  removed = true;
11934
12076
  console.log(`Removed launchd service: ${plistPath}`);
11935
12077
  } catch {
@@ -11949,7 +12091,7 @@ function daemonUninstall() {
11949
12091
  let removed = false;
11950
12092
  for (const unitPath of SYSTEMD_UNIT_PATHS) {
11951
12093
  try {
11952
- fs10.unlinkSync(unitPath);
12094
+ fs11.unlinkSync(unitPath);
11953
12095
  removed = true;
11954
12096
  console.log(`Removed systemd service: ${unitPath}`);
11955
12097
  } catch {
@@ -12016,13 +12158,13 @@ async function daemonStatus() {
12016
12158
  console.log(` Port: ${port}`);
12017
12159
  console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
12018
12160
  console.log(` Platform: ${process.platform}`);
12019
- console.log(` PID file: ${fs10.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
12020
- console.log(` Log file: ${fs10.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
12161
+ console.log(` PID file: ${fs11.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
12162
+ console.log(` Log file: ${fs11.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
12021
12163
  try {
12022
12164
  const configPath = resolveConfigPath();
12023
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
12024
- const remnicCfg = resolveRemnicConfigRecord3(raw);
12025
- const config = parseConfig3(remnicCfg);
12165
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
12166
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
12167
+ const config = parseConfig4(remnicCfg);
12026
12168
  const extRoot = resolveExtensionsRoot(config);
12027
12169
  const noopLog = { warn: () => {
12028
12170
  }, debug: () => {
@@ -12061,9 +12203,9 @@ function daemonStart() {
12061
12203
  return;
12062
12204
  }
12063
12205
  }
12064
- fs10.mkdirSync(PID_DIR, { recursive: true });
12065
- fs10.mkdirSync(LOGS_DIR, { recursive: true });
12066
- const logStream = fs10.openSync(LOG_FILE, "a");
12206
+ fs11.mkdirSync(PID_DIR, { recursive: true });
12207
+ fs11.mkdirSync(LOGS_DIR, { recursive: true });
12208
+ const logStream = fs11.openSync(LOG_FILE, "a");
12067
12209
  const serverBin = resolveServerBin();
12068
12210
  const isSource = serverBin.endsWith(".ts");
12069
12211
  let cmd;
@@ -12085,7 +12227,7 @@ function daemonStart() {
12085
12227
  }
12086
12228
  });
12087
12229
  child.unref();
12088
- fs10.writeFileSync(PID_FILE, String(child.pid));
12230
+ fs11.writeFileSync(PID_FILE, String(child.pid));
12089
12231
  console.log(`Started remnic server (pid ${child.pid})`);
12090
12232
  console.log(` Log: ${LOG_FILE}`);
12091
12233
  }
@@ -12119,11 +12261,11 @@ function daemonStop() {
12119
12261
  console.log("Process not found (cleaning up PID file)");
12120
12262
  }
12121
12263
  try {
12122
- fs10.unlinkSync(PID_FILE);
12264
+ fs11.unlinkSync(PID_FILE);
12123
12265
  } catch {
12124
12266
  }
12125
12267
  try {
12126
- fs10.unlinkSync(LEGACY_PID_FILE);
12268
+ fs11.unlinkSync(LEGACY_PID_FILE);
12127
12269
  } catch {
12128
12270
  }
12129
12271
  }
@@ -12251,9 +12393,9 @@ async function promptYesNo(question, defaultYes = true) {
12251
12393
  async function cmdBinary(rest) {
12252
12394
  initLogger2();
12253
12395
  const configPath = resolveConfigPath();
12254
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
12255
- const remnicCfg = resolveRemnicConfigRecord3(raw);
12256
- const config = parseConfig3(remnicCfg);
12396
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
12397
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
12398
+ const config = parseConfig4(remnicCfg);
12257
12399
  const memoryDir = resolveMemoryDir();
12258
12400
  const blConfig = {
12259
12401
  enabled: config.binaryLifecycleEnabled,
@@ -12442,7 +12584,7 @@ async function cmdOpenclawInstall(opts) {
12442
12584
  } else if (slotIsActiveLegacy) {
12443
12585
  changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
12444
12586
  }
12445
- if (!fs10.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
12587
+ if (!fs11.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
12446
12588
  if (hasLegacy && migrateLegacy) {
12447
12589
  changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
12448
12590
  }
@@ -12462,8 +12604,8 @@ async function cmdOpenclawInstall(opts) {
12462
12604
  Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
12463
12605
  return;
12464
12606
  }
12465
- if (fs10.existsSync(memoryDir)) {
12466
- const st = fs10.statSync(memoryDir);
12607
+ if (fs11.existsSync(memoryDir)) {
12608
+ const st = fs11.statSync(memoryDir);
12467
12609
  if (!st.isDirectory()) {
12468
12610
  throw new Error(
12469
12611
  `Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
@@ -12471,12 +12613,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
12471
12613
  );
12472
12614
  }
12473
12615
  } else {
12474
- fs10.mkdirSync(memoryDir, { recursive: true });
12616
+ fs11.mkdirSync(memoryDir, { recursive: true });
12475
12617
  console.log(`Created memory directory: ${memoryDir}`);
12476
12618
  }
12477
12619
  const configDir = path12.dirname(configPath);
12478
- if (!fs10.existsSync(configDir)) {
12479
- fs10.mkdirSync(configDir, { recursive: true });
12620
+ if (!fs11.existsSync(configDir)) {
12621
+ fs11.mkdirSync(configDir, { recursive: true });
12480
12622
  }
12481
12623
  atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
12482
12624
  console.log("\nDone! Summary of changes:");
@@ -12648,15 +12790,15 @@ async function cmdOpenclawMigrateEngram(opts) {
12648
12790
  }
12649
12791
  function createOpenclawUpgradeBackupDir() {
12650
12792
  const backupsRoot = path12.join(resolveHomeDir(), ".openclaw", "backups");
12651
- fs10.mkdirSync(backupsRoot, { recursive: true });
12652
- return fs10.mkdtempSync(path12.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
12793
+ fs11.mkdirSync(backupsRoot, { recursive: true });
12794
+ return fs11.mkdtempSync(path12.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
12653
12795
  }
12654
12796
  async function cmdTaxonomy(rest) {
12655
12797
  initLogger2();
12656
12798
  const configPath = resolveConfigPath();
12657
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
12658
- const remnicCfg = resolveRemnicConfigRecord3(raw);
12659
- const config = parseConfig3(remnicCfg);
12799
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
12800
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
12801
+ const config = parseConfig4(remnicCfg);
12660
12802
  if (!config.taxonomyEnabled) {
12661
12803
  console.error(
12662
12804
  "Taxonomy is disabled in config (taxonomyEnabled = false). Enable it to use taxonomy commands."
@@ -12692,8 +12834,8 @@ async function cmdTaxonomy(rest) {
12692
12834
  console.log(doc);
12693
12835
  if (config.taxonomyAutoGenResolver) {
12694
12836
  const resolverPath = path12.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12695
- fs10.mkdirSync(path12.dirname(resolverPath), { recursive: true });
12696
- fs10.writeFileSync(resolverPath, doc);
12837
+ fs11.mkdirSync(path12.dirname(resolverPath), { recursive: true });
12838
+ fs11.writeFileSync(resolverPath, doc);
12697
12839
  console.error(`Written: ${resolverPath}`);
12698
12840
  }
12699
12841
  break;
@@ -12739,7 +12881,7 @@ async function cmdTaxonomy(rest) {
12739
12881
  if (config.taxonomyAutoGenResolver) {
12740
12882
  const doc = generateResolverDocument(taxonomy);
12741
12883
  const resolverPath = path12.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12742
- fs10.writeFileSync(resolverPath, doc);
12884
+ fs11.writeFileSync(resolverPath, doc);
12743
12885
  console.error(`Regenerated: ${resolverPath}`);
12744
12886
  }
12745
12887
  break;
@@ -12770,7 +12912,7 @@ async function cmdTaxonomy(rest) {
12770
12912
  if (config.taxonomyAutoGenResolver) {
12771
12913
  const doc = generateResolverDocument(taxonomy);
12772
12914
  const resolverPath = path12.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12773
- fs10.writeFileSync(resolverPath, doc);
12915
+ fs11.writeFileSync(resolverPath, doc);
12774
12916
  console.error(`Regenerated: ${resolverPath}`);
12775
12917
  }
12776
12918
  break;
@@ -12961,12 +13103,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
12961
13103
  `Unknown training-export format "${args.format}". ${validList}`
12962
13104
  );
12963
13105
  }
12964
- if (!fs10.existsSync(args.memoryDir)) {
13106
+ if (!fs11.existsSync(args.memoryDir)) {
12965
13107
  throw new Error(
12966
13108
  `--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
12967
13109
  );
12968
13110
  }
12969
- if (!fs10.statSync(args.memoryDir).isDirectory()) {
13111
+ if (!fs11.statSync(args.memoryDir).isDirectory()) {
12970
13112
  throw new Error(
12971
13113
  `--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
12972
13114
  );
@@ -13052,10 +13194,10 @@ async function runTrainingExport(args, stdout = process.stdout) {
13052
13194
  }
13053
13195
  const formatted = adapter.formatRecords(records);
13054
13196
  const outDir = path12.dirname(args.output);
13055
- fs10.mkdirSync(outDir, { recursive: true });
13197
+ fs11.mkdirSync(outDir, { recursive: true });
13056
13198
  const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
13057
- fs10.writeFileSync(tmpPath, formatted, "utf-8");
13058
- fs10.renameSync(tmpPath, args.output);
13199
+ fs11.writeFileSync(tmpPath, formatted, "utf-8");
13200
+ fs11.renameSync(tmpPath, args.output);
13059
13201
  stdout.write(
13060
13202
  `Exported ${records.length} records to ${args.output} (${adapter.name} format)
13061
13203
  `
@@ -13224,7 +13366,7 @@ async function main(argv = process.argv.slice(2)) {
13224
13366
  }
13225
13367
  }, 500);
13226
13368
  };
13227
- fs10.watch(memoryDir, { recursive: true }, (_event, filename) => {
13369
+ fs11.watch(memoryDir, { recursive: true }, (_event, filename) => {
13228
13370
  if (filename && filename.startsWith(".")) return;
13229
13371
  rebuild();
13230
13372
  });
@@ -13232,12 +13374,12 @@ async function main(argv = process.argv.slice(2)) {
13232
13374
  });
13233
13375
  } else if (subAction === "validate") {
13234
13376
  const treeDir = outputDir;
13235
- if (!fs10.existsSync(treeDir)) {
13377
+ if (!fs11.existsSync(treeDir)) {
13236
13378
  console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
13237
13379
  process.exit(1);
13238
13380
  }
13239
13381
  const indexPath = path12.join(treeDir, "INDEX.md");
13240
- if (!fs10.existsSync(indexPath)) {
13382
+ if (!fs11.existsSync(indexPath)) {
13241
13383
  console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
13242
13384
  process.exit(1);
13243
13385
  }
@@ -13407,10 +13549,10 @@ Other:
13407
13549
  let wearablesService;
13408
13550
  try {
13409
13551
  const configPath = resolveConfigPath();
13410
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
13411
- const remnicCfg = resolveRemnicConfigRecord3(raw);
13412
- const config = parseConfig3(remnicCfg);
13413
- wearablesOrchestrator = new Orchestrator2(config);
13552
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
13553
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
13554
+ const config = parseConfig4(remnicCfg);
13555
+ wearablesOrchestrator = new Orchestrator3(config);
13414
13556
  await wearablesOrchestrator.initialize();
13415
13557
  await wearablesOrchestrator.deferredReady;
13416
13558
  wearablesService = wearablesOrchestrator.getWearablesService();
@@ -13425,6 +13567,9 @@ Other:
13425
13567
  stdout: process.stdout,
13426
13568
  stderr: process.stderr
13427
13569
  });
13570
+ if (wearablesArgs[0] === "sync" && code === 0 && wearablesOrchestrator.config.meetings.enabled) {
13571
+ await (await wearablesOrchestrator.getMeetingsService()).flushBuilds();
13572
+ }
13428
13573
  if (code !== 0) process.exitCode = code;
13429
13574
  } catch (err) {
13430
13575
  console.error(err instanceof Error ? err.message : String(err));
@@ -13442,6 +13587,10 @@ Other:
13442
13587
  }
13443
13588
  break;
13444
13589
  }
13590
+ case "meetings": {
13591
+ await runMeetingsBinaryCommand(rest);
13592
+ break;
13593
+ }
13445
13594
  case "import": {
13446
13595
  if (rest.includes("--help") || rest.includes("-h") || rest.length === 0) {
13447
13596
  console.log(IMPORT_USAGE);
@@ -13451,10 +13600,10 @@ Other:
13451
13600
  const targetFactory = async () => {
13452
13601
  if (!orchestratorSingleton) {
13453
13602
  const configPath = resolveConfigPath();
13454
- const raw = fs10.existsSync(configPath) ? JSON.parse(fs10.readFileSync(configPath, "utf8")) : {};
13455
- const remnicCfg = resolveRemnicConfigRecord3(raw);
13456
- const config = parseConfig3(remnicCfg);
13457
- orchestratorSingleton = new Orchestrator2(config);
13603
+ const raw = fs11.existsSync(configPath) ? JSON.parse(fs11.readFileSync(configPath, "utf8")) : {};
13604
+ const remnicCfg = resolveRemnicConfigRecord4(raw);
13605
+ const config = parseConfig4(remnicCfg);
13606
+ orchestratorSingleton = new Orchestrator3(config);
13458
13607
  await orchestratorSingleton.initialize();
13459
13608
  await orchestratorSingleton.deferredReady;
13460
13609
  }
@@ -13482,6 +13631,14 @@ Other:
13482
13631
  if (exitCode !== 0) process.exit(exitCode);
13483
13632
  break;
13484
13633
  }
13634
+ case "capture": {
13635
+ const exitCode = await cmdCapture(rest, {
13636
+ stdout: (line) => console.log(line),
13637
+ stderr: (line) => console.error(line)
13638
+ });
13639
+ if (exitCode !== 0) process.exit(exitCode);
13640
+ break;
13641
+ }
13485
13642
  case "capsule": {
13486
13643
  const subAction = rest[0] ?? "help";
13487
13644
  const capsuleArgs = rest.slice(1);
@@ -13638,6 +13795,10 @@ Usage:
13638
13795
  store day transcripts, trust-gated memory creation, speaker labels,
13639
13796
  and per-user corrections. Run "remnic wearables help" for details.
13640
13797
  Connectors install \xE0 la carte: npm install @remnic/connector-limitless
13798
+ remnic meetings <list|show|build>
13799
+ Retrospective meetings: list stored records, show one by id, or build
13800
+ (detect + fuse + store) a day's meetings from ingested audio + screen
13801
+ activity. Run "remnic meetings help" for details.
13641
13802
 
13642
13803
  remnic doctor Run diagnostics
13643
13804
  remnic config Show current config