@remnic/cli 9.7.15 → 9.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1004 -638
  2. package/package.json +28 -28
package/dist/index.js CHANGED
@@ -1,16 +1,35 @@
1
+ // src/enrichment-persist.ts
2
+ import { composeSalvagedEnvelope } from "@remnic/core/salvage-envelope";
3
+ async function persistEnrichmentCandidate(storage, entityName, candidate) {
4
+ await storage.writeSealedMemory(
5
+ composeSalvagedEnvelope(
6
+ "enrichment",
7
+ {
8
+ content: candidate.text,
9
+ category: candidate.category,
10
+ confidence: candidate.confidence,
11
+ tags: [...candidate.tags ?? [], "enrichment", candidate.source],
12
+ entityRef: entityName
13
+ },
14
+ { source: `enrichment:${candidate.source}` }
15
+ ),
16
+ {}
17
+ );
18
+ }
19
+
1
20
  // src/index.ts
2
- import fs7 from "fs";
21
+ import fs9 from "fs";
3
22
  import os from "os";
4
- import path11 from "path";
5
- import { createDecipheriv, createHash } from "crypto";
23
+ import path12 from "path";
24
+ import { createHash as createHash2 } from "crypto";
6
25
  import * as childProcess2 from "child_process";
7
26
  import { fileURLToPath as fileURLToPath4 } from "url";
8
27
  import { gzipSync } from "zlib";
9
28
  import {
10
- parseConfig,
29
+ parseConfig as parseConfig2,
11
30
  isOpenaiApiKeyDisabled,
12
31
  resolveEnvVars,
13
- resolveRemnicConfigRecord,
32
+ resolveRemnicConfigRecord as resolveRemnicConfigRecord2,
14
33
  Orchestrator,
15
34
  EngramAccessService,
16
35
  initLogger,
@@ -85,18 +104,19 @@ import {
85
104
  discoverMemoryExtensions,
86
105
  resolveExtensionsRoot,
87
106
  coerceInstallExtension,
88
- StorageManager,
107
+ StorageManager as StorageManager2,
89
108
  computeProcedureStats,
90
109
  formatProcedureStatsText,
91
110
  parseXrayCliOptions,
92
111
  renderXray,
93
112
  OFFLINE_SYNC_APPLY_MAX_BODY_BYTES,
94
113
  OFFLINE_SYNC_FILE_CONTENT_MAX_CHUNK_BYTES,
95
- OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES,
114
+ OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES as OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES2,
96
115
  OFFLINE_SYNC_SNAPSHOT_BASE_MAX_BODY_BYTES,
97
116
  applyOfflineSyncFileContentChunk,
98
117
  applyOfflineSyncSnapshot,
99
118
  buildOfflineSyncChangesetFromSnapshot,
119
+ drainPendingLifecycleForOfflineSync,
100
120
  compileOfflineSyncExcludeGlobs,
101
121
  buildOfflineSyncSnapshotFromBase,
102
122
  defaultOfflineSyncStatePath,
@@ -118,24 +138,6 @@ import {
118
138
  OPERATION_NAMES,
119
139
  validateCapabilitiesForMint
120
140
  } from "@remnic/core";
121
- import {
122
- AUTH_TAG_LENGTH,
123
- ENVELOPE_HEADER_SIZE,
124
- ENVELOPE_LAYOUT,
125
- ENVELOPE_SALT_LENGTH,
126
- ENVELOPE_VERSION,
127
- FILE_FORMAT_FLAGS,
128
- FILE_FORMAT_VERSION,
129
- IV_LENGTH,
130
- MAGIC_BYTES,
131
- MAGIC_HEADER_SIZE,
132
- SecureStoreLockedError,
133
- filePathAad,
134
- isEncryptedFile,
135
- keyring,
136
- readHeader,
137
- secureStoreDir
138
- } from "@remnic/core/secure-store";
139
141
 
140
142
  // src/optional-module-loader.ts
141
143
  function isSpecifierNotFoundError(err, specifier) {
@@ -186,6 +188,386 @@ async function loadWecloneExportModule() {
186
188
  return cached;
187
189
  }
188
190
 
191
+ // src/doctor-namespace-lint.ts
192
+ import { isNamespacePolicyCovered } from "@remnic/core";
193
+ function readConfiguredNamespace(remnicCfg) {
194
+ if (!("namespace" in remnicCfg)) return { invalid: false };
195
+ const value = remnicCfg.namespace;
196
+ if (typeof value === "string" && value.trim().length > 0) {
197
+ return { configuredNamespace: value.trim(), invalid: false };
198
+ }
199
+ return { invalid: true };
200
+ }
201
+ function buildNamespacePolicyCheck(args) {
202
+ if (args.invalid) {
203
+ return {
204
+ name: "Namespace policy",
205
+ ok: false,
206
+ detail: "config `namespace` is set but is not a non-empty string",
207
+ remediation: "Set `namespace` to a non-empty string (a namespacePolicies name or the default namespace), or remove it."
208
+ };
209
+ }
210
+ if (!args.config || !args.configuredNamespace) return void 0;
211
+ const covered = isNamespacePolicyCovered(args.configuredNamespace, args.config);
212
+ return {
213
+ name: "Namespace policy",
214
+ ok: covered,
215
+ warn: !covered,
216
+ detail: covered ? `configured namespace "${args.configuredNamespace}" is writable` : `configured namespace "${args.configuredNamespace}" is writable by no one \u2014 its namespacePolicies entry grants no writer, or it has no entry and is not the default namespace`,
217
+ remediation: covered ? void 0 : `Give "${args.configuredNamespace}" a namespacePolicies entry with a non-blank writePrincipals value, or set namespace to a writable one \u2014 otherwise every write is rejected and dead-lettered.`
218
+ };
219
+ }
220
+
221
+ // src/index.ts
222
+ import { WriteQuarantineStore } from "@remnic/core/write-quarantine.js";
223
+
224
+ // src/quarantine-cli.ts
225
+ function renderQuarantineList(records, format) {
226
+ if (format === "json") {
227
+ const summary = records.map((record) => ({
228
+ timestamp: record.timestamp,
229
+ operation: record.operation,
230
+ principal: record.principal,
231
+ attemptedNamespace: record.attemptedNamespace
232
+ }));
233
+ return JSON.stringify(summary, null, 2);
234
+ }
235
+ if (format !== "text") {
236
+ throw new Error(`Unsupported quarantine format: ${String(format)}`);
237
+ }
238
+ if (records.length === 0) return "No quarantined writes.";
239
+ const lines = [`Quarantined writes (${records.length}):`, ""];
240
+ for (const record of records) {
241
+ lines.push(
242
+ ` ${record.timestamp} ${record.operation} principal=${record.principal ?? "-"} attemptedNamespace=${record.attemptedNamespace}`
243
+ );
244
+ }
245
+ return lines.join("\n");
246
+ }
247
+
248
+ // src/offline-impression-rotation.ts
249
+ import fs from "fs";
250
+ import { parseConfig, resolveRemnicConfigRecord, drainPendingImpressionsForOfflineSync } from "@remnic/core";
251
+ import { LastRecallStore } from "@remnic/core/recall-state";
252
+ function parseConfigQuietly(raw) {
253
+ const originalWarn = console.warn;
254
+ console.warn = () => {
255
+ };
256
+ try {
257
+ return parseConfig(resolveRemnicConfigRecord(raw));
258
+ } finally {
259
+ console.warn = originalWarn;
260
+ }
261
+ }
262
+ var OFFLINE_CONFIG_KEYS = [
263
+ "offlineSyncExcludes",
264
+ "secureStoreEncryptOnWrite",
265
+ "recallImpressionsRotateBytes",
266
+ "recallImpressionsRotateKeep"
267
+ ];
268
+ function pickOfflineConfigRecord(raw) {
269
+ let resolved;
270
+ try {
271
+ resolved = resolveRemnicConfigRecord(raw);
272
+ } catch {
273
+ resolved = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
274
+ }
275
+ const picked = {};
276
+ for (const key of OFFLINE_CONFIG_KEYS) {
277
+ if (key in resolved) picked[key] = resolved[key];
278
+ }
279
+ return picked;
280
+ }
281
+ function resolveOfflineImpressionRotation(configPath) {
282
+ let raw;
283
+ try {
284
+ raw = fs.existsSync(configPath) ? JSON.parse(fs.readFileSync(configPath, "utf8")) : {};
285
+ } catch {
286
+ throw new Error(
287
+ `cannot read recall-impression rotation from ${configPath}: config file could not be read as JSON`
288
+ );
289
+ }
290
+ let config;
291
+ try {
292
+ config = parseConfigQuietly(pickOfflineConfigRecord(raw));
293
+ } catch {
294
+ throw new Error(
295
+ `cannot read recall-impression rotation from ${configPath}: config failed validation`
296
+ );
297
+ }
298
+ return {
299
+ impressionsRotateBytes: config.recallImpressionsRotateBytes,
300
+ impressionsRotateKeep: config.recallImpressionsRotateKeep
301
+ };
302
+ }
303
+ async function drainOfflineSyncImpressions(memoryDir, rotation) {
304
+ await drainPendingImpressionsForOfflineSync(
305
+ () => new LastRecallStore(memoryDir, {
306
+ impressionsRotateBytes: rotation.impressionsRotateBytes,
307
+ impressionsRotateKeep: rotation.impressionsRotateKeep
308
+ }).drainPendingImpressions()
309
+ );
310
+ }
311
+
312
+ // src/offline-storage-io.ts
313
+ import { mkdtemp, readdir, lstat, rm } from "fs/promises";
314
+ import fs2 from "fs";
315
+ import path from "path";
316
+ import { createHash, createDecipheriv } from "crypto";
317
+ import {
318
+ OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES,
319
+ StorageManager
320
+ } from "@remnic/core";
321
+ import { OFFLINE_DECRYPT_STAGING_DIR_PREFIX } from "@remnic/core/offline-sync-exclude-globs";
322
+ import {
323
+ AUTH_TAG_LENGTH,
324
+ ENVELOPE_HEADER_SIZE,
325
+ ENVELOPE_LAYOUT,
326
+ ENVELOPE_SALT_LENGTH,
327
+ ENVELOPE_VERSION,
328
+ FILE_FORMAT_FLAGS,
329
+ FILE_FORMAT_VERSION,
330
+ IV_LENGTH,
331
+ MAGIC_BYTES,
332
+ MAGIC_HEADER_SIZE,
333
+ SecureStoreLockedError,
334
+ filePathAad,
335
+ isEncryptedFile,
336
+ keyring,
337
+ readHeader,
338
+ secureStoreDir
339
+ } from "@remnic/core/secure-store";
340
+ async function createConfiguredOfflineStorage(memoryDir, secureStoreEncryptOnWrite = true) {
341
+ const storage = new StorageManager(memoryDir);
342
+ const header = await readHeader(memoryDir);
343
+ let secureStoreKey = null;
344
+ let secureStoreRequired = false;
345
+ if (header) {
346
+ secureStoreRequired = true;
347
+ storage.setSecureStoreRequired(true);
348
+ const key = keyring.getKey(secureStoreDir(memoryDir));
349
+ if (key) {
350
+ storage.setSecureStoreKey(key, secureStoreEncryptOnWrite);
351
+ secureStoreKey = key;
352
+ }
353
+ }
354
+ return { storage, secureStoreKey, secureStoreRequired };
355
+ }
356
+ function createOfflineStorageForPath(memoryDir, filePath, configured, secureStoreEncryptOnWrite) {
357
+ const memoryRoot = path.resolve(memoryDir);
358
+ const stateDir = path.dirname(filePath);
359
+ if (path.basename(stateDir) !== "state" || path.basename(filePath) !== "memory-lifecycle-ledger.jsonl") {
360
+ throw new Error(`invalid lifecycle ledger path: ${filePath}`);
361
+ }
362
+ const storageRoot = path.resolve(path.dirname(stateDir));
363
+ if (storageRoot !== memoryRoot && !storageRoot.startsWith(`${memoryRoot}${path.sep}`)) {
364
+ throw new Error(`lifecycle ledger path is outside the offline memory directory: ${filePath}`);
365
+ }
366
+ const storage = new StorageManager(storageRoot);
367
+ if (configured.secureStoreRequired) {
368
+ storage.setSecureStoreRequired(true);
369
+ }
370
+ if (configured.secureStoreKey) {
371
+ storage.setSecureStoreKey(configured.secureStoreKey, secureStoreEncryptOnWrite);
372
+ }
373
+ return storage;
374
+ }
375
+ async function createOfflineStorageIo(memoryDir, configuredStorage) {
376
+ await cleanupOrphanedOfflineDecryptStaging(memoryDir);
377
+ const { storage, secureStoreKey } = configuredStorage ?? await createConfiguredOfflineStorage(memoryDir);
378
+ return {
379
+ readFile: async ({ filePath }) => storage.readOfflineSyncFile(filePath),
380
+ readFileDigest: async ({ filePath }) => {
381
+ const hash = createHash("sha256");
382
+ let bytes = 0;
383
+ for await (const rawChunk of readOfflineSyncFileChunks({
384
+ filePath,
385
+ memoryDir,
386
+ secureStoreKey,
387
+ chunkSize: OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES
388
+ })) {
389
+ const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
390
+ hash.update(chunk);
391
+ bytes += chunk.length;
392
+ }
393
+ return {
394
+ sha256: hash.digest("hex"),
395
+ bytes
396
+ };
397
+ },
398
+ readFileChunks: ({ filePath, chunkSize }) => readOfflineSyncFileChunks({
399
+ filePath,
400
+ memoryDir,
401
+ secureStoreKey,
402
+ chunkSize
403
+ }),
404
+ writeFile: async ({ filePath, content }) => storage.writeOfflineSyncFile(filePath, content),
405
+ writeStagingFile: async ({ filePath, content }) => storage.writeOfflineSyncStagingFile(filePath, content),
406
+ writeFileChunks: async ({ filePath, chunks }) => storage.writeOfflineSyncFileChunks(filePath, chunks),
407
+ deleteFile: async ({ filePath }) => storage.deleteOfflineSyncFile(filePath)
408
+ };
409
+ }
410
+ var OFFLINE_DECRYPT_STAGING_ORPHAN_MS = 60 * 60 * 1e3;
411
+ async function cleanupOrphanedOfflineDecryptStaging(memoryDir) {
412
+ let entries;
413
+ try {
414
+ entries = await readdir(memoryDir);
415
+ } catch {
416
+ return;
417
+ }
418
+ const now = Date.now();
419
+ for (const name of entries) {
420
+ if (!name.startsWith(OFFLINE_DECRYPT_STAGING_DIR_PREFIX)) continue;
421
+ const dir = path.join(memoryDir, name);
422
+ try {
423
+ const info = await lstat(dir);
424
+ if (!info.isDirectory() || info.isSymbolicLink()) continue;
425
+ if (now - info.mtimeMs < OFFLINE_DECRYPT_STAGING_ORPHAN_MS) continue;
426
+ await rm(dir, { recursive: true, force: true });
427
+ } catch {
428
+ }
429
+ }
430
+ }
431
+ async function* readOfflineSyncFileChunks(options) {
432
+ const header = await readFilePrefix(options.filePath, MAGIC_HEADER_SIZE);
433
+ if (!isEncryptedFile(header)) {
434
+ yield* readPlainOfflineFileChunks(options.filePath, options.chunkSize);
435
+ return;
436
+ }
437
+ if (!options.secureStoreKey) {
438
+ throw new SecureStoreLockedError(
439
+ `secure-store is locked \u2014 cannot read encrypted file at ${options.filePath}. Run \`remnic secure-store unlock\` to decrypt.`
440
+ );
441
+ }
442
+ yield* readEncryptedOfflineFileChunks({
443
+ filePath: options.filePath,
444
+ memoryDir: options.memoryDir,
445
+ key: options.secureStoreKey,
446
+ chunkSize: options.chunkSize
447
+ });
448
+ }
449
+ async function readFilePrefix(filePath, length) {
450
+ const handle = await fs2.promises.open(filePath, "r");
451
+ try {
452
+ const out = Buffer.alloc(length);
453
+ const { bytesRead } = await handle.read(out, 0, length, 0);
454
+ return out.subarray(0, bytesRead);
455
+ } finally {
456
+ await handle.close();
457
+ }
458
+ }
459
+ async function* readPlainOfflineFileChunks(filePath, chunkSize) {
460
+ const stream = fs2.createReadStream(filePath, { highWaterMark: chunkSize });
461
+ for await (const chunk of stream) {
462
+ yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
463
+ }
464
+ }
465
+ async function* readEncryptedOfflineFileChunks(options) {
466
+ const header = await readFilePrefix(options.filePath, MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE);
467
+ if (header.length < MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE || !isEncryptedFile(header)) {
468
+ throw new Error(`secure-store encrypted file is truncated: ${options.filePath}`);
469
+ }
470
+ const version = header.readUInt8(MAGIC_BYTES.length);
471
+ const flags = header.readUInt8(MAGIC_BYTES.length + 1);
472
+ if (version !== FILE_FORMAT_VERSION) {
473
+ throw new Error(`secure-store file has unsupported version ${version}: ${options.filePath}`);
474
+ }
475
+ if (flags !== FILE_FORMAT_FLAGS) {
476
+ throw new Error(`secure-store file has unsupported flags 0x${flags.toString(16)}: ${options.filePath}`);
477
+ }
478
+ const envelopeHeader = header.subarray(MAGIC_HEADER_SIZE);
479
+ const envelopeVersion = envelopeHeader.readUInt8(ENVELOPE_LAYOUT.version);
480
+ if (envelopeVersion !== ENVELOPE_VERSION) {
481
+ throw new Error(`secure-store envelope has unsupported version ${envelopeVersion}: ${options.filePath}`);
482
+ }
483
+ const salt = envelopeHeader.subarray(
484
+ ENVELOPE_LAYOUT.salt,
485
+ ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH
486
+ );
487
+ const iv = envelopeHeader.subarray(ENVELOPE_LAYOUT.iv, ENVELOPE_LAYOUT.iv + IV_LENGTH);
488
+ const authTag = envelopeHeader.subarray(
489
+ ENVELOPE_LAYOUT.authTag,
490
+ ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH
491
+ );
492
+ const aadCandidates = offlineFileAadCandidates(options.filePath, options.memoryDir);
493
+ let lastError;
494
+ for (const aad of aadCandidates) {
495
+ const tempDir = await mkdtemp(path.join(options.memoryDir, OFFLINE_DECRYPT_STAGING_DIR_PREFIX));
496
+ const tempPath = path.join(tempDir, "content");
497
+ try {
498
+ const decipher = createDecipheriv("aes-256-gcm", options.key, iv, {
499
+ authTagLength: AUTH_TAG_LENGTH
500
+ });
501
+ decipher.setAuthTag(authTag);
502
+ decipher.setAAD(Buffer.concat([secureStoreEnvelopeHeaderAad(salt), aad]));
503
+ const output = fs2.createWriteStream(tempPath, { mode: 384 });
504
+ try {
505
+ const stream = fs2.createReadStream(options.filePath, {
506
+ start: MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE,
507
+ highWaterMark: options.chunkSize
508
+ });
509
+ for await (const encryptedChunk of stream) {
510
+ const plain = decipher.update(
511
+ Buffer.isBuffer(encryptedChunk) ? encryptedChunk : Buffer.from(encryptedChunk)
512
+ );
513
+ if (plain.length > 0 && !output.write(plain)) {
514
+ await new Promise((resolve, reject) => {
515
+ output.once("drain", resolve);
516
+ output.once("error", reject);
517
+ });
518
+ }
519
+ }
520
+ const finalPlain = decipher.final();
521
+ if (finalPlain.length > 0 && !output.write(finalPlain)) {
522
+ await new Promise((resolve, reject) => {
523
+ output.once("drain", resolve);
524
+ output.once("error", reject);
525
+ });
526
+ }
527
+ } finally {
528
+ await closeWriteStream(output);
529
+ }
530
+ yield* readPlainOfflineFileChunks(tempPath, options.chunkSize);
531
+ return;
532
+ } catch (error) {
533
+ lastError = error;
534
+ } finally {
535
+ await rm(tempDir, { recursive: true, force: true });
536
+ }
537
+ }
538
+ throw lastError instanceof Error ? lastError : new Error(`secure-store could not decrypt file: ${options.filePath}`);
539
+ }
540
+ function offlineFileAadCandidates(filePath, memoryDir) {
541
+ const candidates = [filePathAad(filePath, memoryDir)];
542
+ const relative = path.relative(memoryDir, filePath);
543
+ if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) return candidates;
544
+ const parts = relative.split(path.sep);
545
+ if (parts[0] === "namespaces" && parts.length >= 3 && parts[1]) {
546
+ candidates.push(filePathAad(filePath, path.join(memoryDir, "namespaces", parts[1])));
547
+ }
548
+ const memoryParts = path.resolve(memoryDir).split(path.sep);
549
+ if (memoryParts.length >= 3 && memoryParts.at(-2) === "namespaces" && memoryParts.at(-1)) {
550
+ const topLevelRoot = memoryParts.slice(0, -2).join(path.sep) || path.sep;
551
+ const topRelative = path.relative(topLevelRoot, filePath);
552
+ if (topRelative && !topRelative.startsWith("..") && !path.isAbsolute(topRelative) && topRelative.split(path.sep)[0] === "namespaces" && topRelative.split(path.sep)[1] === memoryParts.at(-1)) {
553
+ candidates.push(filePathAad(filePath, topLevelRoot));
554
+ }
555
+ }
556
+ return candidates;
557
+ }
558
+ async function closeWriteStream(stream) {
559
+ await new Promise((resolve, reject) => {
560
+ stream.once("error", reject);
561
+ stream.end(() => resolve());
562
+ });
563
+ }
564
+ function secureStoreEnvelopeHeaderAad(salt) {
565
+ const out = Buffer.alloc(1 + ENVELOPE_SALT_LENGTH);
566
+ out.writeUInt8(ENVELOPE_VERSION, 0);
567
+ Buffer.from(salt).copy(out, 1);
568
+ return out;
569
+ }
570
+
189
571
  // src/bench-build-freshness.ts
190
572
  import {
191
573
  existsSync,
@@ -194,15 +576,15 @@ import {
194
576
  readFileSync,
195
577
  statSync
196
578
  } from "fs";
197
- import path from "path";
579
+ import path2 from "path";
198
580
  import { fileURLToPath } from "url";
199
581
  var STALE_BUILD_TOLERANCE_MS = 1e3;
200
582
  function assertLocalBenchBuildFreshForDevelopment(currentModuleUrl) {
201
583
  if (isTruthyEnv(process.env.REMNIC_BENCH_ALLOW_STALE_DIST)) {
202
584
  return;
203
585
  }
204
- const currentDir = path.dirname(fileURLToPath(currentModuleUrl));
205
- const benchPackageDir = path.resolve(currentDir, "../../bench");
586
+ const currentDir = path2.dirname(fileURLToPath(currentModuleUrl));
587
+ const benchPackageDir = path2.resolve(currentDir, "../../bench");
206
588
  const freshness = checkBenchBuildFreshness(benchPackageDir);
207
589
  if (!freshness.stale) {
208
590
  return;
@@ -219,7 +601,7 @@ function assertLocalBenchBuildFreshForDevelopment(currentModuleUrl) {
219
601
  );
220
602
  }
221
603
  function checkBenchBuildFreshness(benchPackageDir) {
222
- const packageJsonPath = path.join(benchPackageDir, "package.json");
604
+ const packageJsonPath = path2.join(benchPackageDir, "package.json");
223
605
  if (!existsSync(packageJsonPath)) {
224
606
  return { stale: false };
225
607
  }
@@ -232,17 +614,17 @@ function checkBenchBuildFreshness(benchPackageDir) {
232
614
  if (packageName !== "@remnic/bench") {
233
615
  return { stale: false };
234
616
  }
235
- const srcDir = path.join(benchPackageDir, "src");
617
+ const srcDir = path2.join(benchPackageDir, "src");
236
618
  if (!isDirectory(srcDir)) {
237
619
  return { stale: false };
238
620
  }
239
621
  const sourceRoots = [
240
622
  srcDir,
241
623
  packageJsonPath,
242
- path.join(benchPackageDir, "tsup.config.ts"),
243
- path.join(benchPackageDir, "tsconfig.json")
624
+ path2.join(benchPackageDir, "tsup.config.ts"),
625
+ path2.join(benchPackageDir, "tsconfig.json")
244
626
  ];
245
- const distPath = path.join(benchPackageDir, "dist", "index.js");
627
+ const distPath = path2.join(benchPackageDir, "dist", "index.js");
246
628
  if (!existsSync(distPath)) {
247
629
  return {
248
630
  stale: true,
@@ -285,7 +667,7 @@ function newestMtime(roots) {
285
667
  }
286
668
  if (stat.isDirectory()) {
287
669
  for (const child of readdirSync(entryPath)) {
288
- visit(path.join(entryPath, child));
670
+ visit(path2.join(entryPath, child));
289
671
  }
290
672
  return;
291
673
  }
@@ -318,18 +700,18 @@ function isTruthyEnv(value) {
318
700
 
319
701
  // src/optional-bench.ts
320
702
  import { existsSync as existsSync2 } from "fs";
321
- import path2 from "path";
703
+ import path3 from "path";
322
704
  import { fileURLToPath as fileURLToPath2, pathToFileURL } from "url";
323
705
  var SPECIFIER2 = "@remnic/bench";
324
706
  var TSX_ESM_API_SPECIFIER = "tsx/esm/api";
325
707
  var cached2;
326
708
  var cachedFromLocalWorkspaceBenchSource = false;
327
709
  function resolveLocalWorkspaceBenchPaths() {
328
- const currentDir = path2.dirname(fileURLToPath2(import.meta.url));
329
- const benchPackageDir = path2.resolve(currentDir, "../../bench");
710
+ const currentDir = path3.dirname(fileURLToPath2(import.meta.url));
711
+ const benchPackageDir = path3.resolve(currentDir, "../../bench");
330
712
  return {
331
- distEntry: path2.join(benchPackageDir, "dist", "index.js"),
332
- sourceEntry: path2.join(benchPackageDir, "src", "index.ts")
713
+ distEntry: path3.join(benchPackageDir, "dist", "index.js"),
714
+ sourceEntry: path3.join(benchPackageDir, "src", "index.ts")
333
715
  };
334
716
  }
335
717
  async function tryImportLocalWorkspaceBenchSource(err) {
@@ -416,8 +798,8 @@ function assertBenchModuleFreshForDevelopment() {
416
798
  }
417
799
 
418
800
  // src/daemon-service-candidates.ts
419
- import fs from "fs";
420
- import path3 from "path";
801
+ import fs3 from "fs";
802
+ import path4 from "path";
421
803
  var LAUNCHD_LABEL = "ai.remnic.daemon";
422
804
  var LEGACY_REMNIC_SERVER_LAUNCHD_LABEL = "ai.remnic.server";
423
805
  var LEGACY_LAUNCHD_LABEL = "ai.engram.daemon";
@@ -430,15 +812,15 @@ var SYSTEMD_SERVICE = "remnic.service";
430
812
  var LEGACY_SYSTEMD_SERVICE = "engram.service";
431
813
  var SYSTEMD_SERVICE_CANDIDATES = [SYSTEMD_SERVICE, LEGACY_SYSTEMD_SERVICE];
432
814
  function launchdPlistPaths(homeDir) {
433
- return LAUNCHD_LABEL_CANDIDATES.map((label) => path3.join(homeDir, "Library", "LaunchAgents", `${label}.plist`));
815
+ return LAUNCHD_LABEL_CANDIDATES.map((label) => path4.join(homeDir, "Library", "LaunchAgents", `${label}.plist`));
434
816
  }
435
817
  function systemdUnitPaths(homeDir) {
436
- return SYSTEMD_SERVICE_CANDIDATES.map((service) => path3.join(homeDir, ".config", "systemd", "user", service));
818
+ return SYSTEMD_SERVICE_CANDIDATES.map((service) => path4.join(homeDir, ".config", "systemd", "user", service));
437
819
  }
438
820
  function anyFileExists(paths) {
439
821
  return paths.some((candidate) => {
440
822
  try {
441
- return fs.statSync(candidate).isFile();
823
+ return fs3.statSync(candidate).isFile();
442
824
  } catch {
443
825
  return false;
444
826
  }
@@ -450,7 +832,7 @@ function commandNames(command) {
450
832
  }
451
833
  function isRunnableNodeScript(filePath) {
452
834
  try {
453
- const text = fs.readFileSync(filePath, "utf8").slice(0, 4096);
835
+ const text = fs3.readFileSync(filePath, "utf8").slice(0, 4096);
454
836
  const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
455
837
  if (/^#!.*\bnode\b/.test(firstLine)) return true;
456
838
  if (firstLine.startsWith("#!")) return false;
@@ -463,20 +845,20 @@ function isRunnableNodeScript(filePath) {
463
845
  function resolveShimNodeScript(filePath) {
464
846
  let text;
465
847
  try {
466
- text = fs.readFileSync(filePath, "utf8").slice(0, 16384);
848
+ text = fs3.readFileSync(filePath, "utf8").slice(0, 16384);
467
849
  } catch {
468
850
  return void 0;
469
851
  }
470
- const basedir = path3.dirname(filePath);
852
+ const basedir = path4.dirname(filePath);
471
853
  const jsReferencePattern = /"([^"]+\.js)"|'([^']+\.js)'|([^\s"'`]+\.js)/g;
472
854
  for (const match of text.matchAll(jsReferencePattern)) {
473
855
  const raw = match[1] ?? match[2] ?? match[3];
474
856
  if (!raw) continue;
475
857
  const candidate = raw.replaceAll("${basedir}", basedir).replaceAll("$basedir", basedir).replaceAll("\\ ", " ");
476
- const resolved = path3.isAbsolute(candidate) ? candidate : path3.resolve(basedir, candidate);
858
+ const resolved = path4.isAbsolute(candidate) ? candidate : path4.resolve(basedir, candidate);
477
859
  try {
478
- if (fs.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
479
- return fs.realpathSync(resolved);
860
+ if (fs3.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
861
+ return fs3.realpathSync(resolved);
480
862
  }
481
863
  } catch {
482
864
  }
@@ -484,19 +866,19 @@ function resolveShimNodeScript(filePath) {
484
866
  return void 0;
485
867
  }
486
868
  function resolveRunnableNodeScript(filePath) {
487
- const realPath = fs.realpathSync(filePath);
869
+ const realPath = fs3.realpathSync(filePath);
488
870
  if (isRunnableNodeScript(realPath)) return realPath;
489
871
  return resolveShimNodeScript(realPath);
490
872
  }
491
873
  function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
492
- for (const dir of pathEnv.split(path3.delimiter)) {
874
+ for (const dir of pathEnv.split(path4.delimiter)) {
493
875
  if (!dir) continue;
494
876
  for (const name of commandNames(command)) {
495
- const candidate = path3.join(dir, name);
877
+ const candidate = path4.join(dir, name);
496
878
  try {
497
- const stat = fs.statSync(candidate);
879
+ const stat = fs3.statSync(candidate);
498
880
  if (!stat.isFile()) continue;
499
- if (process.platform !== "win32") fs.accessSync(candidate, fs.constants.X_OK);
881
+ if (process.platform !== "win32") fs3.accessSync(candidate, fs3.constants.X_OK);
500
882
  const runnable = resolveRunnableNodeScript(candidate);
501
883
  if (runnable) return runnable;
502
884
  } catch {
@@ -506,11 +888,11 @@ function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
506
888
  return void 0;
507
889
  }
508
890
  function serverBinWrapperRequiredPath(candidate) {
509
- const filename = path3.basename(candidate);
891
+ const filename = path4.basename(candidate);
510
892
  if (filename !== "remnic-server.js" && filename !== "engram-server.js") return void 0;
511
- const binDir = path3.dirname(candidate);
512
- if (path3.basename(binDir) !== "bin") return void 0;
513
- return path3.join(path3.dirname(binDir), "dist", "index.js");
893
+ const binDir = path4.dirname(candidate);
894
+ if (path4.basename(binDir) !== "bin") return void 0;
895
+ return path4.join(path4.dirname(binDir), "dist", "index.js");
514
896
  }
515
897
 
516
898
  // src/service-candidates.ts
@@ -532,7 +914,7 @@ function firstSuccessfulCandidate(candidates, attempt) {
532
914
  }
533
915
 
534
916
  // src/bench-args.ts
535
- import path4 from "path";
917
+ import path5 from "path";
536
918
 
537
919
  // src/path-utils.ts
538
920
  function resolveHomeDir() {
@@ -1632,13 +2014,13 @@ function parseBenchArgs(argv) {
1632
2014
  mcpUrl,
1633
2015
  mcpToolMap,
1634
2016
  mcpDemo,
1635
- datasetDir: datasetDir ? path4.resolve(expandTilde(datasetDir)) : void 0,
1636
- resultsDir: resultsDir ? path4.resolve(expandTilde(resultsDir)) : void 0,
1637
- baselinesDir: baselinesDir ? path4.resolve(expandTilde(baselinesDir)) : void 0,
2017
+ datasetDir: datasetDir ? path5.resolve(expandTilde(datasetDir)) : void 0,
2018
+ resultsDir: resultsDir ? path5.resolve(expandTilde(resultsDir)) : void 0,
2019
+ baselinesDir: baselinesDir ? path5.resolve(expandTilde(baselinesDir)) : void 0,
1638
2020
  runtimeProfile,
1639
2021
  matrixProfiles,
1640
- remnicConfigPath: remnicConfigRaw ? path4.resolve(expandTilde(remnicConfigRaw)) : void 0,
1641
- openclawConfigPath: openclawConfigRaw ? path4.resolve(expandTilde(openclawConfigRaw)) : void 0,
2022
+ remnicConfigPath: remnicConfigRaw ? path5.resolve(expandTilde(remnicConfigRaw)) : void 0,
2023
+ openclawConfigPath: openclawConfigRaw ? path5.resolve(expandTilde(openclawConfigRaw)) : void 0,
1642
2024
  modelSource,
1643
2025
  gatewayAgentId,
1644
2026
  fastGatewayAgentId,
@@ -1661,13 +2043,13 @@ function parseBenchArgs(argv) {
1661
2043
  internalDisableThinking: args.includes("--internal-disable-thinking"),
1662
2044
  internalCodexReasoningEffort,
1663
2045
  threshold,
1664
- custom: customRaw ? path4.resolve(expandTilde(customRaw)) : void 0,
2046
+ custom: customRaw ? path5.resolve(expandTilde(customRaw)) : void 0,
1665
2047
  baselineAction,
1666
2048
  datasetAction,
1667
2049
  providerAction,
1668
2050
  runAction,
1669
2051
  format,
1670
- output: output ? path4.resolve(expandTilde(output)) : void 0,
2052
+ output: output ? path5.resolve(expandTilde(output)) : void 0,
1671
2053
  target,
1672
2054
  publishedName,
1673
2055
  publishedSeed,
@@ -1677,24 +2059,24 @@ function parseBenchArgs(argv) {
1677
2059
  publishedIngestConcurrency,
1678
2060
  publishedTaskFilter,
1679
2061
  memcorrectAdapter,
1680
- publishedOut: publishedOutRaw ? path4.resolve(expandTilde(publishedOutRaw)) : void 0,
2062
+ publishedOut: publishedOutRaw ? path5.resolve(expandTilde(publishedOutRaw)) : void 0,
1681
2063
  publishedDryRun: args.includes("--dry-run"),
1682
2064
  requestTimeout,
1683
2065
  localJudgeRequestTimeout,
1684
2066
  frontierJudgeRequestTimeout,
1685
- calibrationDir: calibrationDirRaw ? path4.resolve(expandTilde(calibrationDirRaw)) : void 0,
2067
+ calibrationDir: calibrationDirRaw ? path5.resolve(expandTilde(calibrationDirRaw)) : void 0,
1686
2068
  calibrationLocalConfigSha256,
1687
2069
  calibrationFrontierConfigSha256,
1688
2070
  sourceResultId,
1689
2071
  expectedAnswerSetSha256,
1690
2072
  expectedQuestionIdListSha256,
1691
- taskIdsFile: taskIdsFileRaw ? path4.resolve(expandTilde(taskIdsFileRaw)) : void 0,
2073
+ taskIdsFile: taskIdsFileRaw ? path5.resolve(expandTilde(taskIdsFileRaw)) : void 0,
1692
2074
  expectedTaskIdListSha256,
1693
2075
  drainTimeout,
1694
2076
  // Issue #1573 PR1: surface judge-cache flags into the runner options.
1695
2077
  noJudgeCache: args.includes("--no-judge-cache"),
1696
- judgeCacheDir: judgeCacheDirRaw ? path4.resolve(expandTilde(judgeCacheDirRaw)) : void 0,
1697
- localLabManifestPath: localLabManifestRaw ? path4.resolve(expandTilde(localLabManifestRaw)) : void 0,
2078
+ judgeCacheDir: judgeCacheDirRaw ? path5.resolve(expandTilde(judgeCacheDirRaw)) : void 0,
2079
+ localLabManifestPath: localLabManifestRaw ? path5.resolve(expandTilde(localLabManifestRaw)) : void 0,
1698
2080
  max429WaitMs,
1699
2081
  disableThinking: args.includes("--disable-thinking"),
1700
2082
  amaBenchJudgeProtocol,
@@ -1709,23 +2091,23 @@ function parseBenchArgs(argv) {
1709
2091
  }
1710
2092
 
1711
2093
  // src/bench-status.ts
1712
- import { mkdir, readFile, readdir, rename, writeFile } from "fs/promises";
1713
- import path5 from "path";
2094
+ import { mkdir, readFile, readdir as readdir2, rename, writeFile } from "fs/promises";
2095
+ import path6 from "path";
1714
2096
  function createBenchStatusPath(resultsDir, pid, startedAtMs = Date.now()) {
1715
- return path5.join(resultsDir, `bench-status-${startedAtMs}-${pid}.json`);
2097
+ return path6.join(resultsDir, `bench-status-${startedAtMs}-${pid}.json`);
1716
2098
  }
1717
2099
  var BENCH_STATUS_FILENAME = /^bench-status-\d+-\d+\.json$/;
1718
2100
  var VALID_BENCH_ENTRY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "complete", "failed"]);
1719
2101
  async function findLatestBenchStatusFile(resultsDir) {
1720
2102
  let entries;
1721
2103
  try {
1722
- entries = await readdir(resultsDir);
2104
+ entries = await readdir2(resultsDir);
1723
2105
  } catch {
1724
2106
  return null;
1725
2107
  }
1726
2108
  const candidates = entries.filter((name) => BENCH_STATUS_FILENAME.test(name)).sort().reverse();
1727
2109
  for (const name of candidates) {
1728
- const filePath = path5.join(resultsDir, name);
2110
+ const filePath = path6.join(resultsDir, name);
1729
2111
  const status = await readBenchStatus(filePath);
1730
2112
  if (status) {
1731
2113
  return filePath;
@@ -1734,7 +2116,7 @@ async function findLatestBenchStatusFile(resultsDir) {
1734
2116
  return null;
1735
2117
  }
1736
2118
  async function atomicWriteJSON(filePath, data) {
1737
- await mkdir(path5.dirname(filePath), { recursive: true });
2119
+ await mkdir(path6.dirname(filePath), { recursive: true });
1738
2120
  const tmp = `${filePath}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;
1739
2121
  await writeFile(tmp, JSON.stringify(data, null, 2) + "\n");
1740
2122
  await rename(tmp, filePath);
@@ -1851,8 +2233,8 @@ function finalizeBenchStatus(filePath) {
1851
2233
  }
1852
2234
 
1853
2235
  // src/bench-fallback.ts
1854
- import fs2 from "fs";
1855
- import path6 from "path";
2236
+ import fs4 from "fs";
2237
+ import path7 from "path";
1856
2238
  var FALLBACK_RESULTS_DIRNAME = "fallback-runs";
1857
2239
  function buildBenchRunnerArgs(parsed, benchmarkId, outputDir) {
1858
2240
  const args = ["--benchmark", benchmarkId];
@@ -1916,34 +2298,34 @@ function findUnsupportedFallbackBenchOptions(parsed) {
1916
2298
  return unsupported;
1917
2299
  }
1918
2300
  function createFallbackBenchOutputDir(resultsDir, benchmarkId, pid, startedAtMs = Date.now()) {
1919
- return path6.join(
2301
+ return path7.join(
1920
2302
  resultsDir,
1921
2303
  FALLBACK_RESULTS_DIRNAME,
1922
2304
  `${benchmarkId}-${startedAtMs}-${pid}`
1923
2305
  );
1924
2306
  }
1925
2307
  function resolveFallbackBenchResultPath(outputDir) {
1926
- const entries = fs2.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
2308
+ const entries = fs4.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
1927
2309
  if (entries.length === 0) {
1928
2310
  throw new Error(`Fallback benchmark runner did not write a JSON result artifact in ${outputDir}`);
1929
2311
  }
1930
- return path6.join(outputDir, entries[0]);
2312
+ return path7.join(outputDir, entries[0]);
1931
2313
  }
1932
2314
 
1933
2315
  // src/openclaw-upgrade-swap.ts
1934
- import fs3 from "fs";
1935
- import path7 from "path";
2316
+ import fs5 from "fs";
2317
+ import path8 from "path";
1936
2318
  function describeError(error) {
1937
2319
  return error instanceof Error ? error.message : String(error);
1938
2320
  }
1939
2321
  function createSiblingTempFilePath(targetPath, label) {
1940
2322
  const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
1941
- return path7.join(path7.dirname(targetPath), `.${path7.basename(targetPath)}.${label}.${nonce}.tmp`);
2323
+ return path8.join(path8.dirname(targetPath), `.${path8.basename(targetPath)}.${label}.${nonce}.tmp`);
1942
2324
  }
1943
2325
  function resolveAtomicWriteMode(targetPath, explicitMode) {
1944
2326
  if (explicitMode !== void 0) return explicitMode;
1945
2327
  try {
1946
- return fs3.statSync(targetPath).mode & 4095;
2328
+ return fs5.statSync(targetPath).mode & 4095;
1947
2329
  } catch (error) {
1948
2330
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
1949
2331
  return 384;
@@ -1953,8 +2335,8 @@ function resolveAtomicWriteMode(targetPath, explicitMode) {
1953
2335
  }
1954
2336
  function resolveAtomicReplacementPath(targetPath) {
1955
2337
  try {
1956
- if (fs3.lstatSync(targetPath).isSymbolicLink()) {
1957
- return fs3.realpathSync(targetPath);
2338
+ if (fs5.lstatSync(targetPath).isSymbolicLink()) {
2339
+ return fs5.realpathSync(targetPath);
1958
2340
  }
1959
2341
  } catch (error) {
1960
2342
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -1966,12 +2348,12 @@ function resolveAtomicReplacementPath(targetPath) {
1966
2348
  }
1967
2349
  function createSiblingSwapPath(targetDir, label) {
1968
2350
  const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
1969
- return path7.join(path7.dirname(targetDir), `.${path7.basename(targetDir)}.${label}.${nonce}`);
2351
+ return path8.join(path8.dirname(targetDir), `.${path8.basename(targetDir)}.${label}.${nonce}`);
1970
2352
  }
1971
2353
  function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
1972
2354
  if (!displacedDir) return void 0;
1973
2355
  try {
1974
- fs3.rmSync(displacedDir, { recursive: true, force: true });
2356
+ fs5.rmSync(displacedDir, { recursive: true, force: true });
1975
2357
  return void 0;
1976
2358
  } catch (error) {
1977
2359
  return `Warning: ${context}, but failed to remove the displaced plugin copy at ${displacedDir}: ${describeError(error)}`;
@@ -1979,55 +2361,55 @@ function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
1979
2361
  }
1980
2362
  function atomicWriteFileSync(targetPath, data, options = {}) {
1981
2363
  const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
1982
- fs3.mkdirSync(path7.dirname(resolvedTargetPath), { recursive: true });
2364
+ fs5.mkdirSync(path8.dirname(resolvedTargetPath), { recursive: true });
1983
2365
  const tempPath = createSiblingTempFilePath(resolvedTargetPath, "write");
1984
2366
  const mode = resolveAtomicWriteMode(resolvedTargetPath, options.mode);
1985
2367
  try {
1986
2368
  if (options.hooks?.writeTempFileSync) {
1987
2369
  options.hooks.writeTempFileSync(tempPath);
1988
2370
  } else {
1989
- fs3.writeFileSync(tempPath, data, { mode });
2371
+ fs5.writeFileSync(tempPath, data, { mode });
1990
2372
  }
1991
- fs3.chmodSync(tempPath, mode);
1992
- const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs3.renameSync;
2373
+ fs5.chmodSync(tempPath, mode);
2374
+ const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs5.renameSync;
1993
2375
  renameTempFileSync(tempPath, resolvedTargetPath);
1994
2376
  } catch (error) {
1995
- fs3.rmSync(tempPath, { force: true });
2377
+ fs5.rmSync(tempPath, { force: true });
1996
2378
  throw error;
1997
2379
  }
1998
2380
  }
1999
2381
  function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
2000
- if (!fs3.existsSync(sourcePath)) return;
2382
+ if (!fs5.existsSync(sourcePath)) return;
2001
2383
  const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
2002
- fs3.mkdirSync(path7.dirname(resolvedTargetPath), { recursive: true });
2384
+ fs5.mkdirSync(path8.dirname(resolvedTargetPath), { recursive: true });
2003
2385
  const tempPath = createSiblingTempFilePath(resolvedTargetPath, "copy");
2004
- const mode = fs3.statSync(sourcePath).mode & 4095;
2386
+ const mode = fs5.statSync(sourcePath).mode & 4095;
2005
2387
  try {
2006
- const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs3.copyFileSync;
2388
+ const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs5.copyFileSync;
2007
2389
  copyTempFileSync(sourcePath, tempPath);
2008
- fs3.chmodSync(tempPath, mode);
2009
- const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs3.renameSync;
2390
+ fs5.chmodSync(tempPath, mode);
2391
+ const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs5.renameSync;
2010
2392
  renameTempFileSync(tempPath, resolvedTargetPath);
2011
2393
  } catch (error) {
2012
- fs3.rmSync(tempPath, { force: true });
2394
+ fs5.rmSync(tempPath, { force: true });
2013
2395
  throw error;
2014
2396
  }
2015
2397
  }
2016
2398
  function swapDirectoryWithRollback(stagedDir, targetDir, rollbackDir) {
2017
2399
  let hasRollbackCopy = false;
2018
- fs3.mkdirSync(path7.dirname(targetDir), { recursive: true });
2019
- fs3.rmSync(rollbackDir, { recursive: true, force: true });
2020
- if (fs3.existsSync(targetDir)) {
2021
- fs3.renameSync(targetDir, rollbackDir);
2400
+ fs5.mkdirSync(path8.dirname(targetDir), { recursive: true });
2401
+ fs5.rmSync(rollbackDir, { recursive: true, force: true });
2402
+ if (fs5.existsSync(targetDir)) {
2403
+ fs5.renameSync(targetDir, rollbackDir);
2022
2404
  hasRollbackCopy = true;
2023
2405
  }
2024
2406
  try {
2025
- fs3.renameSync(stagedDir, targetDir);
2407
+ fs5.renameSync(stagedDir, targetDir);
2026
2408
  } catch (swapError) {
2027
- fs3.rmSync(targetDir, { recursive: true, force: true });
2028
- if (hasRollbackCopy && fs3.existsSync(rollbackDir)) {
2409
+ fs5.rmSync(targetDir, { recursive: true, force: true });
2410
+ if (hasRollbackCopy && fs5.existsSync(rollbackDir)) {
2029
2411
  try {
2030
- fs3.renameSync(rollbackDir, targetDir);
2412
+ fs5.renameSync(rollbackDir, targetDir);
2031
2413
  hasRollbackCopy = false;
2032
2414
  } catch (restoreError) {
2033
2415
  throw new AggregateError(
@@ -2042,7 +2424,7 @@ function swapDirectoryWithRollback(stagedDir, targetDir, rollbackDir) {
2042
2424
  }
2043
2425
  function cleanupRollbackDirectory(rollbackDir) {
2044
2426
  if (!rollbackDir) return;
2045
- fs3.rmSync(rollbackDir, { recursive: true, force: true });
2427
+ fs5.rmSync(rollbackDir, { recursive: true, force: true });
2046
2428
  }
2047
2429
  function cleanupRollbackDirectoryBestEffort(rollbackDir) {
2048
2430
  if (!rollbackDir) return void 0;
@@ -2054,20 +2436,20 @@ function cleanupRollbackDirectoryBestEffort(rollbackDir) {
2054
2436
  }
2055
2437
  }
2056
2438
  function restoreDirectoryFromRollback(targetDir, rollbackDir) {
2057
- if (!fs3.existsSync(rollbackDir)) {
2439
+ if (!fs5.existsSync(rollbackDir)) {
2058
2440
  throw new Error(`Rollback directory is missing: ${rollbackDir}`);
2059
2441
  }
2060
- fs3.mkdirSync(path7.dirname(targetDir), { recursive: true });
2061
- const displacedDir = fs3.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
2442
+ fs5.mkdirSync(path8.dirname(targetDir), { recursive: true });
2443
+ const displacedDir = fs5.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
2062
2444
  if (displacedDir) {
2063
- fs3.renameSync(targetDir, displacedDir);
2445
+ fs5.renameSync(targetDir, displacedDir);
2064
2446
  }
2065
2447
  try {
2066
- fs3.renameSync(rollbackDir, targetDir);
2448
+ fs5.renameSync(rollbackDir, targetDir);
2067
2449
  } catch (restoreError) {
2068
- if (displacedDir && fs3.existsSync(displacedDir)) {
2450
+ if (displacedDir && fs5.existsSync(displacedDir)) {
2069
2451
  try {
2070
- fs3.renameSync(displacedDir, targetDir);
2452
+ fs5.renameSync(displacedDir, targetDir);
2071
2453
  } catch (revertError) {
2072
2454
  throw new AggregateError(
2073
2455
  [restoreError, revertError],
@@ -2086,23 +2468,23 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
2086
2468
  );
2087
2469
  }
2088
2470
  function restoreDirectoryFromBackup(targetDir, backupDir) {
2089
- if (!fs3.existsSync(backupDir)) {
2471
+ if (!fs5.existsSync(backupDir)) {
2090
2472
  throw new Error(`Plugin backup directory is missing: ${backupDir}`);
2091
2473
  }
2092
- fs3.mkdirSync(path7.dirname(targetDir), { recursive: true });
2474
+ fs5.mkdirSync(path8.dirname(targetDir), { recursive: true });
2093
2475
  const stagedDir = createSiblingSwapPath(targetDir, "backup-restore");
2094
- const displacedDir = fs3.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
2095
- fs3.cpSync(backupDir, stagedDir, { recursive: true });
2476
+ const displacedDir = fs5.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
2477
+ fs5.cpSync(backupDir, stagedDir, { recursive: true });
2096
2478
  if (displacedDir) {
2097
- fs3.renameSync(targetDir, displacedDir);
2479
+ fs5.renameSync(targetDir, displacedDir);
2098
2480
  }
2099
2481
  try {
2100
- fs3.renameSync(stagedDir, targetDir);
2482
+ fs5.renameSync(stagedDir, targetDir);
2101
2483
  } catch (restoreError) {
2102
- fs3.rmSync(targetDir, { recursive: true, force: true });
2103
- if (displacedDir && fs3.existsSync(displacedDir)) {
2484
+ fs5.rmSync(targetDir, { recursive: true, force: true });
2485
+ if (displacedDir && fs5.existsSync(displacedDir)) {
2104
2486
  try {
2105
- fs3.renameSync(displacedDir, targetDir);
2487
+ fs5.renameSync(displacedDir, targetDir);
2106
2488
  } catch (revertError) {
2107
2489
  throw new AggregateError(
2108
2490
  [restoreError, revertError],
@@ -2110,7 +2492,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
2110
2492
  );
2111
2493
  }
2112
2494
  }
2113
- fs3.rmSync(stagedDir, { recursive: true, force: true });
2495
+ fs5.rmSync(stagedDir, { recursive: true, force: true });
2114
2496
  throw new Error(
2115
2497
  `Failed to restore the plugin backup into ${targetDir}. The durable backup remains preserved at ${backupDir}.`,
2116
2498
  { cause: restoreError }
@@ -2136,7 +2518,7 @@ function rollbackOpenclawUpgrade({
2136
2518
  let rollbackRestoreError;
2137
2519
  let pluginRestored = false;
2138
2520
  try {
2139
- if (rollbackDir && fs3.existsSync(rollbackDir)) {
2521
+ if (rollbackDir && fs5.existsSync(rollbackDir)) {
2140
2522
  const cleanupWarning = restoreDirectoryFromRollback(pluginDir, rollbackDir);
2141
2523
  notes.push(`Restored previous plugin from rollback copy at ${rollbackDir}`);
2142
2524
  if (cleanupWarning) notes.push(cleanupWarning);
@@ -2146,7 +2528,7 @@ function rollbackOpenclawUpgrade({
2146
2528
  rollbackRestoreError = error instanceof Error ? error.message : String(error);
2147
2529
  }
2148
2530
  try {
2149
- if (!pluginRestored && pluginBackupDir && fs3.existsSync(pluginBackupDir)) {
2531
+ if (!pluginRestored && pluginBackupDir && fs5.existsSync(pluginBackupDir)) {
2150
2532
  const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
2151
2533
  if (rollbackRestoreError) {
2152
2534
  notes.push(
@@ -2173,7 +2555,7 @@ function rollbackOpenclawUpgrade({
2173
2555
  notes.push("No previous plugin copy was available for automatic restore");
2174
2556
  }
2175
2557
  try {
2176
- if (configBackupPath && fs3.existsSync(configBackupPath)) {
2558
+ if (configBackupPath && fs5.existsSync(configBackupPath)) {
2177
2559
  restoreFileFromBackup(configPath, configBackupPath);
2178
2560
  notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
2179
2561
  }
@@ -2213,11 +2595,11 @@ Run this manually when you're ready:
2213
2595
  }
2214
2596
 
2215
2597
  // src/daemon-service.ts
2216
- import fs4 from "fs";
2217
- import path8 from "path";
2598
+ import fs6 from "fs";
2599
+ import path9 from "path";
2218
2600
  import * as childProcess from "child_process";
2219
2601
  import { fileURLToPath as fileURLToPath3 } from "url";
2220
- var thisModuleDir = path8.dirname(fileURLToPath3(import.meta.url));
2602
+ var thisModuleDir = path9.dirname(fileURLToPath3(import.meta.url));
2221
2603
  function launchdLoadPlist(plistPath, processApi = childProcess) {
2222
2604
  processApi.execFileSync("launchctl", ["load", "-w", plistPath], { stdio: "pipe" });
2223
2605
  }
@@ -2225,7 +2607,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
2225
2607
  processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
2226
2608
  }
2227
2609
  function resolveServerBinDetails(options = {}) {
2228
- const existsSync3 = options.existsSync ?? fs4.existsSync;
2610
+ const existsSync3 = options.existsSync ?? fs6.existsSync;
2229
2611
  const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
2230
2612
  const moduleDir = options.moduleDir ?? thisModuleDir;
2231
2613
  const packageResolve = options.packageResolve ?? resolveImportSpecifier;
@@ -2239,8 +2621,8 @@ function resolveServerBinDetails(options = {}) {
2239
2621
  });
2240
2622
  } catch {
2241
2623
  }
2242
- const workspaceServerBin = path8.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
2243
- const workspaceDistIndex = path8.resolve(moduleDir, "../../remnic-server/dist/index.js");
2624
+ const workspaceServerBin = path9.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
2625
+ const workspaceDistIndex = path9.resolve(moduleDir, "../../remnic-server/dist/index.js");
2244
2626
  candidates.push(
2245
2627
  {
2246
2628
  path: workspaceServerBin,
@@ -2261,11 +2643,11 @@ function resolveServerBinDetails(options = {}) {
2261
2643
  });
2262
2644
  }
2263
2645
  candidates.push({
2264
- path: path8.resolve(moduleDir, "../../remnic-server/src/index.ts"),
2646
+ path: path9.resolve(moduleDir, "../../remnic-server/src/index.ts"),
2265
2647
  source: "workspace-source"
2266
2648
  });
2267
2649
  const selected = candidates.find((candidate) => isCandidateReady(candidate, existsSync3)) ?? candidates.find((candidate) => existsSync3(candidate.path)) ?? candidates[0] ?? {
2268
- path: path8.resolve(moduleDir, "../../remnic-server/dist/index.js"),
2650
+ path: path9.resolve(moduleDir, "../../remnic-server/dist/index.js"),
2269
2651
  source: "workspace-dist"
2270
2652
  };
2271
2653
  const exists = existsSync3(selected.path);
@@ -2284,8 +2666,8 @@ function resolveServerBin(options = {}) {
2284
2666
  return resolveServerBinDetails(options).path;
2285
2667
  }
2286
2668
  function readVerifiedDaemonPid(options) {
2287
- const readFileSync3 = options.readFileSync ?? fs4.readFileSync;
2288
- const unlinkSync = options.unlinkSync ?? fs4.unlinkSync;
2669
+ const readFileSync3 = options.readFileSync ?? fs6.readFileSync;
2670
+ const unlinkSync = options.unlinkSync ?? fs6.unlinkSync;
2289
2671
  const processKill = options.processKill ?? process.kill;
2290
2672
  const platform = options.platform ?? process.platform;
2291
2673
  const execFileSync3 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
@@ -2320,7 +2702,7 @@ function readVerifiedDaemonPid(options) {
2320
2702
  }
2321
2703
  function doesProcessCommandLookLikeRemnicDaemon(command, expectedServerBin) {
2322
2704
  const normalizedCommand = command.trim();
2323
- const normalizedExpected = path8.resolve(expandTilde(expectedServerBin));
2705
+ const normalizedExpected = path9.resolve(expandTilde(expectedServerBin));
2324
2706
  return normalizedCommand.includes(normalizedExpected) || /(?:^|\s|[/\\])(?:remnic-server|engram-server)(?:\.js)?(?:\s|$)/.test(normalizedCommand) || /@remnic[/\\]server[/\\]/.test(normalizedCommand) || /packages[/\\]remnic-server[/\\](?:bin[/\\]remnic-server\.js|dist[/\\]index\.js|src[/\\]index\.ts)/.test(normalizedCommand);
2325
2707
  }
2326
2708
  function parseDaemonPid(raw) {
@@ -2385,8 +2767,8 @@ function removePidFileBestEffort(file, unlinkSync) {
2385
2767
  }
2386
2768
  }
2387
2769
  function inspectLaunchdPlist(plistPath, options = {}) {
2388
- const existsSync3 = options.existsSync ?? fs4.existsSync;
2389
- const readFileSync3 = options.readFileSync ?? fs4.readFileSync;
2770
+ const existsSync3 = options.existsSync ?? fs6.existsSync;
2771
+ const readFileSync3 = options.readFileSync ?? fs6.readFileSync;
2390
2772
  if (!existsSync3(plistPath)) {
2391
2773
  return {
2392
2774
  installed: false,
@@ -2425,7 +2807,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
2425
2807
  };
2426
2808
  }
2427
2809
  const expandedServerArg = expandTilde(serverArg);
2428
- if (!path8.isAbsolute(expandedServerArg)) {
2810
+ if (!path9.isAbsolute(expandedServerArg)) {
2429
2811
  return {
2430
2812
  installed: true,
2431
2813
  ok: false,
@@ -2497,8 +2879,8 @@ function normalizeResolvedPath(resolved) {
2497
2879
  return resolved;
2498
2880
  }
2499
2881
  function packageServerBinFromEntry(packageEntry) {
2500
- if (path8.basename(packageEntry) === "index.js" && path8.basename(path8.dirname(packageEntry)) === "dist") {
2501
- return path8.join(path8.dirname(path8.dirname(packageEntry)), "bin", "remnic-server.js");
2882
+ if (path9.basename(packageEntry) === "index.js" && path9.basename(path9.dirname(packageEntry)) === "dist") {
2883
+ return path9.join(path9.dirname(path9.dirname(packageEntry)), "bin", "remnic-server.js");
2502
2884
  }
2503
2885
  return packageEntry;
2504
2886
  }
@@ -2620,7 +3002,7 @@ function stripConfigArgv(args) {
2620
3002
  }
2621
3003
 
2622
3004
  // src/import-dispatch.ts
2623
- import fs5 from "fs";
3005
+ import fs7 from "fs";
2624
3006
  import {
2625
3007
  runImporter,
2626
3008
  validateImportBatchSize,
@@ -2629,9 +3011,9 @@ import {
2629
3011
 
2630
3012
  // src/import-bundle-detect.ts
2631
3013
  import { lstatSync as lstatSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
2632
- import path9 from "path";
3014
+ import path10 from "path";
2633
3015
  function detectBundleEntries(bundleDir, options = {}) {
2634
- const readdir2 = options.readdirImpl ?? defaultReaddir;
3016
+ const readdir3 = options.readdirImpl ?? defaultReaddir;
2635
3017
  const readFileImpl = options.readFileImpl ?? defaultReadFile;
2636
3018
  const isDirectory2 = options.isDirectoryImpl ?? defaultIsDirectory;
2637
3019
  const isRegularFile = options.isRegularFileImpl ?? (options.readdirImpl !== void 0 || options.isDirectoryImpl !== void 0 ? (p) => !isDirectory2(p) : defaultIsRegularFile);
@@ -2651,7 +3033,7 @@ function detectBundleEntries(bundleDir, options = {}) {
2651
3033
  }
2652
3034
  const roots = collectCandidatePaths(
2653
3035
  bundleDir,
2654
- readdir2,
3036
+ readdir3,
2655
3037
  isDirectory2,
2656
3038
  isRegularFile
2657
3039
  );
@@ -2660,7 +3042,7 @@ function detectBundleEntries(bundleDir, options = {}) {
2660
3042
  for (const filePath of roots) {
2661
3043
  if (seenFiles.has(filePath)) continue;
2662
3044
  seenFiles.add(filePath);
2663
- const name = path9.basename(filePath);
3045
+ const name = path10.basename(filePath);
2664
3046
  const match = classifyFile(name, filePath, readFileImpl);
2665
3047
  if (match) entries.push(match);
2666
3048
  }
@@ -2680,9 +3062,9 @@ function detectBundleEntries(bundleDir, options = {}) {
2680
3062
  return entries;
2681
3063
  }
2682
3064
  var MAX_WALK_DEPTH = 4;
2683
- function collectCandidatePaths(root, readdir2, isDirectory2, isRegularFile) {
3065
+ function collectCandidatePaths(root, readdir3, isDirectory2, isRegularFile) {
2684
3066
  try {
2685
- readdir2(root);
3067
+ readdir3(root);
2686
3068
  } catch {
2687
3069
  throw new Error(
2688
3070
  `Bundle directory '${root}' could not be read. Pass an existing directory.`
@@ -2693,12 +3075,12 @@ function collectCandidatePaths(root, readdir2, isDirectory2, isRegularFile) {
2693
3075
  if (depth > MAX_WALK_DEPTH) return;
2694
3076
  let entries;
2695
3077
  try {
2696
- entries = readdir2(dir);
3078
+ entries = readdir3(dir);
2697
3079
  } catch {
2698
3080
  return;
2699
3081
  }
2700
3082
  for (const entry of entries) {
2701
- const full = path9.join(dir, entry);
3083
+ const full = path10.join(dir, entry);
2702
3084
  if (isDirectory2(full)) {
2703
3085
  walk(full, depth + 1);
2704
3086
  } else if (isRegularFile(full)) {
@@ -3134,7 +3516,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
3134
3516
  let materializedTarget;
3135
3517
  let materializePromise;
3136
3518
  const io = {
3137
- readFile: ioOverrides.readFile ?? (async (p) => fs5.promises.readFile(p, "utf-8")),
3519
+ readFile: ioOverrides.readFile ?? (async (p) => fs7.promises.readFile(p, "utf-8")),
3138
3520
  loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
3139
3521
  runImporter: ioOverrides.runImporter ?? runImporter,
3140
3522
  getWriteTarget: async () => {
@@ -3207,8 +3589,8 @@ function takeOptionalValue(args, flag) {
3207
3589
  }
3208
3590
 
3209
3591
  // src/import-lossless-claw-cmd.ts
3210
- import fs6 from "fs";
3211
- import path10 from "path";
3592
+ import fs8 from "fs";
3593
+ import path11 from "path";
3212
3594
  import {
3213
3595
  applyLcmSchema,
3214
3596
  ensureLcmStateDir,
@@ -3319,15 +3701,15 @@ async function loadImportLosslessClawModule() {
3319
3701
 
3320
3702
  // src/import-lossless-claw-cmd.ts
3321
3703
  function assertDirectoryOrAbsent(p, label) {
3322
- if (fs6.existsSync(p) && !fs6.statSync(p).isDirectory()) {
3704
+ if (fs8.existsSync(p) && !fs8.statSync(p).isDirectory()) {
3323
3705
  throw new Error(`${label} is not a directory: ${p}`);
3324
3706
  }
3325
3707
  }
3326
3708
  function assertFile(p, label) {
3327
- if (!fs6.existsSync(p)) {
3709
+ if (!fs8.existsSync(p)) {
3328
3710
  throw new Error(`${label} does not exist: ${p}`);
3329
3711
  }
3330
- if (!fs6.statSync(p).isFile()) {
3712
+ if (!fs8.statSync(p).isFile()) {
3331
3713
  throw new Error(`${label} is not a file: ${p}`);
3332
3714
  }
3333
3715
  }
@@ -3358,8 +3740,8 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
3358
3740
  let destDb;
3359
3741
  try {
3360
3742
  if (parsed.dryRun) {
3361
- const lcmPath = path10.join(memoryDir, "state", "lcm.sqlite");
3362
- if (fs6.existsSync(lcmPath)) {
3743
+ const lcmPath = path11.join(memoryDir, "state", "lcm.sqlite");
3744
+ if (fs8.existsSync(lcmPath)) {
3363
3745
  destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
3364
3746
  } else {
3365
3747
  destDb = mod.openInMemoryDestinationDatabase();
@@ -3451,15 +3833,15 @@ registerPublisher("omp", () => new LazyPluginPiPublisher("omp", (mod) => mod.Omp
3451
3833
  function readCompatEnv(primary, legacy) {
3452
3834
  return process.env[primary] ?? process.env[legacy];
3453
3835
  }
3454
- var PID_DIR = path11.join(resolveHomeDir(), ".remnic");
3455
- var LEGACY_PID_DIR = path11.join(resolveHomeDir(), ".engram");
3456
- var PID_FILE = path11.join(PID_DIR, "server.pid");
3457
- var LEGACY_PID_FILE = path11.join(LEGACY_PID_DIR, "server.pid");
3458
- var LOG_FILE = path11.join(PID_DIR, "server.log");
3459
- var LEGACY_LOG_FILE = path11.join(LEGACY_PID_DIR, "server.log");
3460
- var CLI_MODULE_DIR = path11.dirname(fileURLToPath4(import.meta.url));
3461
- var CLI_REPO_ROOT = path11.resolve(CLI_MODULE_DIR, "../../..");
3462
- var EVAL_RUNNER_PATH = path11.join(CLI_REPO_ROOT, "evals", "run.ts");
3836
+ var PID_DIR = path12.join(resolveHomeDir(), ".remnic");
3837
+ var LEGACY_PID_DIR = path12.join(resolveHomeDir(), ".engram");
3838
+ var PID_FILE = path12.join(PID_DIR, "server.pid");
3839
+ var LEGACY_PID_FILE = path12.join(LEGACY_PID_DIR, "server.pid");
3840
+ var LOG_FILE = path12.join(PID_DIR, "server.log");
3841
+ var LEGACY_LOG_FILE = path12.join(LEGACY_PID_DIR, "server.log");
3842
+ var CLI_MODULE_DIR = path12.dirname(fileURLToPath4(import.meta.url));
3843
+ var CLI_REPO_ROOT = path12.resolve(CLI_MODULE_DIR, "../../..");
3844
+ var EVAL_RUNNER_PATH = path12.join(CLI_REPO_ROOT, "evals", "run.ts");
3463
3845
  var OPENCLAW_GATEWAY_LABEL = "ai.openclaw.gateway";
3464
3846
  var CLI_SUCCESS_EXIT_GRACE_MS = 5e3;
3465
3847
  var CLI_OUTPUT_FLUSH_GRACE_MS = 250;
@@ -3792,7 +4174,7 @@ async function resolveAllBenchmarks() {
3792
4174
  if (packageBenchmarks) {
3793
4175
  return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
3794
4176
  }
3795
- if (!fs7.existsSync(EVAL_RUNNER_PATH)) {
4177
+ if (!fs9.existsSync(EVAL_RUNNER_PATH)) {
3796
4178
  return [];
3797
4179
  }
3798
4180
  return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
@@ -3840,17 +4222,17 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
3840
4222
  `Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
3841
4223
  );
3842
4224
  }
3843
- if (!fs7.existsSync(EVAL_RUNNER_PATH)) {
4225
+ if (!fs9.existsSync(EVAL_RUNNER_PATH)) {
3844
4226
  console.error(
3845
4227
  "Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
3846
4228
  );
3847
4229
  process.exit(1);
3848
4230
  }
3849
4231
  const tsxCandidates = [
3850
- path11.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
3851
- path11.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
4232
+ path12.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
4233
+ path12.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
3852
4234
  ];
3853
- const tsxCmd = tsxCandidates.find((candidate) => fs7.existsSync(candidate)) ?? "tsx";
4235
+ const tsxCmd = tsxCandidates.find((candidate) => fs9.existsSync(candidate)) ?? "tsx";
3854
4236
  const fallbackOutputDir = createFallbackBenchOutputDir(
3855
4237
  parsed.resultsDir ?? resolveBenchOutputDir(),
3856
4238
  benchmarkId,
@@ -3867,7 +4249,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
3867
4249
  return resolveFallbackBenchResultPath(fallbackOutputDir);
3868
4250
  }
3869
4251
  function resolveBenchOutputDir() {
3870
- return path11.join(resolveHomeDir(), ".remnic", "bench", "results");
4252
+ return path12.join(resolveHomeDir(), ".remnic", "bench", "results");
3871
4253
  }
3872
4254
  var DOWNLOADABLE_BENCHMARK_DATASETS = [
3873
4255
  "ama-bench",
@@ -3912,8 +4294,8 @@ var MEMORY_AGENT_BENCH_SPLIT_FILENAMES = [
3912
4294
  ];
3913
4295
  var MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES = [
3914
4296
  "entity2id.json",
3915
- path11.join("processed_data", "Recsys_Redial", "entity2id.json"),
3916
- path11.join("Recsys_Redial", "entity2id.json")
4297
+ path12.join("processed_data", "Recsys_Redial", "entity2id.json"),
4298
+ path12.join("Recsys_Redial", "entity2id.json")
3917
4299
  ];
3918
4300
  var DOWNLOADED_DATASET_MARKERS = {
3919
4301
  "ama-bench": { anyOf: ["open_end_qa_set.jsonl"] },
@@ -3988,18 +4370,18 @@ var PERSONAMEM_DATASET_FILE_CANDIDATES = [
3988
4370
  "benchmark/benchmark.csv",
3989
4371
  "benchmark.csv"
3990
4372
  ];
3991
- var PERSONAMEM_COMPLETION_MARKER = path11.join(
4373
+ var PERSONAMEM_COMPLETION_MARKER = path12.join(
3992
4374
  "data",
3993
4375
  "chat_history_32k",
3994
4376
  ".download-complete"
3995
4377
  );
3996
4378
  function resolveRealpathWithinDataset(datasetPath, relativePath) {
3997
4379
  try {
3998
- const datasetRoot = fs7.realpathSync(datasetPath);
3999
- const candidatePath = path11.resolve(datasetRoot, relativePath);
4000
- const candidateRealPath = fs7.realpathSync(candidatePath);
4001
- const relativeToRoot = path11.relative(datasetRoot, candidateRealPath);
4002
- if (relativeToRoot.startsWith("..") || path11.isAbsolute(relativeToRoot)) {
4380
+ const datasetRoot = fs9.realpathSync(datasetPath);
4381
+ const candidatePath = path12.resolve(datasetRoot, relativePath);
4382
+ const candidateRealPath = fs9.realpathSync(candidatePath);
4383
+ const relativeToRoot = path12.relative(datasetRoot, candidateRealPath);
4384
+ if (relativeToRoot.startsWith("..") || path12.isAbsolute(relativeToRoot)) {
4003
4385
  return null;
4004
4386
  }
4005
4387
  return candidateRealPath;
@@ -4055,15 +4437,15 @@ function parseCsvRows(raw) {
4055
4437
  }
4056
4438
  function isPersonaMemDatasetComplete(datasetPath) {
4057
4439
  try {
4058
- const completionMarkerPath = path11.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
4059
- if (fs7.statSync(completionMarkerPath).isFile()) {
4440
+ const completionMarkerPath = path12.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
4441
+ if (fs9.statSync(completionMarkerPath).isFile()) {
4060
4442
  return true;
4061
4443
  }
4062
4444
  } catch {
4063
4445
  }
4064
4446
  const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
4065
4447
  try {
4066
- return fs7.statSync(path11.join(datasetPath, candidate)).isFile();
4448
+ return fs9.statSync(path12.join(datasetPath, candidate)).isFile();
4067
4449
  } catch {
4068
4450
  return false;
4069
4451
  }
@@ -4072,7 +4454,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
4072
4454
  return false;
4073
4455
  }
4074
4456
  try {
4075
- const rows = parseCsvRows(fs7.readFileSync(path11.join(datasetPath, datasetFile), "utf8"));
4457
+ const rows = parseCsvRows(fs9.readFileSync(path12.join(datasetPath, datasetFile), "utf8"));
4076
4458
  if (rows.length < 2) {
4077
4459
  return false;
4078
4460
  }
@@ -4087,7 +4469,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
4087
4469
  }
4088
4470
  return historyPaths.every((relativePath) => {
4089
4471
  const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
4090
- return resolvedPath !== null && fs7.statSync(resolvedPath).isFile();
4472
+ return resolvedPath !== null && fs9.statSync(resolvedPath).isFile();
4091
4473
  });
4092
4474
  } catch {
4093
4475
  return false;
@@ -4095,14 +4477,14 @@ function isPersonaMemDatasetComplete(datasetPath) {
4095
4477
  }
4096
4478
  function hasDatasetFile(datasetPath, relativePath) {
4097
4479
  try {
4098
- return fs7.statSync(path11.join(datasetPath, relativePath)).isFile();
4480
+ return fs9.statSync(path12.join(datasetPath, relativePath)).isFile();
4099
4481
  } catch {
4100
4482
  return false;
4101
4483
  }
4102
4484
  }
4103
4485
  function hasMemoryAgentBenchEntityMapping(datasetPath) {
4104
- const absoluteDatasetPath = path11.resolve(datasetPath);
4105
- const roots = [absoluteDatasetPath, path11.dirname(absoluteDatasetPath)];
4486
+ const absoluteDatasetPath = path12.resolve(datasetPath);
4487
+ const roots = [absoluteDatasetPath, path12.dirname(absoluteDatasetPath)];
4106
4488
  return hasDatasetFile(absoluteDatasetPath, "entity2id.json") || roots.some(
4107
4489
  (root) => MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES.filter((relativePath) => relativePath !== "entity2id.json").some((relativePath) => hasDatasetFile(root, relativePath))
4108
4490
  );
@@ -4113,12 +4495,12 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
4113
4495
  ...MEMORY_AGENT_BENCH_SPLIT_FILENAMES
4114
4496
  ];
4115
4497
  return candidateFilenames.some((filename) => {
4116
- const filePath = path11.join(datasetPath, filename);
4498
+ const filePath = path12.join(datasetPath, filename);
4117
4499
  try {
4118
- if (!fs7.statSync(filePath).isFile()) {
4500
+ if (!fs9.statSync(filePath).isFile()) {
4119
4501
  return false;
4120
4502
  }
4121
- const raw = fs7.readFileSync(filePath, "utf8");
4503
+ const raw = fs9.readFileSync(filePath, "utf8");
4122
4504
  return /"source"\s*:\s*"recsys[_-]/i.test(raw);
4123
4505
  } catch {
4124
4506
  return false;
@@ -4134,7 +4516,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
4134
4516
  function isDatasetDownloaded(datasetPath, benchmarkId) {
4135
4517
  let stats;
4136
4518
  try {
4137
- stats = fs7.statSync(datasetPath);
4519
+ stats = fs9.statSync(datasetPath);
4138
4520
  } catch {
4139
4521
  return false;
4140
4522
  }
@@ -4144,7 +4526,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4144
4526
  const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
4145
4527
  if (!marker) {
4146
4528
  try {
4147
- return fs7.readdirSync(datasetPath).length > 0;
4529
+ return fs9.readdirSync(datasetPath).length > 0;
4148
4530
  } catch {
4149
4531
  return false;
4150
4532
  }
@@ -4152,7 +4534,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4152
4534
  if (marker.allOf) {
4153
4535
  const hasAllRequiredFiles = marker.allOf.every((name) => {
4154
4536
  try {
4155
- return fs7.statSync(path11.join(datasetPath, name)).isFile();
4537
+ return fs9.statSync(path12.join(datasetPath, name)).isFile();
4156
4538
  } catch {
4157
4539
  return false;
4158
4540
  }
@@ -4164,7 +4546,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4164
4546
  if (marker.anyOf) {
4165
4547
  const hasMarkerFile = marker.anyOf.some((name) => {
4166
4548
  try {
4167
- return fs7.statSync(path11.join(datasetPath, name)).isFile();
4549
+ return fs9.statSync(path12.join(datasetPath, name)).isFile();
4168
4550
  } catch {
4169
4551
  return false;
4170
4552
  }
@@ -4182,7 +4564,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4182
4564
  }
4183
4565
  if (marker.ext) {
4184
4566
  try {
4185
- return fs7.readdirSync(datasetPath).some(
4567
+ return fs9.readdirSync(datasetPath).some(
4186
4568
  (name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
4187
4569
  );
4188
4570
  } catch {
@@ -4192,9 +4574,9 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
4192
4574
  return false;
4193
4575
  }
4194
4576
  async function launchBenchUi(resultsDir) {
4195
- const benchUiDir = path11.join(CLI_REPO_ROOT, "packages", "bench-ui");
4577
+ const benchUiDir = path12.join(CLI_REPO_ROOT, "packages", "bench-ui");
4196
4578
  const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
4197
- if (!fs7.existsSync(path11.join(benchUiDir, "package.json"))) {
4579
+ if (!fs9.existsSync(path12.join(benchUiDir, "package.json"))) {
4198
4580
  console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
4199
4581
  process.exit(1);
4200
4582
  }
@@ -4221,24 +4603,24 @@ async function launchBenchUi(resultsDir) {
4221
4603
  });
4222
4604
  }
4223
4605
  function resolveRepoDatasetRoot() {
4224
- const repoCandidate = path11.join(CLI_REPO_ROOT, "evals", "datasets");
4606
+ const repoCandidate = path12.join(CLI_REPO_ROOT, "evals", "datasets");
4225
4607
  if (isRepoCheckout()) {
4226
4608
  return repoCandidate;
4227
4609
  }
4228
- return path11.join(resolveHomeDir(), ".remnic", "bench", "datasets");
4610
+ return path12.join(resolveHomeDir(), ".remnic", "bench", "datasets");
4229
4611
  }
4230
4612
  function listDownloadableBenchmarks() {
4231
4613
  return [...DOWNLOADABLE_BENCHMARK_DATASETS];
4232
4614
  }
4233
4615
  function resolveDatasetDownloadScriptPath() {
4234
- const bundled = path11.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
4235
- if (fs7.existsSync(bundled)) {
4616
+ const bundled = path12.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
4617
+ if (fs9.existsSync(bundled)) {
4236
4618
  return bundled;
4237
4619
  }
4238
- return path11.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
4620
+ return path12.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
4239
4621
  }
4240
4622
  function isRepoCheckout() {
4241
- return fs7.existsSync(path11.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs7.existsSync(path11.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
4623
+ return fs9.existsSync(path12.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs9.existsSync(path12.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
4242
4624
  }
4243
4625
  function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
4244
4626
  const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
@@ -4289,7 +4671,7 @@ function resolveBenchDatasetDir(benchmarkId, quick, datasetDirOverride) {
4289
4671
  if (quick) {
4290
4672
  return void 0;
4291
4673
  }
4292
- const datasetDir = path11.join(resolveRepoDatasetRoot(), benchmarkId);
4674
+ const datasetDir = path12.join(resolveRepoDatasetRoot(), benchmarkId);
4293
4675
  if (isDatasetDownloaded(datasetDir, benchmarkId)) {
4294
4676
  return datasetDir;
4295
4677
  }
@@ -4607,13 +4989,13 @@ async function exportBenchPackageResult(parsed) {
4607
4989
  process.exit(1);
4608
4990
  }
4609
4991
  const result = await loadBenchmarkResult(summary.path);
4610
- const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path11.dirname(summary.path), result.meta.id) : void 0;
4992
+ const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path12.dirname(summary.path), result.meta.id) : void 0;
4611
4993
  const rendered = renderBenchmarkResultExport(result, parsed.format, {
4612
4994
  ...reportCardProvenance ? { reportCardProvenance } : {}
4613
4995
  });
4614
4996
  if (parsed.output) {
4615
- fs7.mkdirSync(path11.dirname(parsed.output), { recursive: true });
4616
- fs7.writeFileSync(parsed.output, rendered);
4997
+ fs9.mkdirSync(path12.dirname(parsed.output), { recursive: true });
4998
+ fs9.writeFileSync(parsed.output, rendered);
4617
4999
  console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
4618
5000
  return;
4619
5001
  }
@@ -4630,7 +5012,7 @@ async function manageBenchDatasets(parsed) {
4630
5012
  process.exit(1);
4631
5013
  }
4632
5014
  const status = supported.map((benchmarkId) => {
4633
- const datasetPath = path11.join(datasetRoot, benchmarkId);
5015
+ const datasetPath = path12.join(datasetRoot, benchmarkId);
4634
5016
  return {
4635
5017
  benchmark: benchmarkId,
4636
5018
  downloaded: isDatasetDownloaded(datasetPath, benchmarkId),
@@ -4658,7 +5040,7 @@ async function manageBenchDatasets(parsed) {
4658
5040
  process.exit(1);
4659
5041
  }
4660
5042
  const scriptPath = resolveDatasetDownloadScriptPath();
4661
- if (!fs7.existsSync(scriptPath)) {
5043
+ if (!fs9.existsSync(scriptPath)) {
4662
5044
  console.error(`ERROR: dataset download script not found: ${scriptPath}`);
4663
5045
  process.exit(1);
4664
5046
  }
@@ -4668,7 +5050,7 @@ async function manageBenchDatasets(parsed) {
4668
5050
  runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, parsed.json === true);
4669
5051
  downloaded.push({
4670
5052
  benchmark: benchmarkId,
4671
- path: path11.join(datasetRoot, benchmarkId)
5053
+ path: path12.join(datasetRoot, benchmarkId)
4672
5054
  });
4673
5055
  }
4674
5056
  if (parsed.json) {
@@ -4807,10 +5189,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
4807
5189
  }
4808
5190
  const bench = await loadBenchModule();
4809
5191
  const resultsDir = expandTilde(
4810
- parsed.resultsDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "results")
5192
+ parsed.resultsDir ?? path12.join(resolveHomeDir(), ".remnic", "bench", "results")
4811
5193
  );
4812
5194
  const calibrationDir = expandTilde(
4813
- parsed.calibrationDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "calibration")
5195
+ parsed.calibrationDir ?? path12.join(resolveHomeDir(), ".remnic", "bench", "calibration")
4814
5196
  );
4815
5197
  const stored = await bench.listBenchmarkResults(resultsDir);
4816
5198
  const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
@@ -4858,7 +5240,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
4858
5240
  );
4859
5241
  process.exit(1);
4860
5242
  }
4861
- const sourceResultSha256 = createHash("sha256").update(fs7.readFileSync(latest.path)).digest("hex");
5243
+ const sourceResultSha256 = createHash2("sha256").update(fs9.readFileSync(latest.path)).digest("hex");
4862
5244
  const expandedManifestPath = expandTilde(manifestPath);
4863
5245
  if (!bench.resolveLocalLabJudgeProviderConfig) {
4864
5246
  console.error(
@@ -5266,7 +5648,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
5266
5648
  }
5267
5649
  let decoded;
5268
5650
  try {
5269
- decoded = JSON.parse(fs7.readFileSync(parsed.taskIdsFile, "utf8"));
5651
+ decoded = JSON.parse(fs9.readFileSync(parsed.taskIdsFile, "utf8"));
5270
5652
  } catch (error) {
5271
5653
  throw new Error(
5272
5654
  `Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
@@ -5363,7 +5745,7 @@ async function loadPublishedPromotionHelpers() {
5363
5745
  return {
5364
5746
  async promoteArtifactsToPublished(args) {
5365
5747
  const { mkdirSync, readFileSync: readFileSync3, writeFileSync } = await import("fs");
5366
- const path12 = await import("path");
5748
+ const path13 = await import("path");
5367
5749
  mkdirSync(args.publishedOutDir, { recursive: true });
5368
5750
  if (args.artifactPaths.length === 0) {
5369
5751
  console.warn(
@@ -5380,13 +5762,13 @@ async function loadPublishedPromotionHelpers() {
5380
5762
  const modelSlug = args.model.replace(/[^a-zA-Z0-9_.-]/g, "-");
5381
5763
  const rawProfile = parsedObj.config?.runtimeProfile;
5382
5764
  const profileSlug = typeof rawProfile === "string" && rawProfile.length > 0 ? `-${rawProfile.replace(/[^a-zA-Z0-9_.-]/g, "-")}` : "";
5383
- const target = path12.join(
5765
+ const target = path13.join(
5384
5766
  args.publishedOutDir,
5385
5767
  `${today}-${args.benchmarkId}-${modelSlug}${profileSlug}-${gitShaShort}.json`
5386
5768
  );
5387
5769
  writeFileSync(target, raw, "utf8");
5388
5770
  console.log(
5389
- `[bench published] Promoted ${path12.basename(artifactPath)} \u2192 ${target}`
5771
+ `[bench published] Promoted ${path13.basename(artifactPath)} \u2192 ${target}`
5390
5772
  );
5391
5773
  }
5392
5774
  void benchModule;
@@ -5471,7 +5853,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
5471
5853
  const previousCodexDiagnosticsDir = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV];
5472
5854
  const previousCodexDiagnosticsMode = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_MODE_ENV];
5473
5855
  if (!previousCodexDiagnosticsDir) {
5474
- process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path11.join(
5856
+ process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path12.join(
5475
5857
  outputDir,
5476
5858
  "codex-cli-diagnostics"
5477
5859
  );
@@ -5609,7 +5991,7 @@ async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmark
5609
5991
  );
5610
5992
  }
5611
5993
  const calibrationDir = expandTilde(
5612
- calibrationBinding.calibrationDir ?? path11.join(resolveHomeDir(), ".remnic", "bench", "calibration")
5994
+ calibrationBinding.calibrationDir ?? path12.join(resolveHomeDir(), ".remnic", "bench", "calibration")
5613
5995
  );
5614
5996
  const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
5615
5997
  if (!state) {
@@ -5683,7 +6065,7 @@ function attachPreparedJudgeCalibration(result, judgeCalibration) {
5683
6065
  function hashCalibrationProviderConfig(config) {
5684
6066
  const canonicalize = (value, key = "") => {
5685
6067
  if (typeof value === "string" && /(?:api.?key|authorization|token|secret)/i.test(key)) {
5686
- return { secretSha256: createHash("sha256").update(value).digest("hex") };
6068
+ return { secretSha256: createHash2("sha256").update(value).digest("hex") };
5687
6069
  }
5688
6070
  if (Array.isArray(value)) return value.map((item) => canonicalize(item));
5689
6071
  if (value && typeof value === "object") {
@@ -5694,7 +6076,7 @@ function hashCalibrationProviderConfig(config) {
5694
6076
  }
5695
6077
  return value;
5696
6078
  };
5697
- return createHash("sha256").update(JSON.stringify(canonicalize(config))).digest("hex");
6079
+ return createHash2("sha256").update(JSON.stringify(canonicalize(config))).digest("hex");
5698
6080
  }
5699
6081
  function restoreOptionalEnv(key, previousValue) {
5700
6082
  if (previousValue === void 0) {
@@ -5906,7 +6288,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
5906
6288
  return void 0;
5907
6289
  }
5908
6290
  try {
5909
- return fs7.realpathSync(datasetDir);
6291
+ return fs9.realpathSync(datasetDir);
5910
6292
  } catch {
5911
6293
  return datasetDir;
5912
6294
  }
@@ -5959,23 +6341,23 @@ async function writeBenchReproManifestForPackageRun(args) {
5959
6341
  }
5960
6342
  }
5961
6343
  function resolveConfigPath(cliPath) {
5962
- if (cliPath) return path11.resolve(expandTilde(cliPath));
6344
+ if (cliPath) return path12.resolve(expandTilde(cliPath));
5963
6345
  const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
5964
- if (envPath) return path11.resolve(expandTilde(envPath));
6346
+ if (envPath) return path12.resolve(expandTilde(envPath));
5965
6347
  const candidates = [
5966
- path11.join(process.cwd(), "remnic.config.json"),
5967
- path11.join(process.cwd(), "engram.config.json"),
5968
- path11.join(resolveHomeDir(), ".config", "remnic", "config.json"),
5969
- path11.join(resolveHomeDir(), ".config", "engram", "config.json")
6348
+ path12.join(process.cwd(), "remnic.config.json"),
6349
+ path12.join(process.cwd(), "engram.config.json"),
6350
+ path12.join(resolveHomeDir(), ".config", "remnic", "config.json"),
6351
+ path12.join(resolveHomeDir(), ".config", "engram", "config.json")
5970
6352
  ];
5971
6353
  for (const candidate of candidates) {
5972
- if (fs7.existsSync(candidate)) return candidate;
6354
+ if (fs9.existsSync(candidate)) return candidate;
5973
6355
  }
5974
- return path11.join(resolveHomeDir(), ".config", "remnic", "config.json");
6356
+ return path12.join(resolveHomeDir(), ".config", "remnic", "config.json");
5975
6357
  }
5976
6358
  function resolveExistingBenchRemnicConfigPath(cliPath) {
5977
6359
  const configPath = resolveConfigPath(cliPath);
5978
- if (fs7.existsSync(configPath)) {
6360
+ if (fs9.existsSync(configPath)) {
5979
6361
  return configPath;
5980
6362
  }
5981
6363
  if (cliPath) {
@@ -5985,7 +6367,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
5985
6367
  }
5986
6368
  function resolveExistingBenchOpenclawConfigPath(cliPath) {
5987
6369
  const configPath = resolveOpenclawConfigPath(cliPath);
5988
- if (fs7.existsSync(configPath)) {
6370
+ if (fs9.existsSync(configPath)) {
5989
6371
  return configPath;
5990
6372
  }
5991
6373
  if (cliPath) {
@@ -6085,34 +6467,34 @@ async function resolvePackageBenchRuntime(benchModule, parsed, runtimeProfile) {
6085
6467
  );
6086
6468
  }
6087
6469
  function normalizeMemoryDirPath(memoryDir) {
6088
- return path11.resolve(expandTilde(memoryDir));
6470
+ return path12.resolve(expandTilde(memoryDir));
6089
6471
  }
6090
6472
  function resolveMemoryDir() {
6091
6473
  const configMemoryDir = (() => {
6092
6474
  const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
6093
6475
  if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
6094
6476
  const configPath = resolveConfigPath();
6095
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
6096
- const remnicCfg = resolveRemnicConfigRecord(raw);
6477
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
6478
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
6097
6479
  if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
6098
6480
  return normalizeMemoryDirPath(remnicCfg.memoryDir);
6099
6481
  }
6100
6482
  const home = resolveHomeDir();
6101
- const standalonePath = path11.join(home, ".remnic", "memory");
6102
- const legacyStandalonePath = path11.join(home, ".engram", "memory");
6103
- const openclawPath = path11.join(home, ".openclaw", "workspace", "memory", "local");
6104
- if (fs7.existsSync(standalonePath)) return standalonePath;
6105
- if (fs7.existsSync(legacyStandalonePath)) return legacyStandalonePath;
6483
+ const standalonePath = path12.join(home, ".remnic", "memory");
6484
+ const legacyStandalonePath = path12.join(home, ".engram", "memory");
6485
+ const openclawPath = path12.join(home, ".openclaw", "workspace", "memory", "local");
6486
+ if (fs9.existsSync(standalonePath)) return standalonePath;
6487
+ if (fs9.existsSync(legacyStandalonePath)) return legacyStandalonePath;
6106
6488
  return openclawPath;
6107
6489
  })();
6108
6490
  const manifestPath = getManifestPath();
6109
- if (fs7.existsSync(manifestPath)) {
6491
+ if (fs9.existsSync(manifestPath)) {
6110
6492
  try {
6111
6493
  const active = getActiveSpace();
6112
6494
  if (active?.memoryDir) {
6113
6495
  const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
6114
- if (!fs7.existsSync(activeMemoryDir)) {
6115
- fs7.mkdirSync(activeMemoryDir, { recursive: true });
6496
+ if (!fs9.existsSync(activeMemoryDir)) {
6497
+ fs9.mkdirSync(activeMemoryDir, { recursive: true });
6116
6498
  }
6117
6499
  return activeMemoryDir;
6118
6500
  }
@@ -6151,20 +6533,20 @@ var REMNIC_OPENCLAW_LEGACY_PLUGIN_ID = "openclaw-engram";
6151
6533
  var DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR = [
6152
6534
  process.env.OPENCLAW_CONFIG_PATH,
6153
6535
  process.env.OPENCLAW_ENGRAM_CONFIG_PATH,
6154
- path11.join(resolveHomeDir(), ".openclaw", "openclaw.json")
6536
+ path12.join(resolveHomeDir(), ".openclaw", "openclaw.json")
6155
6537
  ].filter(Boolean);
6156
6538
  function resolveOpenclawConfigPath(cliPath) {
6157
- if (cliPath) return path11.resolve(expandTilde(cliPath));
6539
+ if (cliPath) return path12.resolve(expandTilde(cliPath));
6158
6540
  const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
6159
- if (envPath) return path11.resolve(expandTilde(envPath));
6541
+ if (envPath) return path12.resolve(expandTilde(envPath));
6160
6542
  for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
6161
- if (fs7.existsSync(candidate)) return candidate;
6543
+ if (fs9.existsSync(candidate)) return candidate;
6162
6544
  }
6163
- return path11.join(resolveHomeDir(), ".openclaw", "openclaw.json");
6545
+ return path12.join(resolveHomeDir(), ".openclaw", "openclaw.json");
6164
6546
  }
6165
6547
  function readOpenclawConfig(configPath) {
6166
- if (!fs7.existsSync(configPath)) return {};
6167
- const raw = fs7.readFileSync(configPath, "utf-8");
6548
+ if (!fs9.existsSync(configPath)) return {};
6549
+ const raw = fs9.readFileSync(configPath, "utf-8");
6168
6550
  let parsed;
6169
6551
  try {
6170
6552
  parsed = JSON.parse(raw);
@@ -6219,10 +6601,10 @@ function buildRemnicOpenclawHooksPolicy(legacyHooks, existingHooks) {
6219
6601
  function resolveOpenclawInstallMemoryDir(args) {
6220
6602
  const existingMemoryDir = (typeof args.existingNewEntryConfig.memoryDir === "string" ? args.existingNewEntryConfig.memoryDir : void 0) || (args.migrateLegacy && typeof args.legacyConfigToMerge.memoryDir === "string" ? args.legacyConfigToMerge.memoryDir : void 0);
6221
6603
  if (args.requestedMemoryDir) {
6222
- return path11.resolve(expandTilde(args.requestedMemoryDir));
6604
+ return path12.resolve(expandTilde(args.requestedMemoryDir));
6223
6605
  }
6224
6606
  if (existingMemoryDir) {
6225
- return path11.resolve(expandTilde(existingMemoryDir));
6607
+ return path12.resolve(expandTilde(existingMemoryDir));
6226
6608
  }
6227
6609
  return args.fallbackMemoryDir;
6228
6610
  }
@@ -6240,18 +6622,18 @@ function resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir) {
6240
6622
  if (!config || typeof config !== "object" || Array.isArray(config)) continue;
6241
6623
  const memoryDir = config.memoryDir;
6242
6624
  if (typeof memoryDir === "string" && memoryDir.trim().length > 0) {
6243
- return path11.resolve(expandTilde(memoryDir));
6625
+ return path12.resolve(expandTilde(memoryDir));
6244
6626
  }
6245
6627
  }
6246
6628
  return fallbackMemoryDir;
6247
6629
  }
6248
6630
  function resolveOpenclawPluginDir(cliPath) {
6249
- if (cliPath) return path11.resolve(expandTilde(cliPath));
6250
- return path11.join(resolveHomeDir(), ".openclaw", "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
6631
+ if (cliPath) return path12.resolve(expandTilde(cliPath));
6632
+ return path12.join(resolveHomeDir(), ".openclaw", "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
6251
6633
  }
6252
6634
  function resolveOpenclawLegacyPluginDir(cliPath) {
6253
- if (cliPath) return path11.resolve(expandTilde(cliPath));
6254
- return path11.join(resolveHomeDir(), ".openclaw", "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
6635
+ if (cliPath) return path12.resolve(expandTilde(cliPath));
6636
+ return path12.join(resolveHomeDir(), ".openclaw", "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
6255
6637
  }
6256
6638
  function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
6257
6639
  const yyyy = now.getFullYear().toString();
@@ -6263,14 +6645,14 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
6263
6645
  return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
6264
6646
  }
6265
6647
  function backupPathIfPresent(sourcePath, backupPath) {
6266
- if (!fs7.existsSync(sourcePath)) return false;
6267
- fs7.mkdirSync(path11.dirname(backupPath), { recursive: true });
6268
- fs7.cpSync(sourcePath, backupPath, { recursive: true });
6648
+ if (!fs9.existsSync(sourcePath)) return false;
6649
+ fs9.mkdirSync(path12.dirname(backupPath), { recursive: true });
6650
+ fs9.cpSync(sourcePath, backupPath, { recursive: true });
6269
6651
  return true;
6270
6652
  }
6271
6653
  function assertDirectoryPathOrMissing(targetPath, label) {
6272
- if (!fs7.existsSync(targetPath)) return;
6273
- const stat = fs7.statSync(targetPath);
6654
+ if (!fs9.existsSync(targetPath)) return;
6655
+ const stat = fs9.statSync(targetPath);
6274
6656
  if (!stat.isDirectory()) {
6275
6657
  throw new Error(`${label} must be a directory when it already exists: ${targetPath}`);
6276
6658
  }
@@ -6295,7 +6677,7 @@ var PublishedOpenclawPluginInstallError = class extends Error {
6295
6677
  }
6296
6678
  };
6297
6679
  function installPublishedOpenclawPlugin(spec, pluginDir) {
6298
- const tempRoot = fs7.mkdtempSync(path11.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
6680
+ const tempRoot = fs9.mkdtempSync(path12.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
6299
6681
  const stagedDir = `${pluginDir}.next-${process.pid}-${Date.now()}`;
6300
6682
  const rollbackDir = `${pluginDir}.rollback-${process.pid}-${Date.now()}`;
6301
6683
  let swapRollbackDir;
@@ -6310,17 +6692,17 @@ function installPublishedOpenclawPlugin(spec, pluginDir) {
6310
6692
  if (!tarballName) {
6311
6693
  throw new Error(`npm pack ${spec} did not return a tarball name`);
6312
6694
  }
6313
- const unpackDir = path11.join(tempRoot, "unpacked");
6314
- fs7.mkdirSync(unpackDir, { recursive: true });
6315
- childProcess2.execFileSync("tar", ["-xzf", path11.join(tempRoot, tarballName), "-C", unpackDir], {
6695
+ const unpackDir = path12.join(tempRoot, "unpacked");
6696
+ fs9.mkdirSync(unpackDir, { recursive: true });
6697
+ childProcess2.execFileSync("tar", ["-xzf", path12.join(tempRoot, tarballName), "-C", unpackDir], {
6316
6698
  stdio: ["ignore", "pipe", "pipe"]
6317
6699
  });
6318
- const packagedDir = path11.join(unpackDir, "package");
6319
- if (!fs7.existsSync(packagedDir)) {
6700
+ const packagedDir = path12.join(unpackDir, "package");
6701
+ if (!fs9.existsSync(packagedDir)) {
6320
6702
  throw new Error(`npm pack ${spec} did not contain a package/ directory`);
6321
6703
  }
6322
- fs7.rmSync(stagedDir, { recursive: true, force: true });
6323
- fs7.cpSync(packagedDir, stagedDir, { recursive: true });
6704
+ fs9.rmSync(stagedDir, { recursive: true, force: true });
6705
+ fs9.cpSync(packagedDir, stagedDir, { recursive: true });
6324
6706
  childProcess2.execFileSync("npm", ["install", "--omit=dev"], {
6325
6707
  cwd: stagedDir,
6326
6708
  stdio: ["ignore", "pipe", "pipe"]
@@ -6335,8 +6717,8 @@ function installPublishedOpenclawPlugin(spec, pluginDir) {
6335
6717
  }
6336
6718
  })();
6337
6719
  swapRollbackDir = swapResult.rollbackDir;
6338
- const installedPackageJsonPath = path11.join(pluginDir, "package.json");
6339
- const installedPackage = fs7.existsSync(installedPackageJsonPath) ? JSON.parse(fs7.readFileSync(installedPackageJsonPath, "utf8")) : {};
6720
+ const installedPackageJsonPath = path12.join(pluginDir, "package.json");
6721
+ const installedPackage = fs9.existsSync(installedPackageJsonPath) ? JSON.parse(fs9.readFileSync(installedPackageJsonPath, "utf8")) : {};
6340
6722
  return {
6341
6723
  rollbackDir: swapRollbackDir,
6342
6724
  version: typeof installedPackage.version === "string" ? installedPackage.version : void 0
@@ -6351,8 +6733,8 @@ function installPublishedOpenclawPlugin(spec, pluginDir) {
6351
6733
  }
6352
6734
  );
6353
6735
  } finally {
6354
- fs7.rmSync(stagedDir, { recursive: true, force: true });
6355
- fs7.rmSync(tempRoot, { recursive: true, force: true });
6736
+ fs9.rmSync(stagedDir, { recursive: true, force: true });
6737
+ fs9.rmSync(tempRoot, { recursive: true, force: true });
6356
6738
  }
6357
6739
  }
6358
6740
  function restartOpenclawGateway() {
@@ -6370,15 +6752,15 @@ function restartOpenclawGateway() {
6370
6752
  });
6371
6753
  }
6372
6754
  function cmdInit() {
6373
- const configPath = path11.join(process.cwd(), "remnic.config.json");
6374
- if (fs7.existsSync(configPath)) {
6755
+ const configPath = path12.join(process.cwd(), "remnic.config.json");
6756
+ if (fs9.existsSync(configPath)) {
6375
6757
  console.log(`Config already exists: ${configPath}`);
6376
6758
  return;
6377
6759
  }
6378
6760
  const template = {
6379
6761
  remnic: {
6380
6762
  openaiApiKey: "${OPENAI_API_KEY}",
6381
- memoryDir: path11.join(process.cwd(), ".remnic", "memory"),
6763
+ memoryDir: path12.join(process.cwd(), ".remnic", "memory"),
6382
6764
  memoryOsPreset: "balanced"
6383
6765
  },
6384
6766
  server: {
@@ -6387,7 +6769,7 @@ function cmdInit() {
6387
6769
  authToken: "${REMNIC_AUTH_TOKEN}"
6388
6770
  }
6389
6771
  };
6390
- fs7.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
6772
+ fs9.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
6391
6773
  console.log(`Created ${configPath}`);
6392
6774
  console.log("\nSet these environment variables:");
6393
6775
  console.log(" export OPENAI_API_KEY=sk-...");
@@ -6396,6 +6778,18 @@ function cmdInit() {
6396
6778
  console.log("\nThen start the server:");
6397
6779
  console.log(" npx --package @remnic/server remnic-server");
6398
6780
  }
6781
+ function resolveStatusProbeToken() {
6782
+ const operatorToken = oauthResolveOperatorToken();
6783
+ if (operatorToken) return operatorToken;
6784
+ try {
6785
+ const usable = listTokens().find(
6786
+ (t) => t.connector !== "chatgpt" && typeof t.token === "string" && t.token.length > 0
6787
+ );
6788
+ if (usable) return usable.token;
6789
+ } catch {
6790
+ }
6791
+ }
6792
+ var __statusHealthTestHooks = { resolveStatusProbeToken };
6399
6793
  async function cmdStatus(json) {
6400
6794
  const { running, pid } = isServiceRunning();
6401
6795
  if (json) {
@@ -6408,18 +6802,34 @@ async function cmdStatus(json) {
6408
6802
  }
6409
6803
  console.log(`Remnic server: running${pid ? ` (pid ${pid})` : ""}`);
6410
6804
  const port = inferPort();
6805
+ const probeToken = resolveStatusProbeToken();
6411
6806
  const controller = new AbortController();
6412
6807
  const timeoutId = setTimeout(() => controller.abort(), 3e3);
6413
6808
  try {
6414
6809
  const response = await fetch(`http://127.0.0.1:${port}/engram/v1/health`, {
6415
- signal: controller.signal
6810
+ signal: controller.signal,
6811
+ ...probeToken ? { headers: { Authorization: `Bearer ${probeToken}` } } : {}
6416
6812
  });
6417
6813
  if (!response.ok) {
6418
- console.log(`Health: server responded with ${response.status} ${response.statusText}`);
6814
+ const hint = response.status === 401 && !probeToken ? " (daemon requires auth and no local token was found \u2014 set REMNIC_AUTH_TOKEN, configure server.authToken, or run 'remnic token generate')" : response.status === 401 ? " (local token rejected by the daemon)" : "";
6815
+ console.log(`Health: server responded with ${response.status} ${response.statusText}${hint}`);
6419
6816
  } else {
6420
6817
  const health = await response.json();
6421
6818
  const status = typeof health.status === "string" ? health.status : "ok";
6422
6819
  console.log(`Health: ${status}`);
6820
+ const qmd = health.qmd;
6821
+ if (qmd?.pendingEmbeddings != null) {
6822
+ console.log(` Pending embeddings: ${qmd.pendingEmbeddings}`);
6823
+ if (qmd.oldestPendingAgeMs != null) {
6824
+ console.log(` Oldest pending: ${Math.round(qmd.oldestPendingAgeMs / 6e4)}m`);
6825
+ }
6826
+ if (qmd.embeddingBacklogThreshold != null) {
6827
+ console.log(` Backlog threshold: ${qmd.embeddingBacklogThreshold}`);
6828
+ }
6829
+ }
6830
+ if (qmd?.degradedReason) {
6831
+ console.log(` Degraded: ${qmd.degradedReason}`);
6832
+ }
6423
6833
  }
6424
6834
  } catch {
6425
6835
  console.log("Health: unable to reach server");
@@ -6429,7 +6839,7 @@ async function cmdStatus(json) {
6429
6839
  }
6430
6840
  function oauthReadConfigRecord(configPath) {
6431
6841
  try {
6432
- const parsed = JSON.parse(fs7.readFileSync(configPath, "utf8"));
6842
+ const parsed = JSON.parse(fs9.readFileSync(configPath, "utf8"));
6433
6843
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
6434
6844
  return parsed;
6435
6845
  }
@@ -6480,14 +6890,14 @@ function oauthResolveOperatorToken() {
6480
6890
  const server = raw.server;
6481
6891
  if (server && typeof server === "object" && "authToken" in server) {
6482
6892
  const candidate = server.authToken;
6483
- if (typeof candidate === "string" && candidate.length > 0) {
6893
+ if (typeof candidate === "string" && candidate.length > 0 && !candidate.includes("${")) {
6484
6894
  return candidate;
6485
6895
  }
6486
6896
  }
6487
6897
  }
6488
6898
  return void 0;
6489
6899
  }
6490
- async function oauthFetch(method, path12, token, body) {
6900
+ async function oauthFetch(method, path13, token, body) {
6491
6901
  const controller = new AbortController();
6492
6902
  const timeoutId = setTimeout(() => controller.abort(), 5e3);
6493
6903
  try {
@@ -6506,7 +6916,7 @@ async function oauthFetch(method, path12, token, body) {
6506
6916
  if (body !== void 0) {
6507
6917
  init.body = JSON.stringify(body);
6508
6918
  }
6509
- const response = await fetch(`${oauthResolveBaseUrl()}${path12}`, init);
6919
+ const response = await fetch(`${oauthResolveBaseUrl()}${path13}`, init);
6510
6920
  if (response.status === 401) {
6511
6921
  throw new Error(
6512
6922
  "operator token rejected by remnic-server (HTTP 401). Update `server.authToken` or `REMNIC_AUTH_TOKEN` to match the running daemon."
@@ -6845,9 +7255,9 @@ async function cmdQuery(queryText, json, explain) {
6845
7255
  }
6846
7256
  initLogger();
6847
7257
  const configPath = resolveConfigPath();
6848
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
6849
- const remnicCfg = resolveRemnicConfigRecord(raw);
6850
- const config = parseConfig(remnicCfg);
7258
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7259
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7260
+ const config = parseConfig2(remnicCfg);
6851
7261
  const orchestrator = new Orchestrator(config);
6852
7262
  await orchestrator.initialize();
6853
7263
  const service = new EngramAccessService(orchestrator);
@@ -7016,9 +7426,9 @@ async function cmdXray(rest) {
7016
7426
  parseXrayCliOptions(rawQuery, options);
7017
7427
  initLogger();
7018
7428
  const configPath = resolveConfigPath();
7019
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7020
- const remnicCfg = resolveRemnicConfigRecord(raw);
7021
- const config = parseConfig(remnicCfg);
7429
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7430
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7431
+ const config = parseConfig2(remnicCfg);
7022
7432
  const orchestrator = new Orchestrator(config);
7023
7433
  await orchestrator.initialize();
7024
7434
  await orchestrator.deferredReady;
@@ -7039,9 +7449,9 @@ async function cmdXray(rest) {
7039
7449
  async function cmdVersions(rest) {
7040
7450
  initLogger();
7041
7451
  const configPath = resolveConfigPath();
7042
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7043
- const remnicCfg = resolveRemnicConfigRecord(raw);
7044
- const config = parseConfig(remnicCfg);
7452
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7453
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7454
+ const config = parseConfig2(remnicCfg);
7045
7455
  if (!config.versioningEnabled) {
7046
7456
  console.error("Page versioning is disabled (versioningEnabled = false).");
7047
7457
  process.exit(1);
@@ -7061,7 +7471,7 @@ async function cmdVersions(rest) {
7061
7471
  console.error("Usage: remnic versions list <page-path>");
7062
7472
  process.exit(1);
7063
7473
  }
7064
- const absPath = path11.resolve(pagePath);
7474
+ const absPath = path12.resolve(pagePath);
7065
7475
  const history = await listVersions(absPath, versioningConfig, memDir);
7066
7476
  if (json) {
7067
7477
  console.log(JSON.stringify(history, null, 2));
@@ -7086,7 +7496,7 @@ async function cmdVersions(rest) {
7086
7496
  console.error("Usage: remnic versions show <page-path> <version-id>");
7087
7497
  process.exit(1);
7088
7498
  }
7089
- const absPath = path11.resolve(pagePath);
7499
+ const absPath = path12.resolve(pagePath);
7090
7500
  try {
7091
7501
  const content = await getVersion(absPath, versionId, versioningConfig, memDir);
7092
7502
  console.log(content);
@@ -7104,7 +7514,7 @@ async function cmdVersions(rest) {
7104
7514
  console.error("Usage: remnic versions diff <page-path> <v1> <v2>");
7105
7515
  process.exit(1);
7106
7516
  }
7107
- const absPath = path11.resolve(pagePath);
7517
+ const absPath = path12.resolve(pagePath);
7108
7518
  try {
7109
7519
  const diffOutput = await diffVersions(absPath, v1, v2, versioningConfig, memDir);
7110
7520
  console.log(diffOutput);
@@ -7121,7 +7531,7 @@ async function cmdVersions(rest) {
7121
7531
  console.error("Usage: remnic versions revert <page-path> <version-id>");
7122
7532
  process.exit(1);
7123
7533
  }
7124
- const absPath = path11.resolve(pagePath);
7534
+ const absPath = path12.resolve(pagePath);
7125
7535
  try {
7126
7536
  const version = await revertToVersion(absPath, versionId, versioningConfig, void 0, memDir);
7127
7537
  if (json) {
@@ -7155,13 +7565,13 @@ Options:
7155
7565
  async function cmdEnrich(rest) {
7156
7566
  initLogger();
7157
7567
  const configPath = resolveConfigPath();
7158
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7159
- const remnicCfg = resolveRemnicConfigRecord(raw);
7160
- const config = parseConfig(remnicCfg);
7568
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7569
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7570
+ const config = parseConfig2(remnicCfg);
7161
7571
  const subcommand = rest[0];
7162
7572
  if (subcommand === "audit") {
7163
7573
  const memoryDir2 = expandTilde(config.memoryDir);
7164
- const auditDir2 = path11.join(memoryDir2, "enrichment");
7574
+ const auditDir2 = path12.join(memoryDir2, "enrichment");
7165
7575
  const sinceFlag = resolveFlag(rest.slice(1), "--since");
7166
7576
  const entries = await readAuditLog(auditDir2, sinceFlag ?? void 0);
7167
7577
  if (entries.length === 0) {
@@ -7286,18 +7696,13 @@ Registered providers:`);
7286
7696
  return;
7287
7697
  }
7288
7698
  const memoryDir = expandTilde(config.memoryDir);
7289
- const auditDir = path11.join(memoryDir, "enrichment");
7699
+ const auditDir = path12.join(memoryDir, "enrichment");
7290
7700
  let totalPersisted = 0;
7291
7701
  for (const result of results) {
7292
7702
  for (const candidate of result.acceptedCandidates) {
7293
7703
  let persisted = false;
7294
7704
  try {
7295
- await storage.writeMemory(candidate.category, candidate.text, {
7296
- confidence: candidate.confidence,
7297
- tags: [...candidate.tags ?? [], "enrichment", candidate.source],
7298
- entityRef: result.entityName,
7299
- source: `enrichment:${candidate.source}`
7300
- });
7705
+ await persistEnrichmentCandidate(storage, result.entityName, candidate);
7301
7706
  persisted = true;
7302
7707
  totalPersisted++;
7303
7708
  } catch (err) {
@@ -7405,13 +7810,13 @@ Shared with:
7405
7810
  process.exit(1);
7406
7811
  }
7407
7812
  const configPath = resolveConfigPath();
7408
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7409
- const remnicCfg = resolveRemnicConfigRecord(raw);
7410
- const config = parseConfig(remnicCfg);
7813
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7814
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7815
+ const config = parseConfig2(remnicCfg);
7411
7816
  const memoryDir = expandTilde(
7412
7817
  typeof memoryDirOverride === "string" && memoryDirOverride.length > 0 ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
7413
7818
  );
7414
- const storage = new StorageManager(memoryDir);
7819
+ const storage = new StorageManager2(memoryDir);
7415
7820
  const report = await computeProcedureStats({ storage, config });
7416
7821
  if (format === "json") {
7417
7822
  process.stdout.write(JSON.stringify(report, null, 2) + "\n");
@@ -7422,9 +7827,9 @@ Shared with:
7422
7827
  async function cmdExtensions(action, rest) {
7423
7828
  initLogger();
7424
7829
  const configPath = resolveConfigPath();
7425
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7426
- const remnicCfg = resolveRemnicConfigRecord(raw);
7427
- const config = parseConfig(remnicCfg);
7830
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7831
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7832
+ const config = parseConfig2(remnicCfg);
7428
7833
  const root = resolveExtensionsRoot(config);
7429
7834
  const noopLog = { warn: () => {
7430
7835
  }, debug: () => {
@@ -7473,7 +7878,7 @@ Root: ${root}`);
7473
7878
  const extensions = await discoverMemoryExtensions(root, warnLog);
7474
7879
  let entries = [];
7475
7880
  try {
7476
- entries = fs7.readdirSync(root);
7881
+ entries = fs9.readdirSync(root);
7477
7882
  } catch {
7478
7883
  console.log(`Extensions root does not exist: ${root}`);
7479
7884
  process.exitCode = 0;
@@ -7482,9 +7887,9 @@ Root: ${root}`);
7482
7887
  const validNames = new Set(extensions.map((e) => e.name));
7483
7888
  let errors = 0;
7484
7889
  for (const entry of entries) {
7485
- const entryPath = path11.join(root, entry);
7890
+ const entryPath = path12.join(root, entry);
7486
7891
  try {
7487
- if (!fs7.statSync(entryPath).isDirectory()) continue;
7892
+ if (!fs9.statSync(entryPath).isDirectory()) continue;
7488
7893
  } catch {
7489
7894
  continue;
7490
7895
  }
@@ -7516,9 +7921,9 @@ Root: ${root}`);
7516
7921
  async function cmdBriefing(rest) {
7517
7922
  initLogger();
7518
7923
  const configPath = resolveConfigPath();
7519
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7520
- const remnicCfg = resolveRemnicConfigRecord(raw);
7521
- const config = parseConfig(remnicCfg);
7924
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
7925
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7926
+ const config = parseConfig2(remnicCfg);
7522
7927
  if (!config.briefing.enabled) {
7523
7928
  console.error("Briefing is disabled in config (briefing.enabled = false).");
7524
7929
  process.exit(1);
@@ -7596,10 +8001,10 @@ async function cmdBriefing(rest) {
7596
8001
  if (save) {
7597
8002
  try {
7598
8003
  const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
7599
- fs7.mkdirSync(saveDir, { recursive: true });
8004
+ fs9.mkdirSync(saveDir, { recursive: true });
7600
8005
  const filename = briefingFilename(new Date(result.window.to), format);
7601
- const filePath = path11.join(saveDir, filename);
7602
- fs7.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
8006
+ const filePath = path12.join(saveDir, filename);
8007
+ fs9.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
7603
8008
  console.error(`Saved briefing: ${filePath}`);
7604
8009
  } catch (err) {
7605
8010
  console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
@@ -7617,17 +8022,19 @@ async function cmdDoctor() {
7617
8022
  detail: `${nodeVersion} (requires >= 22.12.0)`
7618
8023
  });
7619
8024
  const configPath = resolveConfigPath();
7620
- const configExists = fs7.existsSync(configPath);
8025
+ const configExists = fs9.existsSync(configPath);
7621
8026
  checks.push({ name: "Config file", ok: configExists, detail: configPath });
7622
8027
  let standaloneConfig;
7623
8028
  let standaloneConfigError;
7624
8029
  let standaloneOpenaiApiKeyExplicitlyFalse = false;
8030
+ let configuredNs = { invalid: false };
7625
8031
  if (configExists) {
7626
8032
  try {
7627
- const raw = JSON.parse(fs7.readFileSync(configPath, "utf8"));
7628
- const remnicCfg = resolveRemnicConfigRecord(raw);
8033
+ const raw = JSON.parse(fs9.readFileSync(configPath, "utf8"));
8034
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
7629
8035
  standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
7630
- standaloneConfig = parseConfig(remnicCfg);
8036
+ configuredNs = readConfiguredNamespace(remnicCfg);
8037
+ standaloneConfig = parseConfig2(remnicCfg);
7631
8038
  } catch (err) {
7632
8039
  standaloneConfigError = err instanceof Error ? err.message : String(err);
7633
8040
  }
@@ -7636,16 +8043,39 @@ async function cmdDoctor() {
7636
8043
  try {
7637
8044
  memoryDir = resolveMemoryDir();
7638
8045
  } catch {
7639
- memoryDir = parseConfig({}).memoryDir;
8046
+ memoryDir = parseConfig2({}).memoryDir;
7640
8047
  }
7641
8048
  try {
7642
- fs7.mkdirSync(memoryDir, { recursive: true });
8049
+ fs9.mkdirSync(memoryDir, { recursive: true });
7643
8050
  checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
7644
8051
  } catch {
7645
8052
  checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
7646
8053
  }
8054
+ try {
8055
+ const quarantined = await new WriteQuarantineStore(memoryDir).count();
8056
+ checks.push({
8057
+ name: "Quarantined writes",
8058
+ ok: quarantined === 0,
8059
+ warn: quarantined > 0,
8060
+ detail: quarantined === 0 ? "none" : `${quarantined} parked`,
8061
+ remediation: quarantined > 0 ? "Inspect with `remnic quarantine list`, then fix the client's namespace config so writes are stored instead of parked." : void 0
8062
+ });
8063
+ } catch {
8064
+ checks.push({
8065
+ name: "Quarantined writes",
8066
+ ok: false,
8067
+ warn: true,
8068
+ detail: "unable to inspect quarantine store"
8069
+ });
8070
+ }
8071
+ const nsPolicyCheck = buildNamespacePolicyCheck({
8072
+ invalid: configuredNs.invalid,
8073
+ configuredNamespace: configuredNs.configuredNamespace,
8074
+ config: standaloneConfig
8075
+ });
8076
+ if (nsPolicyCheck) checks.push(nsPolicyCheck);
7647
8077
  const openclawConfigPath = resolveOpenclawConfigPath();
7648
- const openclawConfigExists = fs7.existsSync(openclawConfigPath);
8078
+ const openclawConfigExists = fs9.existsSync(openclawConfigPath);
7649
8079
  let openclawConfig = {};
7650
8080
  let openclawConfigValid = false;
7651
8081
  let openclawPluginModeConfigured = false;
@@ -7653,7 +8083,7 @@ async function cmdDoctor() {
7653
8083
  let activeOpenclawEntryConfig = null;
7654
8084
  if (openclawConfigExists) {
7655
8085
  try {
7656
- const parsed = JSON.parse(fs7.readFileSync(openclawConfigPath, "utf-8"));
8086
+ const parsed = JSON.parse(fs9.readFileSync(openclawConfigPath, "utf-8"));
7657
8087
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
7658
8088
  openclawConfig = parsed;
7659
8089
  openclawConfigValid = true;
@@ -7729,13 +8159,13 @@ async function cmdDoctor() {
7729
8159
  const rawMemoryDir = entryConfig?.memoryDir;
7730
8160
  const configuredMemoryDir = typeof rawMemoryDir === "string" ? rawMemoryDir : void 0;
7731
8161
  if (configuredMemoryDir) {
7732
- const resolvedMemDir = path11.resolve(expandTilde(configuredMemoryDir));
8162
+ const resolvedMemDir = path12.resolve(expandTilde(configuredMemoryDir));
7733
8163
  let memDirOk = false;
7734
8164
  let memDirDetail = `${resolvedMemDir} (not found)`;
7735
8165
  let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
7736
- if (fs7.existsSync(resolvedMemDir)) {
8166
+ if (fs9.existsSync(resolvedMemDir)) {
7737
8167
  try {
7738
- const stat = fs7.statSync(resolvedMemDir);
8168
+ const stat = fs9.statSync(resolvedMemDir);
7739
8169
  if (stat.isDirectory()) {
7740
8170
  memDirOk = true;
7741
8171
  memDirDetail = resolvedMemDir;
@@ -7877,12 +8307,12 @@ async function cmdDoctor() {
7877
8307
  }
7878
8308
  function cmdConfig() {
7879
8309
  const configPath = resolveConfigPath();
7880
- if (!fs7.existsSync(configPath)) {
8310
+ if (!fs9.existsSync(configPath)) {
7881
8311
  console.log("No config file found. Run `remnic init` to create one.");
7882
8312
  return;
7883
8313
  }
7884
8314
  console.log(`Config: ${configPath}`);
7885
- const rawConfig = fs7.readFileSync(configPath, "utf8");
8315
+ const rawConfig = fs9.readFileSync(configPath, "utf8");
7886
8316
  const redacted = rawConfig.replace(
7887
8317
  /("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
7888
8318
  "$1[REDACTED]$3"
@@ -7929,7 +8359,7 @@ async function cmdMigrate(json, rollback) {
7929
8359
  console.log(` Rollback: ${result.rollbackCommand}`);
7930
8360
  }
7931
8361
  function cmdOnboard(dirPath, json) {
7932
- const directory = path11.resolve(dirPath || process.cwd());
8362
+ const directory = path12.resolve(dirPath || process.cwd());
7933
8363
  const result = onboard({ directory });
7934
8364
  if (json) {
7935
8365
  console.log(JSON.stringify(result, null, 2));
@@ -7948,7 +8378,7 @@ Suggested namespace: ${result.plan.suggestedNamespace}`);
7948
8378
  async function cmdCurate(targetPath, json) {
7949
8379
  const memoryDir = resolveMemoryDir();
7950
8380
  const result = await curate({
7951
- targetPath: path11.resolve(targetPath),
8381
+ targetPath: path12.resolve(targetPath),
7952
8382
  memoryDir,
7953
8383
  source: "curation",
7954
8384
  checkDuplicates: true,
@@ -7986,13 +8416,13 @@ async function cmdReview(action, rest) {
7986
8416
  console.error("Usage: remnic review <approve|dismiss|flag> <id>");
7987
8417
  process.exit(1);
7988
8418
  }
7989
- const storage = new StorageManager(memoryDir);
8419
+ const storage = new StorageManager2(memoryDir);
7990
8420
  const configPath = resolveConfigPath();
7991
8421
  let tombstonesConfig = null;
7992
8422
  try {
7993
- const rawCfg = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
7994
- const remnicCfg = resolveRemnicConfigRecord(rawCfg);
7995
- const config = parseConfig(remnicCfg);
8423
+ const rawCfg = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
8424
+ const remnicCfg = resolveRemnicConfigRecord2(rawCfg);
8425
+ const config = parseConfig2(remnicCfg);
7996
8426
  tombstonesConfig = {
7997
8427
  enabled: config.tombstonesEnabled,
7998
8428
  semanticMatch: config.tombstonesSemanticMatch,
@@ -8078,7 +8508,7 @@ async function cmdSync(action, rest, json) {
8078
8508
  }
8079
8509
  function localOfflineSourceId(memoryDir) {
8080
8510
  const host = os.hostname() || "unknown-host";
8081
- const dirHash = createHash("sha256").update(path11.resolve(memoryDir)).digest("hex").slice(0, 16);
8511
+ const dirHash = createHash2("sha256").update(path12.resolve(memoryDir)).digest("hex").slice(0, 16);
8082
8512
  return `remnic-local:${host}:${dirHash}`;
8083
8513
  }
8084
8514
  function normalizeOfflineRemoteUrl(raw) {
@@ -8476,10 +8906,10 @@ var OFFLINE_SYNC_CONTENT_MISSING_RETRY_MAX = 3;
8476
8906
  var OFFLINE_SYNC_CONTENT_MISSING_RETRY_DELAY_MS = 250;
8477
8907
  var OfflineRemoteFileChangedError = class extends Error {
8478
8908
  path;
8479
- constructor(path12) {
8480
- super(`remote file changed while fetching offline content: ${path12}`);
8909
+ constructor(path13) {
8910
+ super(`remote file changed while fetching offline content: ${path13}`);
8481
8911
  this.name = "OfflineRemoteFileChangedError";
8482
- this.path = path12;
8912
+ this.path = path13;
8483
8913
  }
8484
8914
  };
8485
8915
  function isOfflineRemoteFileChangedError(error) {
@@ -8670,15 +9100,15 @@ function offlineDirectPushFiles(options) {
8670
9100
  }).sort((left, right) => right.bytes - left.bytes || left.path.localeCompare(right.path));
8671
9101
  }
8672
9102
  function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
8673
- const base = path11.resolve(memoryDir);
8674
- const target = path11.resolve(base, relPath);
8675
- const relative = path11.relative(base, target);
8676
- if (relative === "" || relative === ".." || relative.startsWith(`..${path11.sep}`) || path11.isAbsolute(relative)) {
9103
+ const base = path12.resolve(memoryDir);
9104
+ const target = path12.resolve(base, relPath);
9105
+ const relative = path12.relative(base, target);
9106
+ if (relative === "" || relative === ".." || relative.startsWith(`..${path12.sep}`) || path12.isAbsolute(relative)) {
8677
9107
  throw new Error(`offline sync direct hydration path escapes memory dir: ${relPath}`);
8678
9108
  }
8679
9109
  return target;
8680
9110
  }
8681
- var OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES = OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES;
9111
+ var OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES = OFFLINE_SYNC_FILE_CONTENT_TRANSFER_CHUNK_BYTES2;
8682
9112
  async function pushOfflineFileContent(args) {
8683
9113
  if (args.readFileChunks) {
8684
9114
  return pushOfflineFileContentFromChunkReader(args);
@@ -8686,7 +9116,7 @@ async function pushOfflineFileContent(args) {
8686
9116
  let offset = 0;
8687
9117
  let finalResult = null;
8688
9118
  let remoteSatisfiedResult = null;
8689
- const hash = createHash("sha256");
9119
+ const hash = createHash2("sha256");
8690
9120
  let bytes = 0;
8691
9121
  while (offset < args.file.bytes || args.file.bytes === 0 && offset === 0) {
8692
9122
  const chunk = await readOfflineSyncFileContentChunk({
@@ -8743,13 +9173,13 @@ async function pushOfflineFileContent(args) {
8743
9173
  }
8744
9174
  async function pushOfflineFileContentFromChunkReader(args) {
8745
9175
  const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
8746
- const stat = fs7.statSync(filePath);
9176
+ const stat = fs9.statSync(filePath);
8747
9177
  if (stat.mtimeMs !== args.file.mtimeMs) {
8748
9178
  throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
8749
9179
  }
8750
- const hash = createHash("sha256");
9180
+ const hash = createHash2("sha256");
8751
9181
  const chunks = args.readFileChunks({
8752
- root: path11.resolve(args.memoryDir),
9182
+ root: path12.resolve(args.memoryDir),
8753
9183
  path: args.file.path,
8754
9184
  filePath,
8755
9185
  chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
@@ -9187,147 +9617,6 @@ function waitForOfflineInterval(ms, setCancel) {
9187
9617
  });
9188
9618
  });
9189
9619
  }
9190
- async function createOfflineStorageIo(memoryDir) {
9191
- const storage = new StorageManager(memoryDir);
9192
- const header = await readHeader(memoryDir);
9193
- let secureStoreKey = null;
9194
- if (header) {
9195
- storage.setSecureStoreRequired(true);
9196
- const key = keyring.getKey(secureStoreDir(memoryDir));
9197
- if (key) {
9198
- storage.setSecureStoreKey(key);
9199
- secureStoreKey = key;
9200
- }
9201
- }
9202
- return {
9203
- readFile: async ({ filePath }) => storage.readOfflineSyncFile(filePath),
9204
- readFileDigest: async ({ filePath }) => {
9205
- const hash = createHash("sha256");
9206
- let bytes = 0;
9207
- for await (const rawChunk of readOfflineSyncFileChunks({
9208
- filePath,
9209
- memoryDir,
9210
- secureStoreKey,
9211
- chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
9212
- })) {
9213
- const chunk = Buffer.isBuffer(rawChunk) ? rawChunk : Buffer.from(rawChunk);
9214
- hash.update(chunk);
9215
- bytes += chunk.length;
9216
- }
9217
- return {
9218
- sha256: hash.digest("hex"),
9219
- bytes
9220
- };
9221
- },
9222
- readFileChunks: ({ filePath, chunkSize }) => readOfflineSyncFileChunks({
9223
- filePath,
9224
- memoryDir,
9225
- secureStoreKey,
9226
- chunkSize
9227
- }),
9228
- writeFile: async ({ filePath, content }) => storage.writeOfflineSyncFile(filePath, content),
9229
- writeStagingFile: async ({ filePath, content }) => storage.writeOfflineSyncStagingFile(filePath, content),
9230
- writeFileChunks: async ({ filePath, chunks }) => storage.writeOfflineSyncFileChunks(filePath, chunks),
9231
- deleteFile: async ({ filePath }) => storage.deleteOfflineSyncFile(filePath)
9232
- };
9233
- }
9234
- async function* readOfflineSyncFileChunks(options) {
9235
- const header = await readFilePrefix(options.filePath, MAGIC_HEADER_SIZE);
9236
- if (!isEncryptedFile(header)) {
9237
- yield* readPlainOfflineFileChunks(options.filePath, options.chunkSize);
9238
- return;
9239
- }
9240
- if (!options.secureStoreKey) {
9241
- throw new SecureStoreLockedError(
9242
- `secure-store is locked \u2014 cannot read encrypted file at ${options.filePath}. Run \`remnic secure-store unlock\` to decrypt.`
9243
- );
9244
- }
9245
- yield* readEncryptedOfflineFileChunks({
9246
- filePath: options.filePath,
9247
- memoryDir: options.memoryDir,
9248
- key: options.secureStoreKey,
9249
- chunkSize: options.chunkSize
9250
- });
9251
- }
9252
- async function readFilePrefix(filePath, length) {
9253
- const handle = await fs7.promises.open(filePath, "r");
9254
- try {
9255
- const out = Buffer.alloc(length);
9256
- const { bytesRead } = await handle.read(out, 0, length, 0);
9257
- return out.subarray(0, bytesRead);
9258
- } finally {
9259
- await handle.close();
9260
- }
9261
- }
9262
- async function* readPlainOfflineFileChunks(filePath, chunkSize) {
9263
- const stream = fs7.createReadStream(filePath, { highWaterMark: chunkSize });
9264
- for await (const chunk of stream) {
9265
- yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
9266
- }
9267
- }
9268
- async function* readEncryptedOfflineFileChunks(options) {
9269
- const header = await readFilePrefix(options.filePath, MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE);
9270
- if (header.length < MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE || !isEncryptedFile(header)) {
9271
- throw new Error(`secure-store encrypted file is truncated: ${options.filePath}`);
9272
- }
9273
- const version = header.readUInt8(MAGIC_BYTES.length);
9274
- const flags = header.readUInt8(MAGIC_BYTES.length + 1);
9275
- if (version !== FILE_FORMAT_VERSION) {
9276
- throw new Error(`secure-store file has unsupported version ${version}: ${options.filePath}`);
9277
- }
9278
- if (flags !== FILE_FORMAT_FLAGS) {
9279
- throw new Error(`secure-store file has unsupported flags 0x${flags.toString(16)}: ${options.filePath}`);
9280
- }
9281
- const envelopeHeader = header.subarray(MAGIC_HEADER_SIZE);
9282
- const envelopeVersion = envelopeHeader.readUInt8(ENVELOPE_LAYOUT.version);
9283
- if (envelopeVersion !== ENVELOPE_VERSION) {
9284
- throw new Error(`secure-store envelope has unsupported version ${envelopeVersion}: ${options.filePath}`);
9285
- }
9286
- const salt = envelopeHeader.subarray(
9287
- ENVELOPE_LAYOUT.salt,
9288
- ENVELOPE_LAYOUT.salt + ENVELOPE_SALT_LENGTH
9289
- );
9290
- const iv = envelopeHeader.subarray(ENVELOPE_LAYOUT.iv, ENVELOPE_LAYOUT.iv + IV_LENGTH);
9291
- const authTag = envelopeHeader.subarray(
9292
- ENVELOPE_LAYOUT.authTag,
9293
- ENVELOPE_LAYOUT.authTag + AUTH_TAG_LENGTH
9294
- );
9295
- const decipher = createDecipheriv("aes-256-gcm", options.key, iv, {
9296
- authTagLength: AUTH_TAG_LENGTH
9297
- });
9298
- decipher.setAuthTag(authTag);
9299
- decipher.setAAD(Buffer.concat([secureStoreEnvelopeHeaderAad(salt), filePathAad(options.filePath, options.memoryDir)]));
9300
- let pending = Buffer.alloc(0);
9301
- const stream = fs7.createReadStream(options.filePath, {
9302
- start: MAGIC_HEADER_SIZE + ENVELOPE_HEADER_SIZE,
9303
- highWaterMark: options.chunkSize
9304
- });
9305
- for await (const encryptedChunk of stream) {
9306
- const plain = decipher.update(Buffer.isBuffer(encryptedChunk) ? encryptedChunk : Buffer.from(encryptedChunk));
9307
- if (plain.length > 0) {
9308
- pending = Buffer.concat([pending, plain], pending.length + plain.length);
9309
- }
9310
- while (pending.length >= options.chunkSize) {
9311
- yield pending.subarray(0, options.chunkSize);
9312
- pending = pending.subarray(options.chunkSize);
9313
- }
9314
- }
9315
- const finalPlain = decipher.final();
9316
- if (finalPlain.length > 0) {
9317
- pending = Buffer.concat([pending, finalPlain], pending.length + finalPlain.length);
9318
- }
9319
- while (pending.length >= options.chunkSize) {
9320
- yield pending.subarray(0, options.chunkSize);
9321
- pending = pending.subarray(options.chunkSize);
9322
- }
9323
- if (pending.length > 0) yield pending;
9324
- }
9325
- function secureStoreEnvelopeHeaderAad(salt) {
9326
- const out = Buffer.alloc(1 + ENVELOPE_SALT_LENGTH);
9327
- out.writeUInt8(ENVELOPE_VERSION, 0);
9328
- Buffer.from(salt).copy(out, 1);
9329
- return out;
9330
- }
9331
9620
  function formatOfflineLargeFilePushFailureMessage(failures) {
9332
9621
  const paths = failures.slice(0, 5).map((failure) => `${failure.path}: ${failure.error}`).join("; ");
9333
9622
  const suffix = failures.length > 5 ? `; +${failures.length - 5} more` : "";
@@ -9375,7 +9664,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
9375
9664
  return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
9376
9665
  }
9377
9666
  async function runOfflineSyncOnce(options) {
9378
- fs7.mkdirSync(options.memoryDir, { recursive: true });
9667
+ fs9.mkdirSync(options.memoryDir, { recursive: true });
9379
9668
  let activeStatePath = options.statePath;
9380
9669
  let priorState = await readOfflineSyncState(activeStatePath);
9381
9670
  let syncNamespace = options.namespace ?? priorState?.namespace;
@@ -9413,8 +9702,22 @@ async function runOfflineSyncOnce(options) {
9413
9702
  }
9414
9703
  const baseFiles = priorState?.baseFiles ?? [];
9415
9704
  const baseCapturedAt = priorState ? new Date(priorState.lastSyncedAt) : void 0;
9416
- const storageIo = await createOfflineStorageIo(options.memoryDir);
9705
+ const offlineStorage = await createConfiguredOfflineStorage(
9706
+ options.memoryDir,
9707
+ options.secureStoreEncryptOnWrite
9708
+ );
9709
+ const storageIo = await createOfflineStorageIo(options.memoryDir, offlineStorage);
9417
9710
  const localSourceId = localOfflineSourceId(options.memoryDir);
9711
+ await drainOfflineSyncImpressions(options.memoryDir, options);
9712
+ await drainPendingLifecycleForOfflineSync(
9713
+ options.memoryDir,
9714
+ (ledgerPath) => createOfflineStorageForPath(
9715
+ options.memoryDir,
9716
+ ledgerPath,
9717
+ offlineStorage,
9718
+ options.secureStoreEncryptOnWrite ?? true
9719
+ ).drainPendingMemoryLifecycleEventsForSyncAt(ledgerPath)
9720
+ );
9418
9721
  const currentSnapshotForPush = await buildOfflineSyncSnapshotFromBase({
9419
9722
  root: options.memoryDir,
9420
9723
  sourceId: localSourceId,
@@ -9933,7 +10236,7 @@ function advanceOfflineLargeFileFailureCounts(options) {
9933
10236
  }
9934
10237
  return { counts: next, newlySkipped };
9935
10238
  }
9936
- function resolveOfflineSyncUserExcludes(rest) {
10239
+ function resolveOfflineSyncUserExcludes(rest, config) {
9937
10240
  const globs = [];
9938
10241
  for (let i = 0; i < rest.length; i += 1) {
9939
10242
  if (rest[i] !== "--exclude") continue;
@@ -9944,27 +10247,17 @@ function resolveOfflineSyncUserExcludes(rest) {
9944
10247
  globs.push(value.trim());
9945
10248
  i += 1;
9946
10249
  }
9947
- const configPath = resolveConfigPath();
9948
- try {
9949
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
9950
- const remnicCfg = resolveRemnicConfigRecord(raw);
9951
- const configured = remnicCfg.offlineSyncExcludes;
9952
- if (configured !== void 0 && configured !== null) {
9953
- if (!Array.isArray(configured)) {
9954
- throw new Error("offlineSyncExcludes config must be an array of non-empty glob strings");
9955
- }
9956
- for (const entry of configured) {
9957
- if (typeof entry !== "string" || entry.trim().length === 0) {
9958
- throw new Error("offlineSyncExcludes config must contain only non-empty glob strings");
9959
- }
9960
- globs.push(entry.trim());
9961
- }
10250
+ const configured = config.offlineSyncExcludes;
10251
+ if (configured !== void 0 && configured !== null) {
10252
+ if (!Array.isArray(configured)) {
10253
+ throw new Error("offlineSyncExcludes config must be an array of non-empty glob strings");
9962
10254
  }
9963
- } catch (error) {
9964
- if (error instanceof SyntaxError) {
9965
- throw new Error(`cannot read offlineSyncExcludes from ${configPath}: ${error.message}`);
10255
+ for (const entry of configured) {
10256
+ if (typeof entry !== "string" || entry.trim().length === 0) {
10257
+ throw new Error("offlineSyncExcludes config must contain only non-empty glob strings");
10258
+ }
10259
+ globs.push(entry.trim());
9966
10260
  }
9967
- throw error;
9968
10261
  }
9969
10262
  return compileOfflineSyncExcludeGlobs(globs);
9970
10263
  }
@@ -9989,19 +10282,30 @@ Environment fallbacks:
9989
10282
  REMNIC_OFFLINE_REMOTE_URL, REMNIC_OFFLINE_TOKEN, REMNIC_AUTH_TOKEN`);
9990
10283
  return;
9991
10284
  }
9992
- const memoryDir = path11.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
10285
+ const memoryDir = path12.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
9993
10286
  const namespace = resolveRequiredValueFlag(rest, "--namespace");
9994
10287
  const includeTranscripts = !hasFlag(rest, "--no-transcripts");
9995
10288
  const stateOverride = resolveRequiredValueFlag(rest, "--state");
9996
10289
  const statePathExplicit = stateOverride !== void 0;
9997
- const userExcludeRegexps = resolveOfflineSyncUserExcludes(rest);
10290
+ const configPath = resolveConfigPath();
10291
+ let config;
10292
+ try {
10293
+ const rawConfig = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
10294
+ config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
10295
+ } catch {
10296
+ throw new Error(
10297
+ "offline sync: failed to load the Remnic config \u2014 run `remnic doctor` and check the config file for errors"
10298
+ );
10299
+ }
10300
+ const userExcludeRegexps = resolveOfflineSyncUserExcludes(rest, config);
10301
+ const impressionRotation = resolveOfflineImpressionRotation(configPath);
9998
10302
  const needsRemote = action === "prepare" || action === "sync" || action === "watch";
9999
10303
  const remoteUrl = needsRemote ? resolveOfflineRemoteUrl(rest) : resolveOptionalOfflineRemoteUrl(rest);
10000
10304
  const token = needsRemote ? resolveOfflineToken(rest) : void 0;
10001
- const statePath = statePathExplicit ? path11.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
10305
+ const statePath = statePathExplicit ? path12.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
10002
10306
  if (action === "prepare") {
10003
10307
  if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
10004
- fs7.mkdirSync(memoryDir, { recursive: true });
10308
+ fs9.mkdirSync(memoryDir, { recursive: true });
10005
10309
  const remoteSnapshot = await fetchOfflineSnapshot({
10006
10310
  remoteUrl,
10007
10311
  token,
@@ -10027,7 +10331,10 @@ Environment fallbacks:
10027
10331
  statePath: existingState.statePath
10028
10332
  });
10029
10333
  }
10030
- const storageIo = await createOfflineStorageIo(memoryDir);
10334
+ const storageIo = await createOfflineStorageIo(
10335
+ memoryDir,
10336
+ await createConfiguredOfflineStorage(memoryDir, config.secureStoreEncryptOnWrite)
10337
+ );
10031
10338
  const pull = await applyOfflineSyncSnapshot({
10032
10339
  root: memoryDir,
10033
10340
  snapshot: remoteSnapshot,
@@ -10072,7 +10379,9 @@ Environment fallbacks:
10072
10379
  includeTranscripts,
10073
10380
  statePath,
10074
10381
  statePathExplicit,
10075
- userExcludeRegexps
10382
+ userExcludeRegexps,
10383
+ secureStoreEncryptOnWrite: config.secureStoreEncryptOnWrite,
10384
+ ...impressionRotation
10076
10385
  });
10077
10386
  if (json) {
10078
10387
  console.log(JSON.stringify(offlineSyncResultJsonSummary(result), null, 2));
@@ -10094,7 +10403,7 @@ Environment fallbacks:
10094
10403
  return;
10095
10404
  }
10096
10405
  if (action === "status") {
10097
- fs7.mkdirSync(memoryDir, { recursive: true });
10406
+ fs9.mkdirSync(memoryDir, { recursive: true });
10098
10407
  const state = statePath ? await readOfflineSyncState(statePath) : null;
10099
10408
  if (state && remoteUrl && statePath) {
10100
10409
  assertOfflineStateMatches({
@@ -10105,7 +10414,18 @@ Environment fallbacks:
10105
10414
  statePath
10106
10415
  });
10107
10416
  }
10108
- const storageIo = await createOfflineStorageIo(memoryDir);
10417
+ const configuredStorage = await createConfiguredOfflineStorage(memoryDir, config.secureStoreEncryptOnWrite);
10418
+ const storageIo = await createOfflineStorageIo(memoryDir, configuredStorage);
10419
+ await drainOfflineSyncImpressions(memoryDir, impressionRotation);
10420
+ await drainPendingLifecycleForOfflineSync(
10421
+ memoryDir,
10422
+ (ledgerPath) => createOfflineStorageForPath(
10423
+ memoryDir,
10424
+ ledgerPath,
10425
+ configuredStorage,
10426
+ config.secureStoreEncryptOnWrite ?? true
10427
+ ).drainPendingMemoryLifecycleEventsForSyncAt(ledgerPath)
10428
+ );
10109
10429
  const summary = await summarizeOfflineSyncPendingChanges({
10110
10430
  root: memoryDir,
10111
10431
  sourceId: localOfflineSourceId(memoryDir),
@@ -10154,6 +10474,8 @@ Environment fallbacks:
10154
10474
  statePath,
10155
10475
  statePathExplicit,
10156
10476
  userExcludeRegexps,
10477
+ secureStoreEncryptOnWrite: config.secureStoreEncryptOnWrite,
10478
+ ...impressionRotation,
10157
10479
  skipLargeFilePaths: skippedLargeFiles
10158
10480
  });
10159
10481
  const advanced = advanceOfflineLargeFileFailureCounts({
@@ -10161,11 +10483,11 @@ Environment fallbacks:
10161
10483
  failures: result.largeFilePushFailures
10162
10484
  });
10163
10485
  largeFileFailureCounts = advanced.counts;
10164
- for (const path12 of advanced.newlySkipped) {
10165
- if (skippedLargeFiles.has(path12)) continue;
10166
- skippedLargeFiles.add(path12);
10486
+ for (const path13 of advanced.newlySkipped) {
10487
+ if (skippedLargeFiles.has(path13)) continue;
10488
+ skippedLargeFiles.add(path13);
10167
10489
  console.warn(
10168
- `offline sync: permanently skipping ${path12} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
10490
+ `offline sync: permanently skipping ${path13} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
10169
10491
  );
10170
10492
  }
10171
10493
  const pulled = result.pull ? result.pull.upserted + result.pull.deleted : 0;
@@ -10180,11 +10502,11 @@ Environment fallbacks:
10180
10502
  failures: error.failures
10181
10503
  });
10182
10504
  largeFileFailureCounts = advanced.counts;
10183
- for (const path12 of advanced.newlySkipped) {
10184
- if (skippedLargeFiles.has(path12)) continue;
10185
- skippedLargeFiles.add(path12);
10505
+ for (const path13 of advanced.newlySkipped) {
10506
+ if (skippedLargeFiles.has(path13)) continue;
10507
+ skippedLargeFiles.add(path13);
10186
10508
  console.warn(
10187
- `offline sync: permanently skipping ${path12} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
10509
+ `offline sync: permanently skipping ${path13} after ${OFFLINE_LARGE_FILE_SKIP_AFTER_FAILURES} failed large-file pushes for this watcher process (see issue #1786; use --exclude or offlineSyncExcludes to silence permanently)`
10188
10510
  );
10189
10511
  }
10190
10512
  }
@@ -10219,7 +10541,7 @@ function cmdDedup(json) {
10219
10541
  function readInstalledConnectorConfig(configPath, fallback) {
10220
10542
  if (!configPath) return fallback;
10221
10543
  try {
10222
- const parsed = JSON.parse(fs7.readFileSync(configPath, "utf8"));
10544
+ const parsed = JSON.parse(fs9.readFileSync(configPath, "utf8"));
10223
10545
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
10224
10546
  const { token: _token, ...config } = parsed;
10225
10547
  return config;
@@ -10231,6 +10553,29 @@ function snapshotConnectorTokenEntry(connectorId) {
10231
10553
  const entry = listTokens().find((candidate) => candidate.connector === connectorId);
10232
10554
  return entry ? { ...entry } : null;
10233
10555
  }
10556
+ async function cmdQuarantine(action, rest, json) {
10557
+ if (action !== "list") {
10558
+ process.stderr.write(`quarantine: unknown action "${action}". Use: list [--json].
10559
+ `);
10560
+ process.exitCode = 2;
10561
+ return;
10562
+ }
10563
+ const extra = rest.filter((a) => !a.startsWith("--"));
10564
+ if (extra.length > 0) {
10565
+ process.stderr.write(`quarantine list: unexpected argument(s): ${extra.join(", ")}. Use: list [--json].
10566
+ `);
10567
+ process.exitCode = 2;
10568
+ return;
10569
+ }
10570
+ const format = json ? "json" : "text";
10571
+ try {
10572
+ const store = new WriteQuarantineStore(resolveMemoryDir());
10573
+ console.log(renderQuarantineList(await store.list(), format));
10574
+ } catch {
10575
+ process.stderr.write("quarantine list: unable to inspect quarantine store\n");
10576
+ process.exitCode = 2;
10577
+ }
10578
+ }
10234
10579
  async function cmdConnectors(action, rest, json) {
10235
10580
  const rawNonFlagArgs = rest.filter((a) => !a.startsWith("--"));
10236
10581
  const resolveConfigStrippedNonFlagArgs = () => {
@@ -10298,7 +10643,7 @@ async function cmdConnectors(action, rest, json) {
10298
10643
  const connectorDaemonUrl = typeof effectiveConnectorConfig.remnicDaemonUrl === "string" && effectiveConnectorConfig.remnicDaemonUrl.trim().length > 0 ? effectiveConnectorConfig.remnicDaemonUrl.trim() : void 0;
10299
10644
  const pubResult = await pub.publish({
10300
10645
  config: { memoryDir, namespace: connectorNamespace, daemonUrl: connectorDaemonUrl },
10301
- skillsRoot: path11.join(memoryDir, "skills"),
10646
+ skillsRoot: path12.join(memoryDir, "skills"),
10302
10647
  rollbackTokenEntry: preInstallTokenEntry,
10303
10648
  log: { info: console.log, warn: console.warn, error: console.error }
10304
10649
  });
@@ -10370,7 +10715,7 @@ async function cmdConnectors(action, rest, json) {
10370
10715
  const pub = factory();
10371
10716
  const available = await pub.isHostAvailable();
10372
10717
  const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
10373
- const extensionExists = available && extRoot ? fs7.existsSync(extRoot) : false;
10718
+ const extensionExists = available && extRoot ? fs9.existsSync(extRoot) : false;
10374
10719
  publisherChecks.push({
10375
10720
  name: `Publisher: ${targetHostId}`,
10376
10721
  ok: !available || extensionExists,
@@ -10441,17 +10786,30 @@ async function cmdConnectors(action, rest, json) {
10441
10786
  const memoryDir = resolveMemoryDir();
10442
10787
  const states = await listLiveConnectorStates(memoryDir);
10443
10788
  const stateMap = new Map(states.map((s) => [s.id, s]));
10789
+ let connectorsCfg;
10790
+ const configPath = resolveConfigPath();
10791
+ try {
10792
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
10793
+ connectorsCfg = parseConfigQuietly(raw).connectors;
10794
+ } catch {
10795
+ process.stderr.write(
10796
+ `connectors status: failed to read config at ${configPath}
10797
+ `
10798
+ );
10799
+ process.exitCode = 2;
10800
+ return;
10801
+ }
10444
10802
  const rows = [
10445
10803
  {
10446
10804
  id: GDRIVE_ID,
10447
10805
  displayName: "Google Drive",
10448
- enabled: true,
10806
+ enabled: connectorsCfg.googleDrive.enabled,
10449
10807
  state: stateMap.get(GDRIVE_ID) ?? null
10450
10808
  },
10451
10809
  {
10452
10810
  id: NOTION_ID,
10453
10811
  displayName: "Notion",
10454
- enabled: true,
10812
+ enabled: connectorsCfg.notion.enabled,
10455
10813
  state: stateMap.get(NOTION_ID) ?? null
10456
10814
  }
10457
10815
  ];
@@ -10507,9 +10865,9 @@ async function cmdConnectors(action, rest, json) {
10507
10865
  }
10508
10866
  initLogger();
10509
10867
  const configPath = resolveConfigPath();
10510
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
10511
- const remnicCfg = resolveRemnicConfigRecord(raw);
10512
- const config = parseConfig(remnicCfg);
10868
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
10869
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
10870
+ const config = parseConfig2(remnicCfg);
10513
10871
  const orchestrator = new Orchestrator(config);
10514
10872
  try {
10515
10873
  await orchestrator.initialize();
@@ -10632,9 +10990,9 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
10632
10990
  console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
10633
10991
  process.exit(1);
10634
10992
  }
10635
- const rawConfig = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
10636
- const pluginConfig = resolveRemnicConfigRecord(rawConfig);
10637
- const config = parseConfig(pluginConfig);
10993
+ const rawConfig = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
10994
+ const pluginConfig = resolveRemnicConfigRecord2(rawConfig);
10995
+ const config = parseConfig2(pluginConfig);
10638
10996
  if (subAction === "generate") {
10639
10997
  let outputDir;
10640
10998
  try {
@@ -10645,22 +11003,22 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
10645
11003
  }
10646
11004
  const manifest = generateMarketplaceManifest();
10647
11005
  await writeMarketplaceManifest(outputDir, manifest);
10648
- const outPath = path11.join(outputDir, "marketplace.json");
11006
+ const outPath = path12.join(outputDir, "marketplace.json");
10649
11007
  if (json) {
10650
11008
  console.log(JSON.stringify({ status: "generated", path: outPath }, null, 2));
10651
11009
  } else {
10652
11010
  console.log(`Generated marketplace.json at ${outPath}`);
10653
11011
  }
10654
11012
  } else if (subAction === "validate") {
10655
- const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path11.join(process.cwd(), "marketplace.json");
10656
- const resolved = path11.resolve(targetPath);
10657
- if (!fs7.existsSync(resolved)) {
11013
+ const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path12.join(process.cwd(), "marketplace.json");
11014
+ const resolved = path12.resolve(targetPath);
11015
+ if (!fs9.existsSync(resolved)) {
10658
11016
  console.error(`File not found: ${resolved}`);
10659
11017
  process.exit(1);
10660
11018
  }
10661
11019
  let parsed;
10662
11020
  try {
10663
- parsed = JSON.parse(fs7.readFileSync(resolved, "utf8"));
11021
+ parsed = JSON.parse(fs9.readFileSync(resolved, "utf8"));
10664
11022
  } catch {
10665
11023
  console.error(`Invalid JSON in ${resolved}`);
10666
11024
  process.exit(1);
@@ -10861,9 +11219,9 @@ async function cmdSpace(action, rest, json) {
10861
11219
  async function cmdLegacyBenchmark(action, rest, json) {
10862
11220
  initLogger();
10863
11221
  const configPath = resolveConfigPath();
10864
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
10865
- const remnicCfg = resolveRemnicConfigRecord(raw);
10866
- const config = parseConfig(remnicCfg);
11222
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
11223
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
11224
+ const config = parseConfig2(remnicCfg);
10867
11225
  const orchestrator = new Orchestrator(config);
10868
11226
  const service = new EngramAccessService(orchestrator);
10869
11227
  const { runBenchSuite, loadBaseline, checkRegression } = await loadBenchModule();
@@ -11057,7 +11415,7 @@ async function cmdBench(rest) {
11057
11415
  }
11058
11416
  const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
11059
11417
  const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
11060
- printBenchStatusLine(parsed.json, `Resuming from: ${path11.basename(latestStatusPath)}`);
11418
+ printBenchStatusLine(parsed.json, `Resuming from: ${path12.basename(latestStatusPath)}`);
11061
11419
  printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
11062
11420
  printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
11063
11421
  const before = selectedBenchmarks.length;
@@ -11219,9 +11577,9 @@ Options:
11219
11577
  );
11220
11578
  process.exit(1);
11221
11579
  } else {
11222
- fixturePath = path11.resolve(expandTilde(fixturePathRaw));
11580
+ fixturePath = path12.resolve(expandTilde(fixturePathRaw));
11223
11581
  }
11224
- const outPath = path11.resolve(expandTilde(outPathRaw));
11582
+ const outPath = path12.resolve(expandTilde(outPathRaw));
11225
11583
  const benchModule = await loadBenchModule();
11226
11584
  const runner = benchModule.runProceduralAblationCli;
11227
11585
  if (typeof runner !== "function") {
@@ -11240,7 +11598,7 @@ Options:
11240
11598
  );
11241
11599
  console.log(`wrote ${outPath}`);
11242
11600
  }
11243
- var LOGS_DIR = path11.join(PID_DIR, "logs");
11601
+ var LOGS_DIR = path12.join(PID_DIR, "logs");
11244
11602
  var LAUNCHD_PLIST_PATHS = launchdPlistPaths(resolveHomeDir());
11245
11603
  var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
11246
11604
  var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
@@ -11254,7 +11612,7 @@ function readPid() {
11254
11612
  function inferPort() {
11255
11613
  try {
11256
11614
  const configPath = resolveConfigPath();
11257
- const raw = JSON.parse(fs7.readFileSync(configPath, "utf8"));
11615
+ const raw = JSON.parse(fs9.readFileSync(configPath, "utf8"));
11258
11616
  return raw.server?.port ?? 4318;
11259
11617
  } catch {
11260
11618
  return 4318;
@@ -11317,7 +11675,7 @@ function selectLaunchdInspection(openclawPluginModeConfigured) {
11317
11675
  for (const plistPath of LAUNCHD_PLIST_PATHS.slice(1)) {
11318
11676
  const legacy = inspectLaunchdPlist(plistPath);
11319
11677
  if (!legacy.installed) continue;
11320
- const label = path11.basename(plistPath, ".plist");
11678
+ const label = path12.basename(plistPath, ".plist");
11321
11679
  return legacy.ok ? {
11322
11680
  ...legacy,
11323
11681
  warn: true,
@@ -11349,13 +11707,13 @@ function daemonInstall() {
11349
11707
  process.exit(1);
11350
11708
  }
11351
11709
  const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
11352
- fs7.mkdirSync(LOGS_DIR, { recursive: true });
11710
+ fs9.mkdirSync(LOGS_DIR, { recursive: true });
11353
11711
  if (isMacOS()) {
11354
- const templatePath = path11.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
11355
- const template = fs7.readFileSync(templatePath, "utf8");
11712
+ const templatePath = path12.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
11713
+ const template = fs9.readFileSync(templatePath, "utf8");
11356
11714
  const plist = renderTemplate(template, vars);
11357
- fs7.mkdirSync(path11.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
11358
- fs7.writeFileSync(LAUNCHD_PLIST_PATH, plist);
11715
+ fs9.mkdirSync(path12.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
11716
+ fs9.writeFileSync(LAUNCHD_PLIST_PATH, plist);
11359
11717
  try {
11360
11718
  launchdLoadPlist(LAUNCHD_PLIST_PATH);
11361
11719
  } catch (err) {
@@ -11371,11 +11729,11 @@ function daemonInstall() {
11371
11729
  console.log(` RunAtLoad: true, KeepAlive: true`);
11372
11730
  console.log(` Logs: ${LOGS_DIR}/daemon.log`);
11373
11731
  } else if (isLinux()) {
11374
- const templatePath = path11.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
11375
- const template = fs7.readFileSync(templatePath, "utf8");
11732
+ const templatePath = path12.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
11733
+ const template = fs9.readFileSync(templatePath, "utf8");
11376
11734
  const unit = renderTemplate(template, vars);
11377
- fs7.mkdirSync(path11.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
11378
- fs7.writeFileSync(SYSTEMD_UNIT_PATH, unit);
11735
+ fs9.mkdirSync(path12.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
11736
+ fs9.writeFileSync(SYSTEMD_UNIT_PATH, unit);
11379
11737
  try {
11380
11738
  childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
11381
11739
  } catch (err) {
@@ -11411,7 +11769,7 @@ function daemonUninstall() {
11411
11769
  } catch {
11412
11770
  }
11413
11771
  try {
11414
- fs7.unlinkSync(plistPath);
11772
+ fs9.unlinkSync(plistPath);
11415
11773
  removed = true;
11416
11774
  console.log(`Removed launchd service: ${plistPath}`);
11417
11775
  } catch {
@@ -11431,7 +11789,7 @@ function daemonUninstall() {
11431
11789
  let removed = false;
11432
11790
  for (const unitPath of SYSTEMD_UNIT_PATHS) {
11433
11791
  try {
11434
- fs7.unlinkSync(unitPath);
11792
+ fs9.unlinkSync(unitPath);
11435
11793
  removed = true;
11436
11794
  console.log(`Removed systemd service: ${unitPath}`);
11437
11795
  } catch {
@@ -11498,13 +11856,13 @@ async function daemonStatus() {
11498
11856
  console.log(` Port: ${port}`);
11499
11857
  console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
11500
11858
  console.log(` Platform: ${process.platform}`);
11501
- console.log(` PID file: ${fs7.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
11502
- console.log(` Log file: ${fs7.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
11859
+ console.log(` PID file: ${fs9.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
11860
+ console.log(` Log file: ${fs9.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
11503
11861
  try {
11504
11862
  const configPath = resolveConfigPath();
11505
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
11506
- const remnicCfg = resolveRemnicConfigRecord(raw);
11507
- const config = parseConfig(remnicCfg);
11863
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
11864
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
11865
+ const config = parseConfig2(remnicCfg);
11508
11866
  const extRoot = resolveExtensionsRoot(config);
11509
11867
  const noopLog = { warn: () => {
11510
11868
  }, debug: () => {
@@ -11543,9 +11901,9 @@ function daemonStart() {
11543
11901
  return;
11544
11902
  }
11545
11903
  }
11546
- fs7.mkdirSync(PID_DIR, { recursive: true });
11547
- fs7.mkdirSync(LOGS_DIR, { recursive: true });
11548
- const logStream = fs7.openSync(LOG_FILE, "a");
11904
+ fs9.mkdirSync(PID_DIR, { recursive: true });
11905
+ fs9.mkdirSync(LOGS_DIR, { recursive: true });
11906
+ const logStream = fs9.openSync(LOG_FILE, "a");
11549
11907
  const serverBin = resolveServerBin();
11550
11908
  const isSource = serverBin.endsWith(".ts");
11551
11909
  let cmd;
@@ -11567,7 +11925,7 @@ function daemonStart() {
11567
11925
  }
11568
11926
  });
11569
11927
  child.unref();
11570
- fs7.writeFileSync(PID_FILE, String(child.pid));
11928
+ fs9.writeFileSync(PID_FILE, String(child.pid));
11571
11929
  console.log(`Started remnic server (pid ${child.pid})`);
11572
11930
  console.log(` Log: ${LOG_FILE}`);
11573
11931
  }
@@ -11601,11 +11959,11 @@ function daemonStop() {
11601
11959
  console.log("Process not found (cleaning up PID file)");
11602
11960
  }
11603
11961
  try {
11604
- fs7.unlinkSync(PID_FILE);
11962
+ fs9.unlinkSync(PID_FILE);
11605
11963
  } catch {
11606
11964
  }
11607
11965
  try {
11608
- fs7.unlinkSync(LEGACY_PID_FILE);
11966
+ fs9.unlinkSync(LEGACY_PID_FILE);
11609
11967
  } catch {
11610
11968
  }
11611
11969
  }
@@ -11733,9 +12091,9 @@ async function promptYesNo(question, defaultYes = true) {
11733
12091
  async function cmdBinary(rest) {
11734
12092
  initLogger();
11735
12093
  const configPath = resolveConfigPath();
11736
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
11737
- const remnicCfg = resolveRemnicConfigRecord(raw);
11738
- const config = parseConfig(remnicCfg);
12094
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
12095
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
12096
+ const config = parseConfig2(remnicCfg);
11739
12097
  const memoryDir = resolveMemoryDir();
11740
12098
  const blConfig = {
11741
12099
  enabled: config.binaryLifecycleEnabled,
@@ -11853,7 +12211,7 @@ Clean complete: cleaned=${result.cleaned}`
11853
12211
  }
11854
12212
  async function cmdOpenclawInstall(opts) {
11855
12213
  const configPath = resolveOpenclawConfigPath(opts.configPath);
11856
- const fallbackMemoryDir = path11.join(resolveHomeDir(), ".openclaw", "workspace", "memory", "local");
12214
+ const fallbackMemoryDir = path12.join(resolveHomeDir(), ".openclaw", "workspace", "memory", "local");
11857
12215
  console.log(`OpenClaw config: ${configPath}`);
11858
12216
  const existingConfig = readOpenclawConfig(configPath);
11859
12217
  const { plugins, entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
@@ -11924,7 +12282,7 @@ async function cmdOpenclawInstall(opts) {
11924
12282
  } else if (slotIsActiveLegacy) {
11925
12283
  changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
11926
12284
  }
11927
- if (!fs7.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
12285
+ if (!fs9.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
11928
12286
  if (hasLegacy && migrateLegacy) {
11929
12287
  changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
11930
12288
  }
@@ -11944,8 +12302,8 @@ async function cmdOpenclawInstall(opts) {
11944
12302
  Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
11945
12303
  return;
11946
12304
  }
11947
- if (fs7.existsSync(memoryDir)) {
11948
- const st = fs7.statSync(memoryDir);
12305
+ if (fs9.existsSync(memoryDir)) {
12306
+ const st = fs9.statSync(memoryDir);
11949
12307
  if (!st.isDirectory()) {
11950
12308
  throw new Error(
11951
12309
  `Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
@@ -11953,12 +12311,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
11953
12311
  );
11954
12312
  }
11955
12313
  } else {
11956
- fs7.mkdirSync(memoryDir, { recursive: true });
12314
+ fs9.mkdirSync(memoryDir, { recursive: true });
11957
12315
  console.log(`Created memory directory: ${memoryDir}`);
11958
12316
  }
11959
- const configDir = path11.dirname(configPath);
11960
- if (!fs7.existsSync(configDir)) {
11961
- fs7.mkdirSync(configDir, { recursive: true });
12317
+ const configDir = path12.dirname(configPath);
12318
+ if (!fs9.existsSync(configDir)) {
12319
+ fs9.mkdirSync(configDir, { recursive: true });
11962
12320
  }
11963
12321
  atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
11964
12322
  console.log("\nDone! Summary of changes:");
@@ -11984,11 +12342,11 @@ async function cmdOpenclawUpgrade(opts) {
11984
12342
  const configPath = resolveOpenclawConfigPath(opts.configPath);
11985
12343
  const pluginDir = resolveOpenclawPluginDir(opts.pluginDir);
11986
12344
  const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
11987
- const fallbackMemoryDir = path11.join(resolveHomeDir(), ".openclaw", "workspace", "memory", "local");
12345
+ const fallbackMemoryDir = path12.join(resolveHomeDir(), ".openclaw", "workspace", "memory", "local");
11988
12346
  const packageSpec = `@remnic/plugin-openclaw@${opts.version ?? "latest"}`;
11989
12347
  const existingConfig = readOpenclawConfig(configPath);
11990
12348
  const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
11991
- const preservedMemoryDir = opts.memoryDir ? path11.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
12349
+ const preservedMemoryDir = opts.memoryDir ? path12.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
11992
12350
  assertDirectoryPathOrMissing(pluginDir, "OpenClaw plugin dir");
11993
12351
  if (legacyPluginDirForBackup) {
11994
12352
  assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
@@ -12000,7 +12358,7 @@ async function cmdOpenclawUpgrade(opts) {
12000
12358
  }
12001
12359
  console.log(`Memory dir: ${preservedMemoryDir}`);
12002
12360
  console.log(`Package spec: ${packageSpec}`);
12003
- console.log(`Backup root: ${path11.join(resolveHomeDir(), ".openclaw", "backups")}`);
12361
+ console.log(`Backup root: ${path12.join(resolveHomeDir(), ".openclaw", "backups")}`);
12004
12362
  const plannedActions = [
12005
12363
  `backup openclaw.json and the existing ${REMNIC_OPENCLAW_PLUGIN_ID} extension`,
12006
12364
  ...legacyPluginDirForBackup ? [`backup the existing ${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID} extension without modifying it`] : [],
@@ -12026,9 +12384,9 @@ async function cmdOpenclawUpgrade(opts) {
12026
12384
  }
12027
12385
  }
12028
12386
  const backupDir = createOpenclawUpgradeBackupDir();
12029
- const configBackupPath = path11.join(backupDir, "openclaw.json");
12030
- const pluginBackupDir = path11.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
12031
- const legacyPluginBackupDir = legacyPluginDirForBackup ? path11.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
12387
+ const configBackupPath = path12.join(backupDir, "openclaw.json");
12388
+ const pluginBackupDir = path12.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
12389
+ const legacyPluginBackupDir = legacyPluginDirForBackup ? path12.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
12032
12390
  const backupNotes = [];
12033
12391
  if (backupPathIfPresent(configPath, configBackupPath)) {
12034
12392
  backupNotes.push(`+ Backed up config to ${configBackupPath}`);
@@ -12129,16 +12487,16 @@ async function cmdOpenclawMigrateEngram(opts) {
12129
12487
  console.log(" - Re-apply any local source patches to the new package only after verifying the published build.");
12130
12488
  }
12131
12489
  function createOpenclawUpgradeBackupDir() {
12132
- const backupsRoot = path11.join(resolveHomeDir(), ".openclaw", "backups");
12133
- fs7.mkdirSync(backupsRoot, { recursive: true });
12134
- return fs7.mkdtempSync(path11.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
12490
+ const backupsRoot = path12.join(resolveHomeDir(), ".openclaw", "backups");
12491
+ fs9.mkdirSync(backupsRoot, { recursive: true });
12492
+ return fs9.mkdtempSync(path12.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
12135
12493
  }
12136
12494
  async function cmdTaxonomy(rest) {
12137
12495
  initLogger();
12138
12496
  const configPath = resolveConfigPath();
12139
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
12140
- const remnicCfg = resolveRemnicConfigRecord(raw);
12141
- const config = parseConfig(remnicCfg);
12497
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
12498
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
12499
+ const config = parseConfig2(remnicCfg);
12142
12500
  if (!config.taxonomyEnabled) {
12143
12501
  console.error(
12144
12502
  "Taxonomy is disabled in config (taxonomyEnabled = false). Enable it to use taxonomy commands."
@@ -12173,9 +12531,9 @@ async function cmdTaxonomy(rest) {
12173
12531
  const doc = generateResolverDocument(taxonomy);
12174
12532
  console.log(doc);
12175
12533
  if (config.taxonomyAutoGenResolver) {
12176
- const resolverPath = path11.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12177
- fs7.mkdirSync(path11.dirname(resolverPath), { recursive: true });
12178
- fs7.writeFileSync(resolverPath, doc);
12534
+ const resolverPath = path12.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12535
+ fs9.mkdirSync(path12.dirname(resolverPath), { recursive: true });
12536
+ fs9.writeFileSync(resolverPath, doc);
12179
12537
  console.error(`Written: ${resolverPath}`);
12180
12538
  }
12181
12539
  break;
@@ -12220,8 +12578,8 @@ async function cmdTaxonomy(rest) {
12220
12578
  console.log(`Added category "${id}" (${name}).`);
12221
12579
  if (config.taxonomyAutoGenResolver) {
12222
12580
  const doc = generateResolverDocument(taxonomy);
12223
- const resolverPath = path11.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12224
- fs7.writeFileSync(resolverPath, doc);
12581
+ const resolverPath = path12.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12582
+ fs9.writeFileSync(resolverPath, doc);
12225
12583
  console.error(`Regenerated: ${resolverPath}`);
12226
12584
  }
12227
12585
  break;
@@ -12251,8 +12609,8 @@ async function cmdTaxonomy(rest) {
12251
12609
  console.log(`Removed category "${id}".`);
12252
12610
  if (config.taxonomyAutoGenResolver) {
12253
12611
  const doc = generateResolverDocument(taxonomy);
12254
- const resolverPath = path11.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12255
- fs7.writeFileSync(resolverPath, doc);
12612
+ const resolverPath = path12.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
12613
+ fs9.writeFileSync(resolverPath, doc);
12256
12614
  console.error(`Regenerated: ${resolverPath}`);
12257
12615
  }
12258
12616
  break;
@@ -12443,12 +12801,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
12443
12801
  `Unknown training-export format "${args.format}". ${validList}`
12444
12802
  );
12445
12803
  }
12446
- if (!fs7.existsSync(args.memoryDir)) {
12804
+ if (!fs9.existsSync(args.memoryDir)) {
12447
12805
  throw new Error(
12448
12806
  `--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
12449
12807
  );
12450
12808
  }
12451
- if (!fs7.statSync(args.memoryDir).isDirectory()) {
12809
+ if (!fs9.statSync(args.memoryDir).isDirectory()) {
12452
12810
  throw new Error(
12453
12811
  `--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
12454
12812
  );
@@ -12533,11 +12891,11 @@ async function runTrainingExport(args, stdout = process.stdout) {
12533
12891
  );
12534
12892
  }
12535
12893
  const formatted = adapter.formatRecords(records);
12536
- const outDir = path11.dirname(args.output);
12537
- fs7.mkdirSync(outDir, { recursive: true });
12894
+ const outDir = path12.dirname(args.output);
12895
+ fs9.mkdirSync(outDir, { recursive: true });
12538
12896
  const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
12539
- fs7.writeFileSync(tmpPath, formatted, "utf-8");
12540
- fs7.renameSync(tmpPath, args.output);
12897
+ fs9.writeFileSync(tmpPath, formatted, "utf-8");
12898
+ fs9.renameSync(tmpPath, args.output);
12541
12899
  stdout.write(
12542
12900
  `Exported ${records.length} records to ${args.output} (${adapter.name} format)
12543
12901
  `
@@ -12641,7 +12999,7 @@ async function main(argv = process.argv.slice(2)) {
12641
12999
  case "tree": {
12642
13000
  const subAction = rest[0];
12643
13001
  const json = rest.includes("--json");
12644
- const outputDir = resolveFlag(rest, "--output") ?? path11.join(process.cwd(), ".remnic", "context-tree");
13002
+ const outputDir = resolveFlag(rest, "--output") ?? path12.join(process.cwd(), ".remnic", "context-tree");
12645
13003
  const categoriesFlag = resolveFlag(rest, "--categories");
12646
13004
  const categories = categoriesFlag ? categoriesFlag.split(",") : void 0;
12647
13005
  const maxPerCategoryRaw = resolveFlag(rest, "--max-per-category");
@@ -12706,7 +13064,7 @@ async function main(argv = process.argv.slice(2)) {
12706
13064
  }
12707
13065
  }, 500);
12708
13066
  };
12709
- fs7.watch(memoryDir, { recursive: true }, (_event, filename) => {
13067
+ fs9.watch(memoryDir, { recursive: true }, (_event, filename) => {
12710
13068
  if (filename && filename.startsWith(".")) return;
12711
13069
  rebuild();
12712
13070
  });
@@ -12714,12 +13072,12 @@ async function main(argv = process.argv.slice(2)) {
12714
13072
  });
12715
13073
  } else if (subAction === "validate") {
12716
13074
  const treeDir = outputDir;
12717
- if (!fs7.existsSync(treeDir)) {
13075
+ if (!fs9.existsSync(treeDir)) {
12718
13076
  console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
12719
13077
  process.exit(1);
12720
13078
  }
12721
- const indexPath = path11.join(treeDir, "INDEX.md");
12722
- if (!fs7.existsSync(indexPath)) {
13079
+ const indexPath = path12.join(treeDir, "INDEX.md");
13080
+ if (!fs9.existsSync(indexPath)) {
12723
13081
  console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
12724
13082
  process.exit(1);
12725
13083
  }
@@ -12788,6 +13146,12 @@ Options:
12788
13146
  await cmdConnectors(action, rest.slice(1), json);
12789
13147
  break;
12790
13148
  }
13149
+ case "quarantine": {
13150
+ const action = rest[0] ?? "list";
13151
+ const json = rest.includes("--json");
13152
+ await cmdQuarantine(action, rest.slice(1), json);
13153
+ break;
13154
+ }
12791
13155
  case "space": {
12792
13156
  const action = rest[0] ?? "list";
12793
13157
  const json = rest.includes("--json");
@@ -12883,9 +13247,9 @@ Other:
12883
13247
  let wearablesService;
12884
13248
  try {
12885
13249
  const configPath = resolveConfigPath();
12886
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
12887
- const remnicCfg = resolveRemnicConfigRecord(raw);
12888
- const config = parseConfig(remnicCfg);
13250
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
13251
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
13252
+ const config = parseConfig2(remnicCfg);
12889
13253
  wearablesOrchestrator = new Orchestrator(config);
12890
13254
  await wearablesOrchestrator.initialize();
12891
13255
  await wearablesOrchestrator.deferredReady;
@@ -12927,9 +13291,9 @@ Other:
12927
13291
  const targetFactory = async () => {
12928
13292
  if (!orchestratorSingleton) {
12929
13293
  const configPath = resolveConfigPath();
12930
- const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
12931
- const remnicCfg = resolveRemnicConfigRecord(raw);
12932
- const config = parseConfig(remnicCfg);
13294
+ const raw = fs9.existsSync(configPath) ? JSON.parse(fs9.readFileSync(configPath, "utf8")) : {};
13295
+ const remnicCfg = resolveRemnicConfigRecord2(raw);
13296
+ const config = parseConfig2(remnicCfg);
12933
13297
  orchestratorSingleton = new Orchestrator(config);
12934
13298
  await orchestratorSingleton.initialize();
12935
13299
  await orchestratorSingleton.deferredReady;
@@ -13143,6 +13507,7 @@ Usage:
13143
13507
  marketplace generate Generate marketplace.json for Codex
13144
13508
  marketplace validate Validate a marketplace.json file
13145
13509
  marketplace install Install from a marketplace source
13510
+ remnic quarantine list [--json] Inspect writes the namespace ACL rejected
13146
13511
  remnic extensions <list|show|validate|reload> Manage memory extensions
13147
13512
  remnic space <list|switch|create|delete|push|pull|share|promote|audit> Manage spaces
13148
13513
  create accepts --parent <id> to set parent-child relationship
@@ -13261,6 +13626,7 @@ export {
13261
13626
  TAXONOMY_RESOLVE_BOOLEAN_FLAGS,
13262
13627
  TAXONOMY_RESOLVE_VALUE_FLAGS,
13263
13628
  __benchDatasetTestHooks,
13629
+ __statusHealthTestHooks,
13264
13630
  advanceOfflineBaseFilesForSuccessfulPush,
13265
13631
  advanceOfflineLargeFileFailureCounts,
13266
13632
  attachPreparedJudgeCalibration,