@remnic/cli 9.54.8 → 9.56.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 +582 -381
  2. package/package.json +31 -31
package/dist/index.js CHANGED
@@ -18,21 +18,21 @@ async function persistEnrichmentCandidate(storage, entityName, candidate) {
18
18
  }
19
19
 
20
20
  // src/index.ts
21
- import fs14 from "fs";
21
+ import fs15 from "fs";
22
22
  import os3 from "os";
23
- import path17 from "path";
23
+ import path18 from "path";
24
24
  import { createHash as createHash4 } from "crypto";
25
25
  import * as childProcess2 from "child_process";
26
26
  import { fileURLToPath as fileURLToPath5 } from "url";
27
27
  import { gzipSync } from "zlib";
28
28
  import {
29
- parseConfig as parseConfig6,
29
+ parseConfig as parseConfig7,
30
30
  isOpenaiApiKeyDisabled,
31
31
  resolveEnvVars,
32
- resolveRemnicConfigRecord as resolveRemnicConfigRecord5,
33
- Orchestrator as Orchestrator3,
32
+ resolveRemnicConfigRecord as resolveRemnicConfigRecord6,
33
+ Orchestrator as Orchestrator4,
34
34
  EngramAccessService as EngramAccessService2,
35
- initLogger as initLogger2,
35
+ initLogger as initLogger3,
36
36
  onboard,
37
37
  curate,
38
38
  listReviewItems,
@@ -2466,8 +2466,53 @@ function assertBenchModuleFreshForDevelopment() {
2466
2466
  assertLocalBenchBuildFreshForDevelopment(import.meta.url);
2467
2467
  }
2468
2468
 
2469
- // src/daemon-service-candidates.ts
2469
+ // src/cmd-security.ts
2470
2470
  import fs7 from "fs";
2471
+ import {
2472
+ Orchestrator as Orchestrator3,
2473
+ parseConfig as parseConfig6,
2474
+ initLogger as initLogger2,
2475
+ resolveRemnicConfigRecord as resolveRemnicConfigRecord5,
2476
+ runAuditMemoryCliCommand,
2477
+ formatAuditMemoryReport
2478
+ } from "@remnic/core";
2479
+ async function cmdSecurity(rest) {
2480
+ const action = rest[0] ?? "help";
2481
+ if (action !== "audit-memory") {
2482
+ console.error(
2483
+ "Unknown security subcommand. Usage: remnic security audit-memory [--since <iso-date>] [--quarantine] [--json]"
2484
+ );
2485
+ process.exitCode = 1;
2486
+ return;
2487
+ }
2488
+ initLogger2();
2489
+ const configPath = resolveConfigPath();
2490
+ const raw = fs7.existsSync(configPath) ? JSON.parse(fs7.readFileSync(configPath, "utf8")) : {};
2491
+ const config = parseConfig6(resolveRemnicConfigRecord5(raw));
2492
+ const orchestrator = new Orchestrator3(config);
2493
+ await orchestrator.initialize();
2494
+ try {
2495
+ const sinceFlag = rest.indexOf("--since");
2496
+ if (sinceFlag >= 0 && !rest[sinceFlag + 1]) {
2497
+ console.error("--since requires a value");
2498
+ process.exitCode = 1;
2499
+ return;
2500
+ }
2501
+ const json = rest.includes("--json");
2502
+ const report = await runAuditMemoryCliCommand({
2503
+ memoryDir: config.memoryDir,
2504
+ storage: orchestrator.storage,
2505
+ since: sinceFlag >= 0 ? rest[sinceFlag + 1] : void 0,
2506
+ quarantine: rest.includes("--quarantine")
2507
+ });
2508
+ console.log(json ? JSON.stringify(report, null, 2) : formatAuditMemoryReport(report));
2509
+ } finally {
2510
+ orchestrator.abortDeferredInit();
2511
+ }
2512
+ }
2513
+
2514
+ // src/daemon-service-candidates.ts
2515
+ import fs8 from "fs";
2471
2516
  import path5 from "path";
2472
2517
  var LAUNCHD_LABEL = "ai.remnic.daemon";
2473
2518
  var LEGACY_REMNIC_SERVER_LAUNCHD_LABEL = "ai.remnic.server";
@@ -2489,7 +2534,7 @@ function systemdUnitPaths(homeDir) {
2489
2534
  function anyFileExists(paths) {
2490
2535
  return paths.some((candidate) => {
2491
2536
  try {
2492
- return fs7.statSync(candidate).isFile();
2537
+ return fs8.statSync(candidate).isFile();
2493
2538
  } catch {
2494
2539
  return false;
2495
2540
  }
@@ -2501,7 +2546,7 @@ function commandNames(command) {
2501
2546
  }
2502
2547
  function isRunnableNodeScript(filePath) {
2503
2548
  try {
2504
- const text = fs7.readFileSync(filePath, "utf8").slice(0, 4096);
2549
+ const text = fs8.readFileSync(filePath, "utf8").slice(0, 4096);
2505
2550
  const firstLine = text.split(/\r?\n/, 1)[0] ?? "";
2506
2551
  if (/^#!.*\bnode\b/.test(firstLine)) return true;
2507
2552
  if (firstLine.startsWith("#!")) return false;
@@ -2514,7 +2559,7 @@ function isRunnableNodeScript(filePath) {
2514
2559
  function resolveShimNodeScript(filePath) {
2515
2560
  let text;
2516
2561
  try {
2517
- text = fs7.readFileSync(filePath, "utf8").slice(0, 16384);
2562
+ text = fs8.readFileSync(filePath, "utf8").slice(0, 16384);
2518
2563
  } catch {
2519
2564
  return void 0;
2520
2565
  }
@@ -2526,8 +2571,8 @@ function resolveShimNodeScript(filePath) {
2526
2571
  const candidate = raw.replaceAll("${basedir}", basedir).replaceAll("$basedir", basedir).replaceAll("\\ ", " ");
2527
2572
  const resolved = path5.isAbsolute(candidate) ? candidate : path5.resolve(basedir, candidate);
2528
2573
  try {
2529
- if (fs7.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
2530
- return fs7.realpathSync(resolved);
2574
+ if (fs8.statSync(resolved).isFile() && isRunnableNodeScript(resolved)) {
2575
+ return fs8.realpathSync(resolved);
2531
2576
  }
2532
2577
  } catch {
2533
2578
  }
@@ -2535,7 +2580,7 @@ function resolveShimNodeScript(filePath) {
2535
2580
  return void 0;
2536
2581
  }
2537
2582
  function resolveRunnableNodeScript(filePath) {
2538
- const realPath = fs7.realpathSync(filePath);
2583
+ const realPath = fs8.realpathSync(filePath);
2539
2584
  if (isRunnableNodeScript(realPath)) return realPath;
2540
2585
  return resolveShimNodeScript(realPath);
2541
2586
  }
@@ -2545,9 +2590,9 @@ function findCommandOnPath(command, pathEnv = process.env.PATH ?? "") {
2545
2590
  for (const name of commandNames(command)) {
2546
2591
  const candidate = path5.join(dir, name);
2547
2592
  try {
2548
- const stat2 = fs7.statSync(candidate);
2593
+ const stat2 = fs8.statSync(candidate);
2549
2594
  if (!stat2.isFile()) continue;
2550
- if (process.platform !== "win32") fs7.accessSync(candidate, fs7.constants.X_OK);
2595
+ if (process.platform !== "win32") fs8.accessSync(candidate, fs8.constants.X_OK);
2551
2596
  const runnable = resolveRunnableNodeScript(candidate);
2552
2597
  if (runnable) return runnable;
2553
2598
  } catch {
@@ -4038,7 +4083,7 @@ function finalizeBenchStatus(filePath) {
4038
4083
  }
4039
4084
 
4040
4085
  // src/bench-fallback.ts
4041
- import fs8 from "fs";
4086
+ import fs9 from "fs";
4042
4087
  import path9 from "path";
4043
4088
  var FALLBACK_RESULTS_DIRNAME = "fallback-runs";
4044
4089
  function buildBenchRunnerArgs(parsed, benchmarkId, outputDir) {
@@ -4110,7 +4155,7 @@ function createFallbackBenchOutputDir(resultsDir, benchmarkId, pid, startedAtMs
4110
4155
  );
4111
4156
  }
4112
4157
  function resolveFallbackBenchResultPath(outputDir) {
4113
- const entries = fs8.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
4158
+ const entries = fs9.readdirSync(outputDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort();
4114
4159
  if (entries.length === 0) {
4115
4160
  throw new Error(`Fallback benchmark runner did not write a JSON result artifact in ${outputDir}`);
4116
4161
  }
@@ -4118,7 +4163,7 @@ function resolveFallbackBenchResultPath(outputDir) {
4118
4163
  }
4119
4164
 
4120
4165
  // src/openclaw-upgrade-swap.ts
4121
- import fs9 from "fs";
4166
+ import fs10 from "fs";
4122
4167
  import path10 from "path";
4123
4168
  function describeError(error) {
4124
4169
  return error instanceof Error ? error.message : String(error);
@@ -4130,7 +4175,7 @@ function createSiblingTempFilePath(targetPath, label) {
4130
4175
  function resolveAtomicWriteMode(targetPath, explicitMode) {
4131
4176
  if (explicitMode !== void 0) return explicitMode;
4132
4177
  try {
4133
- return fs9.statSync(targetPath).mode & 4095;
4178
+ return fs10.statSync(targetPath).mode & 4095;
4134
4179
  } catch (error) {
4135
4180
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
4136
4181
  return 384;
@@ -4140,8 +4185,8 @@ function resolveAtomicWriteMode(targetPath, explicitMode) {
4140
4185
  }
4141
4186
  function resolveAtomicReplacementPath(targetPath) {
4142
4187
  try {
4143
- if (fs9.lstatSync(targetPath).isSymbolicLink()) {
4144
- return fs9.realpathSync(targetPath);
4188
+ if (fs10.lstatSync(targetPath).isSymbolicLink()) {
4189
+ return fs10.realpathSync(targetPath);
4145
4190
  }
4146
4191
  } catch (error) {
4147
4192
  if (error instanceof Error && "code" in error && error.code === "ENOENT") {
@@ -4158,7 +4203,7 @@ function createSiblingSwapPath(targetDir, label) {
4158
4203
  function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
4159
4204
  if (!displacedDir) return void 0;
4160
4205
  try {
4161
- fs9.rmSync(displacedDir, { recursive: true, force: true });
4206
+ fs10.rmSync(displacedDir, { recursive: true, force: true });
4162
4207
  return void 0;
4163
4208
  } catch (error) {
4164
4209
  return `Warning: ${context}, but failed to remove the displaced plugin copy at ${displacedDir}: ${describeError(error)}`;
@@ -4166,43 +4211,43 @@ function cleanupDisplacedDirectoryBestEffort(displacedDir, context) {
4166
4211
  }
4167
4212
  function atomicWriteFileSync(targetPath, data, options = {}) {
4168
4213
  const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
4169
- fs9.mkdirSync(path10.dirname(resolvedTargetPath), { recursive: true });
4214
+ fs10.mkdirSync(path10.dirname(resolvedTargetPath), { recursive: true });
4170
4215
  const tempPath = createSiblingTempFilePath(resolvedTargetPath, "write");
4171
4216
  const mode = resolveAtomicWriteMode(resolvedTargetPath, options.mode);
4172
4217
  try {
4173
4218
  if (options.hooks?.writeTempFileSync) {
4174
4219
  options.hooks.writeTempFileSync(tempPath);
4175
4220
  } else {
4176
- fs9.writeFileSync(tempPath, data, { mode });
4221
+ fs10.writeFileSync(tempPath, data, { mode });
4177
4222
  }
4178
- fs9.chmodSync(tempPath, mode);
4179
- const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs9.renameSync;
4223
+ fs10.chmodSync(tempPath, mode);
4224
+ const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs10.renameSync;
4180
4225
  renameTempFileSync(tempPath, resolvedTargetPath);
4181
4226
  } catch (error) {
4182
- fs9.rmSync(tempPath, { force: true });
4227
+ fs10.rmSync(tempPath, { force: true });
4183
4228
  throw error;
4184
4229
  }
4185
4230
  }
4186
4231
  function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
4187
- if (!fs9.existsSync(sourcePath)) return;
4232
+ if (!fs10.existsSync(sourcePath)) return;
4188
4233
  const resolvedTargetPath = resolveAtomicReplacementPath(targetPath);
4189
- fs9.mkdirSync(path10.dirname(resolvedTargetPath), { recursive: true });
4234
+ fs10.mkdirSync(path10.dirname(resolvedTargetPath), { recursive: true });
4190
4235
  const tempPath = createSiblingTempFilePath(resolvedTargetPath, "copy");
4191
- const mode = fs9.statSync(sourcePath).mode & 4095;
4236
+ const mode = fs10.statSync(sourcePath).mode & 4095;
4192
4237
  try {
4193
- const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs9.copyFileSync;
4238
+ const copyTempFileSync = options.hooks?.copyTempFileSync ?? fs10.copyFileSync;
4194
4239
  copyTempFileSync(sourcePath, tempPath);
4195
- fs9.chmodSync(tempPath, mode);
4196
- const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs9.renameSync;
4240
+ fs10.chmodSync(tempPath, mode);
4241
+ const renameTempFileSync = options.hooks?.renameTempFileSync ?? fs10.renameSync;
4197
4242
  renameTempFileSync(tempPath, resolvedTargetPath);
4198
4243
  } catch (error) {
4199
- fs9.rmSync(tempPath, { force: true });
4244
+ fs10.rmSync(tempPath, { force: true });
4200
4245
  throw error;
4201
4246
  }
4202
4247
  }
4203
4248
  function cleanupRollbackDirectory(rollbackDir) {
4204
4249
  if (!rollbackDir) return;
4205
- fs9.rmSync(rollbackDir, { recursive: true, force: true });
4250
+ fs10.rmSync(rollbackDir, { recursive: true, force: true });
4206
4251
  }
4207
4252
  function cleanupRollbackDirectoryBestEffort(rollbackDir) {
4208
4253
  if (!rollbackDir) return void 0;
@@ -4214,20 +4259,20 @@ function cleanupRollbackDirectoryBestEffort(rollbackDir) {
4214
4259
  }
4215
4260
  }
4216
4261
  function restoreDirectoryFromRollback(targetDir, rollbackDir) {
4217
- if (!fs9.existsSync(rollbackDir)) {
4262
+ if (!fs10.existsSync(rollbackDir)) {
4218
4263
  throw new Error(`Rollback directory is missing: ${rollbackDir}`);
4219
4264
  }
4220
- fs9.mkdirSync(path10.dirname(targetDir), { recursive: true });
4221
- const displacedDir = fs9.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
4265
+ fs10.mkdirSync(path10.dirname(targetDir), { recursive: true });
4266
+ const displacedDir = fs10.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "rollback-restore") : void 0;
4222
4267
  if (displacedDir) {
4223
- fs9.renameSync(targetDir, displacedDir);
4268
+ fs10.renameSync(targetDir, displacedDir);
4224
4269
  }
4225
4270
  try {
4226
- fs9.renameSync(rollbackDir, targetDir);
4271
+ fs10.renameSync(rollbackDir, targetDir);
4227
4272
  } catch (restoreError) {
4228
- if (displacedDir && fs9.existsSync(displacedDir)) {
4273
+ if (displacedDir && fs10.existsSync(displacedDir)) {
4229
4274
  try {
4230
- fs9.renameSync(displacedDir, targetDir);
4275
+ fs10.renameSync(displacedDir, targetDir);
4231
4276
  } catch (revertError) {
4232
4277
  throw new AggregateError(
4233
4278
  [restoreError, revertError],
@@ -4243,23 +4288,23 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
4243
4288
  return cleanupDisplacedDirectoryBestEffort(displacedDir, `restored the previous plugin copy into ${targetDir}`);
4244
4289
  }
4245
4290
  function restoreDirectoryFromBackup(targetDir, backupDir) {
4246
- if (!fs9.existsSync(backupDir)) {
4291
+ if (!fs10.existsSync(backupDir)) {
4247
4292
  throw new Error(`Plugin backup directory is missing: ${backupDir}`);
4248
4293
  }
4249
- fs9.mkdirSync(path10.dirname(targetDir), { recursive: true });
4294
+ fs10.mkdirSync(path10.dirname(targetDir), { recursive: true });
4250
4295
  const stagedDir = createSiblingSwapPath(targetDir, "backup-restore");
4251
- const displacedDir = fs9.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
4252
- fs9.cpSync(backupDir, stagedDir, { recursive: true });
4296
+ const displacedDir = fs10.existsSync(targetDir) ? createSiblingSwapPath(targetDir, "pre-backup-restore") : void 0;
4297
+ fs10.cpSync(backupDir, stagedDir, { recursive: true });
4253
4298
  if (displacedDir) {
4254
- fs9.renameSync(targetDir, displacedDir);
4299
+ fs10.renameSync(targetDir, displacedDir);
4255
4300
  }
4256
4301
  try {
4257
- fs9.renameSync(stagedDir, targetDir);
4302
+ fs10.renameSync(stagedDir, targetDir);
4258
4303
  } catch (restoreError) {
4259
- fs9.rmSync(targetDir, { recursive: true, force: true });
4260
- if (displacedDir && fs9.existsSync(displacedDir)) {
4304
+ fs10.rmSync(targetDir, { recursive: true, force: true });
4305
+ if (displacedDir && fs10.existsSync(displacedDir)) {
4261
4306
  try {
4262
- fs9.renameSync(displacedDir, targetDir);
4307
+ fs10.renameSync(displacedDir, targetDir);
4263
4308
  } catch (revertError) {
4264
4309
  throw new AggregateError(
4265
4310
  [restoreError, revertError],
@@ -4267,7 +4312,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
4267
4312
  );
4268
4313
  }
4269
4314
  }
4270
- fs9.rmSync(stagedDir, { recursive: true, force: true });
4315
+ fs10.rmSync(stagedDir, { recursive: true, force: true });
4271
4316
  throw new Error(
4272
4317
  `Failed to restore the plugin backup into ${targetDir}. The durable backup remains preserved at ${backupDir}.`,
4273
4318
  { cause: restoreError }
@@ -4292,7 +4337,7 @@ function rollbackOpenclawUpgrade({
4292
4337
  let configRemovalAttempted = false;
4293
4338
  let pluginRestored = false;
4294
4339
  try {
4295
- if (rollbackDir && fs9.existsSync(rollbackDir)) {
4340
+ if (rollbackDir && fs10.existsSync(rollbackDir)) {
4296
4341
  const cleanupWarning = restoreDirectoryFromRollback(pluginDir, rollbackDir);
4297
4342
  notes.push(`Restored previous plugin from rollback copy at ${rollbackDir}`);
4298
4343
  if (cleanupWarning) notes.push(cleanupWarning);
@@ -4302,7 +4347,7 @@ function rollbackOpenclawUpgrade({
4302
4347
  rollbackRestoreError = error instanceof Error ? error.message : String(error);
4303
4348
  }
4304
4349
  try {
4305
- if (!pluginRestored && pluginBackupDir && fs9.existsSync(pluginBackupDir)) {
4350
+ if (!pluginRestored && pluginBackupDir && fs10.existsSync(pluginBackupDir)) {
4306
4351
  const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
4307
4352
  if (rollbackRestoreError) {
4308
4353
  notes.push(`Rollback copy restore failed; restored previous plugin from durable backup at ${pluginBackupDir}`);
@@ -4327,12 +4372,12 @@ function rollbackOpenclawUpgrade({
4327
4372
  notes.push("No previous plugin copy was available for automatic restore");
4328
4373
  }
4329
4374
  try {
4330
- if (configBackupPath && fs9.existsSync(configBackupPath)) {
4375
+ if (configBackupPath && fs10.existsSync(configBackupPath)) {
4331
4376
  restoreFileFromBackup(configPath, configBackupPath);
4332
4377
  notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
4333
- } else if (removeConfigIfUnbacked && fs9.existsSync(configPath)) {
4378
+ } else if (removeConfigIfUnbacked && fs10.existsSync(configPath)) {
4334
4379
  configRemovalAttempted = true;
4335
- fs9.rmSync(configPath, { force: true });
4380
+ fs10.rmSync(configPath, { force: true });
4336
4381
  notes.push("Removed OpenClaw config created during the failed upgrade");
4337
4382
  }
4338
4383
  } catch (error) {
@@ -4385,7 +4430,7 @@ Run this manually when you're ready:
4385
4430
 
4386
4431
  // src/openclaw-managed-upgrade-loader.ts
4387
4432
  import { execFileSync } from "child_process";
4388
- import fs10 from "fs";
4433
+ import fs11 from "fs";
4389
4434
  import os from "os";
4390
4435
  import path11 from "path";
4391
4436
  import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "url";
@@ -4461,7 +4506,7 @@ function buildOpenclawManagedUpgradePackageSpec(version = "latest") {
4461
4506
  function readCliAdapterRange() {
4462
4507
  const moduleDir = path11.dirname(fileURLToPath3(import.meta.url));
4463
4508
  const manifestPath = path11.resolve(moduleDir, "../package.json");
4464
- const manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf8"));
4509
+ const manifest = JSON.parse(fs11.readFileSync(manifestPath, "utf8"));
4465
4510
  if (manifest.name !== "@remnic/cli") {
4466
4511
  throw new Error(`Invalid @remnic/cli package manifest at ${manifestPath}.`);
4467
4512
  }
@@ -4505,7 +4550,7 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
4505
4550
  const adapterMissing = isSpecifierNotFoundError(error, OPENCLAW_PLUGIN_PACKAGE) || isSpecifierNotFoundError(error, MANAGED_UPGRADE_SPECIFIER) || isManagedUpgradeSubpathMissing(error);
4506
4551
  if (!adapterMissing) throw error;
4507
4552
  }
4508
- const temporaryRoot = fs10.mkdtempSync(path11.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
4553
+ const temporaryRoot = fs11.mkdtempSync(path11.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
4509
4554
  try {
4510
4555
  const toolingPackageSpec = `${OPENCLAW_PLUGIN_PACKAGE}@${readCliAdapterRange()}`;
4511
4556
  const installArgs = [
@@ -4520,12 +4565,12 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
4520
4565
  ];
4521
4566
  (hooks.runNpmInstall ?? runNpmInstall)(installArgs);
4522
4567
  const resolverPath = path11.join(temporaryRoot, "load-managed-upgrade.mjs");
4523
- fs10.writeFileSync(resolverPath, `export * from ${JSON.stringify(MANAGED_UPGRADE_SPECIFIER)};
4568
+ fs11.writeFileSync(resolverPath, `export * from ${JSON.stringify(MANAGED_UPGRADE_SPECIFIER)};
4524
4569
  `, "utf8");
4525
4570
  return await importModule(pathToFileURL2(resolverPath).href);
4526
4571
  } finally {
4527
4572
  try {
4528
- fs10.rmSync(temporaryRoot, { recursive: true, force: true });
4573
+ fs11.rmSync(temporaryRoot, { recursive: true, force: true });
4529
4574
  } catch (error) {
4530
4575
  const detail = error instanceof Error ? error.message : String(error);
4531
4576
  console.warn(`Could not remove temporary managed upgrade project at ${temporaryRoot}: ${detail}`);
@@ -4534,7 +4579,7 @@ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
4534
4579
  }
4535
4580
 
4536
4581
  // src/daemon-service.ts
4537
- import fs11 from "fs";
4582
+ import fs12 from "fs";
4538
4583
  import path12 from "path";
4539
4584
  import * as childProcess from "child_process";
4540
4585
  import { fileURLToPath as fileURLToPath4 } from "url";
@@ -4546,7 +4591,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
4546
4591
  processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
4547
4592
  }
4548
4593
  function resolveServerBinDetails(options = {}) {
4549
- const existsSync4 = options.existsSync ?? fs11.existsSync;
4594
+ const existsSync4 = options.existsSync ?? fs12.existsSync;
4550
4595
  const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
4551
4596
  const moduleDir = options.moduleDir ?? thisModuleDir;
4552
4597
  const packageResolve = options.packageResolve ?? resolveImportSpecifier;
@@ -4605,8 +4650,8 @@ function resolveServerBin(options = {}) {
4605
4650
  return resolveServerBinDetails(options).path;
4606
4651
  }
4607
4652
  function readVerifiedDaemonPid(options) {
4608
- const readFileSync4 = options.readFileSync ?? fs11.readFileSync;
4609
- const unlinkSync = options.unlinkSync ?? fs11.unlinkSync;
4653
+ const readFileSync4 = options.readFileSync ?? fs12.readFileSync;
4654
+ const unlinkSync = options.unlinkSync ?? fs12.unlinkSync;
4610
4655
  const processKill = options.processKill ?? process.kill;
4611
4656
  const platform = options.platform ?? process.platform;
4612
4657
  const execFileSync4 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
@@ -4706,8 +4751,8 @@ function removePidFileBestEffort(file, unlinkSync) {
4706
4751
  }
4707
4752
  }
4708
4753
  function inspectLaunchdPlist(plistPath, options = {}) {
4709
- const existsSync4 = options.existsSync ?? fs11.existsSync;
4710
- const readFileSync4 = options.readFileSync ?? fs11.readFileSync;
4754
+ const existsSync4 = options.existsSync ?? fs12.existsSync;
4755
+ const readFileSync4 = options.readFileSync ?? fs12.readFileSync;
4711
4756
  if (!existsSync4(plistPath)) {
4712
4757
  return {
4713
4758
  installed: false,
@@ -4941,7 +4986,7 @@ function stripConfigArgv(args) {
4941
4986
  }
4942
4987
 
4943
4988
  // src/import-dispatch.ts
4944
- import fs12 from "fs";
4989
+ import fs13 from "fs";
4945
4990
  import {
4946
4991
  runImporter,
4947
4992
  validateImportBatchSize,
@@ -5455,7 +5500,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
5455
5500
  let materializedTarget;
5456
5501
  let materializePromise;
5457
5502
  const io = {
5458
- readFile: ioOverrides.readFile ?? (async (p) => fs12.promises.readFile(p, "utf-8")),
5503
+ readFile: ioOverrides.readFile ?? (async (p) => fs13.promises.readFile(p, "utf-8")),
5459
5504
  loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
5460
5505
  runImporter: ioOverrides.runImporter ?? runImporter,
5461
5506
  getWriteTarget: async () => {
@@ -5568,7 +5613,7 @@ async function cmdCapture(rest, io) {
5568
5613
  }
5569
5614
 
5570
5615
  // src/import-lossless-claw-cmd.ts
5571
- import fs13 from "fs";
5616
+ import fs14 from "fs";
5572
5617
  import path14 from "path";
5573
5618
  import {
5574
5619
  applyLcmSchema,
@@ -5680,15 +5725,15 @@ async function loadImportLosslessClawModule() {
5680
5725
 
5681
5726
  // src/import-lossless-claw-cmd.ts
5682
5727
  function assertDirectoryOrAbsent(p, label) {
5683
- if (fs13.existsSync(p) && !fs13.statSync(p).isDirectory()) {
5728
+ if (fs14.existsSync(p) && !fs14.statSync(p).isDirectory()) {
5684
5729
  throw new Error(`${label} is not a directory: ${p}`);
5685
5730
  }
5686
5731
  }
5687
5732
  function assertFile(p, label) {
5688
- if (!fs13.existsSync(p)) {
5733
+ if (!fs14.existsSync(p)) {
5689
5734
  throw new Error(`${label} does not exist: ${p}`);
5690
5735
  }
5691
- if (!fs13.statSync(p).isFile()) {
5736
+ if (!fs14.statSync(p).isFile()) {
5692
5737
  throw new Error(`${label} is not a file: ${p}`);
5693
5738
  }
5694
5739
  }
@@ -5720,7 +5765,7 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
5720
5765
  try {
5721
5766
  if (parsed.dryRun) {
5722
5767
  const lcmPath = path14.join(memoryDir, "state", "lcm.sqlite");
5723
- if (fs13.existsSync(lcmPath)) {
5768
+ if (fs14.existsSync(lcmPath)) {
5724
5769
  destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
5725
5770
  } else {
5726
5771
  destDb = mod.openInMemoryDestinationDatabase();
@@ -6459,8 +6504,158 @@ async function cmdBenchCoding(args) {
6459
6504
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
6460
6505
  }
6461
6506
 
6462
- // src/bench-research-commands.ts
6507
+ // src/bench-security-commands.ts
6463
6508
  import path16 from "path";
6509
+ var DEFAULT_OUTPUT_DIR = path16.join(
6510
+ resolveHomeDir(),
6511
+ ".remnic",
6512
+ "bench",
6513
+ "results",
6514
+ "h5-injection-suite"
6515
+ );
6516
+ var BENCH_SECURITY_USAGE = `Usage: remnic bench security injection-suite --seeds N [options]
6517
+
6518
+ H5 injection-suite runner. Resume, host-fault pause, multi-host claim
6519
+ leases, and --limit follow the H6 contract (issue #1963 / PR #2312).
6520
+
6521
+ Options:
6522
+ --seeds N Positive seed count (required)
6523
+ --variants-per-family N Variants per attack family (default: 25)
6524
+ --model-profile ID Profile label recorded on each row (default: local-dry)
6525
+ --executor local|ollama|openai-compat
6526
+ local = deterministic screen/fence (default)
6527
+ ollama = native /api/chat
6528
+ openai-compat = /v1/chat/completions
6529
+ --base-url URL Endpoint (default: http://127.0.0.1:11434)
6530
+ --model NAME Model id (default: qwen2.5:7b-instruct)
6531
+ --request-timeout-ms N Per-call timeout (default: 120000)
6532
+ --out DIR New run directory (default: ~/.remnic/bench/results/h5-injection-suite)
6533
+ --run DIR Existing run directory; implies --resume
6534
+ --resume Continue an existing run (required if DIR already has run.json)
6535
+ --limit N Execute at most N planned rows (dry-run / smoke)
6536
+ `;
6537
+ function parsePositiveInteger(raw, flag) {
6538
+ const value = Number(raw);
6539
+ if (!Number.isInteger(value) || value < 1) {
6540
+ throw new Error(`${flag} must be a positive integer`);
6541
+ }
6542
+ return value;
6543
+ }
6544
+ function parseBenchSecurityArgs(args) {
6545
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") return { help: true };
6546
+ if (args[0] !== "injection-suite") {
6547
+ throw new Error(`unknown bench security subcommand ${args[0]}`);
6548
+ }
6549
+ let seeds;
6550
+ let variantsPerFamily = 25;
6551
+ let modelProfileId = "local-dry";
6552
+ let outputDir = DEFAULT_OUTPUT_DIR;
6553
+ let resume = false;
6554
+ let limit;
6555
+ let executor = "local";
6556
+ let baseUrl;
6557
+ let model;
6558
+ let requestTimeoutMs;
6559
+ for (let index = 1; index < args.length; index += 1) {
6560
+ const flag = args[index] ?? "";
6561
+ const next = args[index + 1];
6562
+ if (flag === "--seeds") {
6563
+ seeds = parsePositiveInteger(next, "--seeds");
6564
+ index += 1;
6565
+ } else if (flag === "--variants-per-family") {
6566
+ variantsPerFamily = parsePositiveInteger(next, "--variants-per-family");
6567
+ index += 1;
6568
+ } else if (flag === "--model-profile") {
6569
+ if (next === void 0 || next.startsWith("-")) throw new Error("missing value for --model-profile");
6570
+ modelProfileId = next;
6571
+ index += 1;
6572
+ } else if (flag === "--executor") {
6573
+ if (next !== "local" && next !== "ollama" && next !== "openai-compat") {
6574
+ throw new Error("--executor must be local, ollama, or openai-compat");
6575
+ }
6576
+ executor = next;
6577
+ index += 1;
6578
+ } else if (flag === "--base-url") {
6579
+ if (next === void 0 || next.startsWith("-")) throw new Error("missing value for --base-url");
6580
+ baseUrl = next;
6581
+ index += 1;
6582
+ } else if (flag === "--model") {
6583
+ if (next === void 0 || next.startsWith("-")) throw new Error("missing value for --model");
6584
+ model = next;
6585
+ index += 1;
6586
+ } else if (flag === "--request-timeout-ms") {
6587
+ requestTimeoutMs = parsePositiveInteger(next, "--request-timeout-ms");
6588
+ index += 1;
6589
+ } else if (flag === "--out") {
6590
+ if (next === void 0 || next.startsWith("-")) throw new Error("missing value for --out");
6591
+ outputDir = expandTilde(next);
6592
+ index += 1;
6593
+ } else if (flag === "--run") {
6594
+ if (next === void 0 || next.startsWith("-")) throw new Error("missing value for --run");
6595
+ outputDir = expandTilde(next);
6596
+ resume = true;
6597
+ index += 1;
6598
+ } else if (flag === "--resume") {
6599
+ resume = true;
6600
+ } else if (flag === "--limit") {
6601
+ limit = parsePositiveInteger(next, "--limit");
6602
+ index += 1;
6603
+ } else {
6604
+ throw new Error(`unknown option ${flag}`);
6605
+ }
6606
+ }
6607
+ if (seeds === void 0) throw new Error("injection-suite requires --seeds N");
6608
+ return {
6609
+ seeds,
6610
+ variantsPerFamily,
6611
+ modelProfileId,
6612
+ outputDir,
6613
+ resume,
6614
+ executor,
6615
+ ...limit === void 0 ? {} : { limit },
6616
+ ...baseUrl === void 0 ? {} : { baseUrl },
6617
+ ...model === void 0 ? {} : { model },
6618
+ ...requestTimeoutMs === void 0 ? {} : { requestTimeoutMs }
6619
+ };
6620
+ }
6621
+ async function cmdBenchSecurity(args) {
6622
+ try {
6623
+ const parsed = parseBenchSecurityArgs(args);
6624
+ if ("help" in parsed) {
6625
+ console.log(BENCH_SECURITY_USAGE);
6626
+ return;
6627
+ }
6628
+ const bench = await loadBenchModule();
6629
+ const run = bench.runInjectionSuiteCliCommand;
6630
+ if (typeof run !== "function") {
6631
+ throw new Error("Installed @remnic/bench is missing runInjectionSuiteCliCommand");
6632
+ }
6633
+ const result = await run({
6634
+ seeds: parsed.seeds,
6635
+ variantsPerFamily: parsed.variantsPerFamily,
6636
+ modelProfileId: parsed.modelProfileId,
6637
+ outputDir: parsed.outputDir,
6638
+ executor: parsed.executor,
6639
+ ...parsed.resume ? { resume: true } : {},
6640
+ ...parsed.limit === void 0 ? {} : { limit: parsed.limit },
6641
+ ...parsed.baseUrl === void 0 ? {} : { baseUrl: parsed.baseUrl },
6642
+ ...parsed.model === void 0 ? {} : { model: parsed.model },
6643
+ ...parsed.requestTimeoutMs === void 0 ? {} : { requestTimeoutMs: parsed.requestTimeoutMs }
6644
+ });
6645
+ if (result.exitCode === 0) console.log(result.output);
6646
+ else console.error(result.output);
6647
+ if (result.exitCode !== 0) process.exitCode = result.exitCode;
6648
+ } catch (error) {
6649
+ const message = error instanceof Error ? error.message : String(error);
6650
+ console.error(`${message}
6651
+
6652
+ ${BENCH_SECURITY_USAGE}`);
6653
+ process.exitCode = 1;
6654
+ }
6655
+ }
6656
+
6657
+ // src/bench-research-commands.ts
6658
+ import path17 from "path";
6464
6659
  function emit(result) {
6465
6660
  if (result.output) {
6466
6661
  console.log(result.output);
@@ -6478,7 +6673,7 @@ async function runBenchResearchCommand(parsed) {
6478
6673
  emit(
6479
6674
  await runAttributeCliCommand({
6480
6675
  runRef: parsed.runRef,
6481
- resultsDir: parsed.resultsDir ?? path16.join(resolveHomeDir(), ".remnic", "bench", "results"),
6676
+ resultsDir: parsed.resultsDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "results"),
6482
6677
  memoryDir: parsed.memoryDir,
6483
6678
  qmdPath: parsed.qmdPath,
6484
6679
  collection: parsed.collection,
@@ -6507,8 +6702,8 @@ async function runBenchResearchCommand(parsed) {
6507
6702
 
6508
6703
  // src/bench-usage.ts
6509
6704
  function getBenchUsageText() {
6510
- return `Usage: remnic bench <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|attribute|drift-gen|coding> [options] [benchmark...]
6511
- remnic benchmark <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|check|report|attribute|drift-gen|coding> [options] [benchmark...]
6705
+ return `Usage: remnic bench <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|attribute|drift-gen|coding|security> [options] [benchmark...]
6706
+ remnic benchmark <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|check|report|attribute|drift-gen|coding|security> [options] [benchmark...]
6512
6707
 
6513
6708
  Commands:
6514
6709
  list List published benchmark packs
@@ -6546,6 +6741,8 @@ Commands:
6546
6741
  coding H6 synthetic coding benchmark commands
6547
6742
  Run \`remnic bench coding --help\` for repo generation,
6548
6743
  repeated-failure runs, resume, and offline stats replay
6744
+ security H5 injection-suite runner (resume/pause/--limit)
6745
+ Run \`remnic bench security --help\`
6549
6746
  check Legacy latency regression gate (compatibility)
6550
6747
  attribute --run <id> [--results-dir <path>] [--memory-dir <path>] [--threshold <value>]
6551
6748
  [--qmd <path> --collection <name>]
@@ -6748,15 +6945,15 @@ registerPublisher("omp", () => new LazyPluginPiPublisher("omp", (mod) => mod.Omp
6748
6945
  function readCompatEnv(primary, legacy) {
6749
6946
  return process.env[primary] ?? process.env[legacy];
6750
6947
  }
6751
- var PID_DIR = path17.join(resolveHomeDir(), ".remnic");
6752
- var LEGACY_PID_DIR = path17.join(resolveHomeDir(), ".engram");
6753
- var PID_FILE = path17.join(PID_DIR, "server.pid");
6754
- var LEGACY_PID_FILE = path17.join(LEGACY_PID_DIR, "server.pid");
6755
- var LOG_FILE = path17.join(PID_DIR, "server.log");
6756
- var LEGACY_LOG_FILE = path17.join(LEGACY_PID_DIR, "server.log");
6757
- var CLI_MODULE_DIR = path17.dirname(fileURLToPath5(import.meta.url));
6758
- var CLI_REPO_ROOT = path17.resolve(CLI_MODULE_DIR, "../../..");
6759
- var EVAL_RUNNER_PATH = path17.join(CLI_REPO_ROOT, "evals", "run.ts");
6948
+ var PID_DIR = path18.join(resolveHomeDir(), ".remnic");
6949
+ var LEGACY_PID_DIR = path18.join(resolveHomeDir(), ".engram");
6950
+ var PID_FILE = path18.join(PID_DIR, "server.pid");
6951
+ var LEGACY_PID_FILE = path18.join(LEGACY_PID_DIR, "server.pid");
6952
+ var LOG_FILE = path18.join(PID_DIR, "server.log");
6953
+ var LEGACY_LOG_FILE = path18.join(LEGACY_PID_DIR, "server.log");
6954
+ var CLI_MODULE_DIR = path18.dirname(fileURLToPath5(import.meta.url));
6955
+ var CLI_REPO_ROOT = path18.resolve(CLI_MODULE_DIR, "../../..");
6956
+ var EVAL_RUNNER_PATH = path18.join(CLI_REPO_ROOT, "evals", "run.ts");
6760
6957
  var OPENCLAW_GATEWAY_LABEL = "ai.openclaw.gateway";
6761
6958
  var CLI_SUCCESS_EXIT_GRACE_MS = 5e3;
6762
6959
  var CLI_OUTPUT_FLUSH_GRACE_MS = 250;
@@ -6921,7 +7118,7 @@ async function resolveAllBenchmarks() {
6921
7118
  if (packageBenchmarks) {
6922
7119
  return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
6923
7120
  }
6924
- if (!fs14.existsSync(EVAL_RUNNER_PATH)) {
7121
+ if (!fs15.existsSync(EVAL_RUNNER_PATH)) {
6925
7122
  return [];
6926
7123
  }
6927
7124
  return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
@@ -6969,17 +7166,17 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
6969
7166
  `Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
6970
7167
  );
6971
7168
  }
6972
- if (!fs14.existsSync(EVAL_RUNNER_PATH)) {
7169
+ if (!fs15.existsSync(EVAL_RUNNER_PATH)) {
6973
7170
  console.error(
6974
7171
  "Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
6975
7172
  );
6976
7173
  process.exit(1);
6977
7174
  }
6978
7175
  const tsxCandidates = [
6979
- path17.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
6980
- path17.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
7176
+ path18.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
7177
+ path18.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
6981
7178
  ];
6982
- const tsxCmd = tsxCandidates.find((candidate) => fs14.existsSync(candidate)) ?? "tsx";
7179
+ const tsxCmd = tsxCandidates.find((candidate) => fs15.existsSync(candidate)) ?? "tsx";
6983
7180
  const fallbackOutputDir = createFallbackBenchOutputDir(
6984
7181
  parsed.resultsDir ?? resolveBenchOutputDir(),
6985
7182
  benchmarkId,
@@ -6996,7 +7193,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
6996
7193
  return resolveFallbackBenchResultPath(fallbackOutputDir);
6997
7194
  }
6998
7195
  function resolveBenchOutputDir() {
6999
- return path17.join(resolveHomeDir(), ".remnic", "bench", "results");
7196
+ return path18.join(resolveHomeDir(), ".remnic", "bench", "results");
7000
7197
  }
7001
7198
  var DOWNLOADABLE_BENCHMARK_DATASETS = [
7002
7199
  "ama-bench",
@@ -7041,8 +7238,8 @@ var MEMORY_AGENT_BENCH_SPLIT_FILENAMES = [
7041
7238
  ];
7042
7239
  var MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES = [
7043
7240
  "entity2id.json",
7044
- path17.join("processed_data", "Recsys_Redial", "entity2id.json"),
7045
- path17.join("Recsys_Redial", "entity2id.json")
7241
+ path18.join("processed_data", "Recsys_Redial", "entity2id.json"),
7242
+ path18.join("Recsys_Redial", "entity2id.json")
7046
7243
  ];
7047
7244
  var DOWNLOADED_DATASET_MARKERS = {
7048
7245
  "ama-bench": { anyOf: ["open_end_qa_set.jsonl"] },
@@ -7117,18 +7314,18 @@ var PERSONAMEM_DATASET_FILE_CANDIDATES = [
7117
7314
  "benchmark/benchmark.csv",
7118
7315
  "benchmark.csv"
7119
7316
  ];
7120
- var PERSONAMEM_COMPLETION_MARKER = path17.join(
7317
+ var PERSONAMEM_COMPLETION_MARKER = path18.join(
7121
7318
  "data",
7122
7319
  "chat_history_32k",
7123
7320
  ".download-complete"
7124
7321
  );
7125
7322
  function resolveRealpathWithinDataset(datasetPath, relativePath) {
7126
7323
  try {
7127
- const datasetRoot = fs14.realpathSync(datasetPath);
7128
- const candidatePath = path17.resolve(datasetRoot, relativePath);
7129
- const candidateRealPath = fs14.realpathSync(candidatePath);
7130
- const relativeToRoot = path17.relative(datasetRoot, candidateRealPath);
7131
- if (relativeToRoot.startsWith("..") || path17.isAbsolute(relativeToRoot)) {
7324
+ const datasetRoot = fs15.realpathSync(datasetPath);
7325
+ const candidatePath = path18.resolve(datasetRoot, relativePath);
7326
+ const candidateRealPath = fs15.realpathSync(candidatePath);
7327
+ const relativeToRoot = path18.relative(datasetRoot, candidateRealPath);
7328
+ if (relativeToRoot.startsWith("..") || path18.isAbsolute(relativeToRoot)) {
7132
7329
  return null;
7133
7330
  }
7134
7331
  return candidateRealPath;
@@ -7184,15 +7381,15 @@ function parseCsvRows(raw) {
7184
7381
  }
7185
7382
  function isPersonaMemDatasetComplete(datasetPath) {
7186
7383
  try {
7187
- const completionMarkerPath = path17.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
7188
- if (fs14.statSync(completionMarkerPath).isFile()) {
7384
+ const completionMarkerPath = path18.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
7385
+ if (fs15.statSync(completionMarkerPath).isFile()) {
7189
7386
  return true;
7190
7387
  }
7191
7388
  } catch {
7192
7389
  }
7193
7390
  const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
7194
7391
  try {
7195
- return fs14.statSync(path17.join(datasetPath, candidate)).isFile();
7392
+ return fs15.statSync(path18.join(datasetPath, candidate)).isFile();
7196
7393
  } catch {
7197
7394
  return false;
7198
7395
  }
@@ -7201,7 +7398,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
7201
7398
  return false;
7202
7399
  }
7203
7400
  try {
7204
- const rows = parseCsvRows(fs14.readFileSync(path17.join(datasetPath, datasetFile), "utf8"));
7401
+ const rows = parseCsvRows(fs15.readFileSync(path18.join(datasetPath, datasetFile), "utf8"));
7205
7402
  if (rows.length < 2) {
7206
7403
  return false;
7207
7404
  }
@@ -7216,7 +7413,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
7216
7413
  }
7217
7414
  return historyPaths.every((relativePath) => {
7218
7415
  const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
7219
- return resolvedPath !== null && fs14.statSync(resolvedPath).isFile();
7416
+ return resolvedPath !== null && fs15.statSync(resolvedPath).isFile();
7220
7417
  });
7221
7418
  } catch {
7222
7419
  return false;
@@ -7224,14 +7421,14 @@ function isPersonaMemDatasetComplete(datasetPath) {
7224
7421
  }
7225
7422
  function hasDatasetFile(datasetPath, relativePath) {
7226
7423
  try {
7227
- return fs14.statSync(path17.join(datasetPath, relativePath)).isFile();
7424
+ return fs15.statSync(path18.join(datasetPath, relativePath)).isFile();
7228
7425
  } catch {
7229
7426
  return false;
7230
7427
  }
7231
7428
  }
7232
7429
  function hasMemoryAgentBenchEntityMapping(datasetPath) {
7233
- const absoluteDatasetPath = path17.resolve(datasetPath);
7234
- const roots = [absoluteDatasetPath, path17.dirname(absoluteDatasetPath)];
7430
+ const absoluteDatasetPath = path18.resolve(datasetPath);
7431
+ const roots = [absoluteDatasetPath, path18.dirname(absoluteDatasetPath)];
7235
7432
  return hasDatasetFile(absoluteDatasetPath, "entity2id.json") || roots.some(
7236
7433
  (root) => MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES.filter((relativePath) => relativePath !== "entity2id.json").some((relativePath) => hasDatasetFile(root, relativePath))
7237
7434
  );
@@ -7242,12 +7439,12 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
7242
7439
  ...MEMORY_AGENT_BENCH_SPLIT_FILENAMES
7243
7440
  ];
7244
7441
  return candidateFilenames.some((filename) => {
7245
- const filePath = path17.join(datasetPath, filename);
7442
+ const filePath = path18.join(datasetPath, filename);
7246
7443
  try {
7247
- if (!fs14.statSync(filePath).isFile()) {
7444
+ if (!fs15.statSync(filePath).isFile()) {
7248
7445
  return false;
7249
7446
  }
7250
- const raw = fs14.readFileSync(filePath, "utf8");
7447
+ const raw = fs15.readFileSync(filePath, "utf8");
7251
7448
  return /"source"\s*:\s*"recsys[_-]/i.test(raw);
7252
7449
  } catch {
7253
7450
  return false;
@@ -7263,7 +7460,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
7263
7460
  function isDatasetDownloaded(datasetPath, benchmarkId) {
7264
7461
  let stats;
7265
7462
  try {
7266
- stats = fs14.statSync(datasetPath);
7463
+ stats = fs15.statSync(datasetPath);
7267
7464
  } catch {
7268
7465
  return false;
7269
7466
  }
@@ -7273,7 +7470,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7273
7470
  const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
7274
7471
  if (!marker) {
7275
7472
  try {
7276
- return fs14.readdirSync(datasetPath).length > 0;
7473
+ return fs15.readdirSync(datasetPath).length > 0;
7277
7474
  } catch {
7278
7475
  return false;
7279
7476
  }
@@ -7281,7 +7478,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7281
7478
  if (marker.allOf) {
7282
7479
  const hasAllRequiredFiles = marker.allOf.every((name) => {
7283
7480
  try {
7284
- return fs14.statSync(path17.join(datasetPath, name)).isFile();
7481
+ return fs15.statSync(path18.join(datasetPath, name)).isFile();
7285
7482
  } catch {
7286
7483
  return false;
7287
7484
  }
@@ -7293,7 +7490,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7293
7490
  if (marker.anyOf) {
7294
7491
  const hasMarkerFile = marker.anyOf.some((name) => {
7295
7492
  try {
7296
- return fs14.statSync(path17.join(datasetPath, name)).isFile();
7493
+ return fs15.statSync(path18.join(datasetPath, name)).isFile();
7297
7494
  } catch {
7298
7495
  return false;
7299
7496
  }
@@ -7311,7 +7508,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7311
7508
  }
7312
7509
  if (marker.ext) {
7313
7510
  try {
7314
- return fs14.readdirSync(datasetPath).some(
7511
+ return fs15.readdirSync(datasetPath).some(
7315
7512
  (name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
7316
7513
  );
7317
7514
  } catch {
@@ -7321,9 +7518,9 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7321
7518
  return false;
7322
7519
  }
7323
7520
  async function launchBenchUi(resultsDir) {
7324
- const benchUiDir = path17.join(CLI_REPO_ROOT, "packages", "bench-ui");
7521
+ const benchUiDir = path18.join(CLI_REPO_ROOT, "packages", "bench-ui");
7325
7522
  const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
7326
- if (!fs14.existsSync(path17.join(benchUiDir, "package.json"))) {
7523
+ if (!fs15.existsSync(path18.join(benchUiDir, "package.json"))) {
7327
7524
  console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
7328
7525
  process.exit(1);
7329
7526
  }
@@ -7350,24 +7547,24 @@ async function launchBenchUi(resultsDir) {
7350
7547
  });
7351
7548
  }
7352
7549
  function resolveRepoDatasetRoot() {
7353
- const repoCandidate = path17.join(CLI_REPO_ROOT, "evals", "datasets");
7550
+ const repoCandidate = path18.join(CLI_REPO_ROOT, "evals", "datasets");
7354
7551
  if (isRepoCheckout()) {
7355
7552
  return repoCandidate;
7356
7553
  }
7357
- return path17.join(resolveHomeDir(), ".remnic", "bench", "datasets");
7554
+ return path18.join(resolveHomeDir(), ".remnic", "bench", "datasets");
7358
7555
  }
7359
7556
  function listDownloadableBenchmarks() {
7360
7557
  return [...DOWNLOADABLE_BENCHMARK_DATASETS];
7361
7558
  }
7362
7559
  function resolveDatasetDownloadScriptPath() {
7363
- const bundled = path17.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
7364
- if (fs14.existsSync(bundled)) {
7560
+ const bundled = path18.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
7561
+ if (fs15.existsSync(bundled)) {
7365
7562
  return bundled;
7366
7563
  }
7367
- return path17.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
7564
+ return path18.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
7368
7565
  }
7369
7566
  function isRepoCheckout() {
7370
- return fs14.existsSync(path17.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs14.existsSync(path17.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
7567
+ return fs15.existsSync(path18.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs15.existsSync(path18.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
7371
7568
  }
7372
7569
  function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
7373
7570
  const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
@@ -7418,7 +7615,7 @@ function resolveBenchDatasetDir(benchmarkId, quick, datasetDirOverride) {
7418
7615
  if (quick) {
7419
7616
  return void 0;
7420
7617
  }
7421
- const datasetDir = path17.join(resolveRepoDatasetRoot(), benchmarkId);
7618
+ const datasetDir = path18.join(resolveRepoDatasetRoot(), benchmarkId);
7422
7619
  if (isDatasetDownloaded(datasetDir, benchmarkId)) {
7423
7620
  return datasetDir;
7424
7621
  }
@@ -7675,13 +7872,13 @@ async function exportBenchPackageResult(parsed) {
7675
7872
  process.exit(1);
7676
7873
  }
7677
7874
  const result = await loadBenchmarkResult(summary.path);
7678
- const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path17.dirname(summary.path), result.meta.id) : void 0;
7875
+ const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path18.dirname(summary.path), result.meta.id) : void 0;
7679
7876
  const rendered = renderBenchmarkResultExport(result, parsed.format, {
7680
7877
  ...reportCardProvenance ? { reportCardProvenance } : {}
7681
7878
  });
7682
7879
  if (parsed.output) {
7683
- fs14.mkdirSync(path17.dirname(parsed.output), { recursive: true });
7684
- fs14.writeFileSync(parsed.output, rendered);
7880
+ fs15.mkdirSync(path18.dirname(parsed.output), { recursive: true });
7881
+ fs15.writeFileSync(parsed.output, rendered);
7685
7882
  console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
7686
7883
  return;
7687
7884
  }
@@ -7698,7 +7895,7 @@ async function manageBenchDatasets(parsed) {
7698
7895
  process.exit(1);
7699
7896
  }
7700
7897
  const status = supported.map((benchmarkId) => {
7701
- const datasetPath = path17.join(datasetRoot, benchmarkId);
7898
+ const datasetPath = path18.join(datasetRoot, benchmarkId);
7702
7899
  return {
7703
7900
  benchmark: benchmarkId,
7704
7901
  downloaded: isDatasetDownloaded(datasetPath, benchmarkId),
@@ -7726,7 +7923,7 @@ async function manageBenchDatasets(parsed) {
7726
7923
  process.exit(1);
7727
7924
  }
7728
7925
  const scriptPath = resolveDatasetDownloadScriptPath();
7729
- if (!fs14.existsSync(scriptPath)) {
7926
+ if (!fs15.existsSync(scriptPath)) {
7730
7927
  console.error(`ERROR: dataset download script not found: ${scriptPath}`);
7731
7928
  process.exit(1);
7732
7929
  }
@@ -7736,7 +7933,7 @@ async function manageBenchDatasets(parsed) {
7736
7933
  runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, parsed.json === true);
7737
7934
  downloaded.push({
7738
7935
  benchmark: benchmarkId,
7739
- path: path17.join(datasetRoot, benchmarkId)
7936
+ path: path18.join(datasetRoot, benchmarkId)
7740
7937
  });
7741
7938
  }
7742
7939
  if (parsed.json) {
@@ -7875,10 +8072,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
7875
8072
  }
7876
8073
  const bench = await loadBenchModule();
7877
8074
  const resultsDir = expandTilde(
7878
- parsed.resultsDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "results")
8075
+ parsed.resultsDir ?? path18.join(resolveHomeDir(), ".remnic", "bench", "results")
7879
8076
  );
7880
8077
  const calibrationDir = expandTilde(
7881
- parsed.calibrationDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "calibration")
8078
+ parsed.calibrationDir ?? path18.join(resolveHomeDir(), ".remnic", "bench", "calibration")
7882
8079
  );
7883
8080
  const stored = await bench.listBenchmarkResults(resultsDir);
7884
8081
  const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
@@ -7926,7 +8123,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
7926
8123
  );
7927
8124
  process.exit(1);
7928
8125
  }
7929
- const sourceResultSha256 = createHash4("sha256").update(fs14.readFileSync(latest.path)).digest("hex");
8126
+ const sourceResultSha256 = createHash4("sha256").update(fs15.readFileSync(latest.path)).digest("hex");
7930
8127
  const expandedManifestPath = expandTilde(manifestPath);
7931
8128
  if (!bench.resolveLocalLabJudgeProviderConfig) {
7932
8129
  console.error(
@@ -8341,7 +8538,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
8341
8538
  }
8342
8539
  let decoded;
8343
8540
  try {
8344
- decoded = JSON.parse(fs14.readFileSync(parsed.taskIdsFile, "utf8"));
8541
+ decoded = JSON.parse(fs15.readFileSync(parsed.taskIdsFile, "utf8"));
8345
8542
  } catch (error) {
8346
8543
  throw new Error(
8347
8544
  `Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
@@ -8438,7 +8635,7 @@ async function loadPublishedPromotionHelpers() {
8438
8635
  return {
8439
8636
  async promoteArtifactsToPublished(args) {
8440
8637
  const { mkdirSync, readFileSync: readFileSync4, writeFileSync } = await import("fs");
8441
- const path18 = await import("path");
8638
+ const path19 = await import("path");
8442
8639
  mkdirSync(args.publishedOutDir, { recursive: true });
8443
8640
  if (args.artifactPaths.length === 0) {
8444
8641
  console.warn(
@@ -8455,13 +8652,13 @@ async function loadPublishedPromotionHelpers() {
8455
8652
  const modelSlug = args.model.replace(/[^a-zA-Z0-9_.-]/g, "-");
8456
8653
  const rawProfile = parsedObj.config?.runtimeProfile;
8457
8654
  const profileSlug = typeof rawProfile === "string" && rawProfile.length > 0 ? `-${rawProfile.replace(/[^a-zA-Z0-9_.-]/g, "-")}` : "";
8458
- const target = path18.join(
8655
+ const target = path19.join(
8459
8656
  args.publishedOutDir,
8460
8657
  `${today}-${args.benchmarkId}-${modelSlug}${profileSlug}-${gitShaShort}.json`
8461
8658
  );
8462
8659
  writeFileSync(target, raw, "utf8");
8463
8660
  console.log(
8464
- `[bench published] Promoted ${path18.basename(artifactPath)} \u2192 ${target}`
8661
+ `[bench published] Promoted ${path19.basename(artifactPath)} \u2192 ${target}`
8465
8662
  );
8466
8663
  }
8467
8664
  void benchModule;
@@ -8568,7 +8765,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
8568
8765
  const previousCodexDiagnosticsDir = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV];
8569
8766
  const previousCodexDiagnosticsMode = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_MODE_ENV];
8570
8767
  if (!previousCodexDiagnosticsDir) {
8571
- process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path17.join(
8768
+ process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path18.join(
8572
8769
  outputDir,
8573
8770
  "codex-cli-diagnostics"
8574
8771
  );
@@ -8718,7 +8915,7 @@ async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmark
8718
8915
  );
8719
8916
  }
8720
8917
  const calibrationDir = expandTilde(
8721
- calibrationBinding.calibrationDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "calibration")
8918
+ calibrationBinding.calibrationDir ?? path18.join(resolveHomeDir(), ".remnic", "bench", "calibration")
8722
8919
  );
8723
8920
  const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
8724
8921
  if (!state) {
@@ -9016,7 +9213,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
9016
9213
  return void 0;
9017
9214
  }
9018
9215
  try {
9019
- return fs14.realpathSync(datasetDir);
9216
+ return fs15.realpathSync(datasetDir);
9020
9217
  } catch {
9021
9218
  return datasetDir;
9022
9219
  }
@@ -9070,13 +9267,13 @@ async function writeBenchReproManifestForPackageRun(args) {
9070
9267
  }
9071
9268
  function loadStandaloneConvergeCommandConfig() {
9072
9269
  const configPath = resolveConfigPath();
9073
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
9074
- return parseConfig6(resolveRemnicConfigRecord5(raw));
9270
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
9271
+ return parseConfig7(resolveRemnicConfigRecord6(raw));
9075
9272
  }
9076
9273
  function parseConvergePluginConfig(value) {
9077
9274
  if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
9078
9275
  if (Object.keys(value).length === 0) return void 0;
9079
- return parseConfig6(resolveRemnicConfigRecord5(value));
9276
+ return parseConfig7(resolveRemnicConfigRecord6(value));
9080
9277
  }
9081
9278
  function loadConvergeCommandConfig() {
9082
9279
  if (readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH")) {
@@ -9089,23 +9286,23 @@ function loadConvergeCommandConfig() {
9089
9286
  return loadStandaloneConvergeCommandConfig();
9090
9287
  }
9091
9288
  function resolveConfigPath(cliPath) {
9092
- if (cliPath) return path17.resolve(expandTilde(cliPath));
9289
+ if (cliPath) return path18.resolve(expandTilde(cliPath));
9093
9290
  const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
9094
- if (envPath) return path17.resolve(expandTilde(envPath));
9291
+ if (envPath) return path18.resolve(expandTilde(envPath));
9095
9292
  const candidates = [
9096
- path17.join(process.cwd(), "remnic.config.json"),
9097
- path17.join(process.cwd(), "engram.config.json"),
9098
- path17.join(resolveHomeDir(), ".config", "remnic", "config.json"),
9099
- path17.join(resolveHomeDir(), ".config", "engram", "config.json")
9293
+ path18.join(process.cwd(), "remnic.config.json"),
9294
+ path18.join(process.cwd(), "engram.config.json"),
9295
+ path18.join(resolveHomeDir(), ".config", "remnic", "config.json"),
9296
+ path18.join(resolveHomeDir(), ".config", "engram", "config.json")
9100
9297
  ];
9101
9298
  for (const candidate of candidates) {
9102
- if (fs14.existsSync(candidate)) return candidate;
9299
+ if (fs15.existsSync(candidate)) return candidate;
9103
9300
  }
9104
- return path17.join(resolveHomeDir(), ".config", "remnic", "config.json");
9301
+ return path18.join(resolveHomeDir(), ".config", "remnic", "config.json");
9105
9302
  }
9106
9303
  function resolveExistingBenchRemnicConfigPath(cliPath) {
9107
9304
  const configPath = resolveConfigPath(cliPath);
9108
- if (fs14.existsSync(configPath)) {
9305
+ if (fs15.existsSync(configPath)) {
9109
9306
  return configPath;
9110
9307
  }
9111
9308
  if (cliPath) {
@@ -9115,7 +9312,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
9115
9312
  }
9116
9313
  function resolveExistingBenchOpenclawConfigPath(cliPath) {
9117
9314
  const configPath = resolveOpenclawConfigPath(cliPath);
9118
- if (fs14.existsSync(configPath)) {
9315
+ if (fs15.existsSync(configPath)) {
9119
9316
  return configPath;
9120
9317
  }
9121
9318
  if (cliPath) {
@@ -9215,34 +9412,34 @@ async function resolvePackageBenchRuntime(benchModule, parsed, runtimeProfile) {
9215
9412
  );
9216
9413
  }
9217
9414
  function normalizeMemoryDirPath(memoryDir) {
9218
- return path17.resolve(expandTilde(memoryDir));
9415
+ return path18.resolve(expandTilde(memoryDir));
9219
9416
  }
9220
9417
  function resolveMemoryDir() {
9221
9418
  const configMemoryDir = (() => {
9222
9419
  const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
9223
9420
  if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
9224
9421
  const configPath = resolveConfigPath();
9225
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
9226
- const remnicCfg = resolveRemnicConfigRecord5(raw);
9422
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
9423
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
9227
9424
  if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
9228
9425
  return normalizeMemoryDirPath(remnicCfg.memoryDir);
9229
9426
  }
9230
9427
  const home = resolveHomeDir();
9231
- const standalonePath = path17.join(home, ".remnic", "memory");
9232
- const legacyStandalonePath = path17.join(home, ".engram", "memory");
9233
- const openclawPath = path17.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
9234
- if (fs14.existsSync(standalonePath)) return standalonePath;
9235
- if (fs14.existsSync(legacyStandalonePath)) return legacyStandalonePath;
9428
+ const standalonePath = path18.join(home, ".remnic", "memory");
9429
+ const legacyStandalonePath = path18.join(home, ".engram", "memory");
9430
+ const openclawPath = path18.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
9431
+ if (fs15.existsSync(standalonePath)) return standalonePath;
9432
+ if (fs15.existsSync(legacyStandalonePath)) return legacyStandalonePath;
9236
9433
  return openclawPath;
9237
9434
  })();
9238
9435
  const manifestPath = getManifestPath();
9239
- if (fs14.existsSync(manifestPath)) {
9436
+ if (fs15.existsSync(manifestPath)) {
9240
9437
  try {
9241
9438
  const active = getActiveSpace();
9242
9439
  if (active?.memoryDir) {
9243
9440
  const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
9244
- if (!fs14.existsSync(activeMemoryDir)) {
9245
- fs14.mkdirSync(activeMemoryDir, { recursive: true });
9441
+ if (!fs15.existsSync(activeMemoryDir)) {
9442
+ fs15.mkdirSync(activeMemoryDir, { recursive: true });
9246
9443
  }
9247
9444
  return activeMemoryDir;
9248
9445
  }
@@ -9279,25 +9476,25 @@ function resolveFlagStrict(args, flag) {
9279
9476
  var REMNIC_OPENCLAW_LEGACY_PLUGIN_ID = "openclaw-engram";
9280
9477
  function resolveOpenclawStateDir() {
9281
9478
  const configuredStateDir = process.env.OPENCLAW_STATE_DIR?.trim();
9282
- return configuredStateDir ? path17.resolve(expandTilde(configuredStateDir)) : path17.join(resolveHomeDir(), ".openclaw");
9479
+ return configuredStateDir ? path18.resolve(expandTilde(configuredStateDir)) : path18.join(resolveHomeDir(), ".openclaw");
9283
9480
  }
9284
9481
  var DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR = [
9285
9482
  process.env.OPENCLAW_CONFIG_PATH,
9286
9483
  process.env.OPENCLAW_ENGRAM_CONFIG_PATH,
9287
- path17.join(resolveOpenclawStateDir(), "openclaw.json")
9484
+ path18.join(resolveOpenclawStateDir(), "openclaw.json")
9288
9485
  ].filter(Boolean);
9289
9486
  function resolveOpenclawConfigPath(cliPath) {
9290
- if (cliPath) return path17.resolve(expandTilde(cliPath));
9487
+ if (cliPath) return path18.resolve(expandTilde(cliPath));
9291
9488
  const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
9292
- if (envPath) return path17.resolve(expandTilde(envPath));
9489
+ if (envPath) return path18.resolve(expandTilde(envPath));
9293
9490
  for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
9294
- if (fs14.existsSync(candidate)) return candidate;
9491
+ if (fs15.existsSync(candidate)) return candidate;
9295
9492
  }
9296
- return path17.join(resolveOpenclawStateDir(), "openclaw.json");
9493
+ return path18.join(resolveOpenclawStateDir(), "openclaw.json");
9297
9494
  }
9298
9495
  function readOpenclawConfig(configPath) {
9299
- if (!fs14.existsSync(configPath)) return {};
9300
- const raw = fs14.readFileSync(configPath, "utf-8");
9496
+ if (!fs15.existsSync(configPath)) return {};
9497
+ const raw = fs15.readFileSync(configPath, "utf-8");
9301
9498
  let parsed;
9302
9499
  try {
9303
9500
  parsed = JSON.parse(raw);
@@ -9352,10 +9549,10 @@ function buildRemnicOpenclawHooksPolicy(legacyHooks, existingHooks) {
9352
9549
  function resolveOpenclawInstallMemoryDir(args) {
9353
9550
  const existingMemoryDir = (typeof args.existingNewEntryConfig.memoryDir === "string" ? args.existingNewEntryConfig.memoryDir : void 0) || (args.migrateLegacy && typeof args.legacyConfigToMerge.memoryDir === "string" ? args.legacyConfigToMerge.memoryDir : void 0);
9354
9551
  if (args.requestedMemoryDir) {
9355
- return path17.resolve(expandTilde(args.requestedMemoryDir));
9552
+ return path18.resolve(expandTilde(args.requestedMemoryDir));
9356
9553
  }
9357
9554
  if (existingMemoryDir) {
9358
- return path17.resolve(expandTilde(existingMemoryDir));
9555
+ return path18.resolve(expandTilde(existingMemoryDir));
9359
9556
  }
9360
9557
  return args.fallbackMemoryDir;
9361
9558
  }
@@ -9373,21 +9570,21 @@ function resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir) {
9373
9570
  if (!config || typeof config !== "object" || Array.isArray(config)) continue;
9374
9571
  const memoryDir = config.memoryDir;
9375
9572
  if (typeof memoryDir === "string" && memoryDir.trim().length > 0) {
9376
- return path17.resolve(expandTilde(memoryDir));
9573
+ return path18.resolve(expandTilde(memoryDir));
9377
9574
  }
9378
9575
  }
9379
9576
  return fallbackMemoryDir;
9380
9577
  }
9381
9578
  function resolveOpenclawPluginDir(cliPath) {
9382
- if (cliPath) return path17.resolve(expandTilde(cliPath));
9579
+ if (cliPath) return path18.resolve(expandTilde(cliPath));
9383
9580
  return resolveOpenclawManagedPluginDir();
9384
9581
  }
9385
9582
  function resolveOpenclawManagedPluginDir() {
9386
- return path17.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
9583
+ return path18.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
9387
9584
  }
9388
9585
  function resolveOpenclawLegacyPluginDir(cliPath) {
9389
- if (cliPath) return path17.resolve(expandTilde(cliPath));
9390
- return path17.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
9586
+ if (cliPath) return path18.resolve(expandTilde(cliPath));
9587
+ return path18.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
9391
9588
  }
9392
9589
  function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
9393
9590
  const yyyy = now.getFullYear().toString();
@@ -9399,9 +9596,9 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
9399
9596
  return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
9400
9597
  }
9401
9598
  function backupPathIfPresent(sourcePath, backupPath) {
9402
- if (!fs14.existsSync(sourcePath)) return false;
9403
- fs14.mkdirSync(path17.dirname(backupPath), { recursive: true });
9404
- fs14.cpSync(sourcePath, backupPath, { recursive: true });
9599
+ if (!fs15.existsSync(sourcePath)) return false;
9600
+ fs15.mkdirSync(path18.dirname(backupPath), { recursive: true });
9601
+ fs15.cpSync(sourcePath, backupPath, { recursive: true });
9405
9602
  return true;
9406
9603
  }
9407
9604
  function restartOpenclawGateway() {
@@ -9419,15 +9616,15 @@ function restartOpenclawGateway() {
9419
9616
  });
9420
9617
  }
9421
9618
  function cmdInit() {
9422
- const configPath = path17.join(process.cwd(), "remnic.config.json");
9423
- if (fs14.existsSync(configPath)) {
9619
+ const configPath = path18.join(process.cwd(), "remnic.config.json");
9620
+ if (fs15.existsSync(configPath)) {
9424
9621
  console.log(`Config already exists: ${configPath}`);
9425
9622
  return;
9426
9623
  }
9427
9624
  const template = {
9428
9625
  remnic: {
9429
9626
  openaiApiKey: "${OPENAI_API_KEY}",
9430
- memoryDir: path17.join(process.cwd(), ".remnic", "memory"),
9627
+ memoryDir: path18.join(process.cwd(), ".remnic", "memory"),
9431
9628
  memoryOsPreset: "balanced"
9432
9629
  },
9433
9630
  server: {
@@ -9436,7 +9633,7 @@ function cmdInit() {
9436
9633
  authToken: "${REMNIC_AUTH_TOKEN}"
9437
9634
  }
9438
9635
  };
9439
- fs14.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
9636
+ fs15.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
9440
9637
  console.log(`Created ${configPath}`);
9441
9638
  console.log("\nSet these environment variables:");
9442
9639
  console.log(" export OPENAI_API_KEY=sk-...");
@@ -9506,7 +9703,7 @@ async function cmdStatus(json) {
9506
9703
  }
9507
9704
  function oauthReadConfigRecord(configPath) {
9508
9705
  try {
9509
- const parsed = JSON.parse(fs14.readFileSync(configPath, "utf8"));
9706
+ const parsed = JSON.parse(fs15.readFileSync(configPath, "utf8"));
9510
9707
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
9511
9708
  return parsed;
9512
9709
  }
@@ -9564,7 +9761,7 @@ function oauthResolveOperatorToken() {
9564
9761
  }
9565
9762
  return void 0;
9566
9763
  }
9567
- async function oauthFetch(method, path18, token, body) {
9764
+ async function oauthFetch(method, path19, token, body) {
9568
9765
  const controller = new AbortController();
9569
9766
  const timeoutId = setTimeout(() => controller.abort(), 5e3);
9570
9767
  try {
@@ -9583,7 +9780,7 @@ async function oauthFetch(method, path18, token, body) {
9583
9780
  if (body !== void 0) {
9584
9781
  init.body = JSON.stringify(body);
9585
9782
  }
9586
- const response = await fetch(`${oauthResolveBaseUrl()}${path18}`, init);
9783
+ const response = await fetch(`${oauthResolveBaseUrl()}${path19}`, init);
9587
9784
  if (response.status === 401) {
9588
9785
  throw new Error(
9589
9786
  "operator token rejected by remnic-server (HTTP 401). Update `server.authToken` or `REMNIC_AUTH_TOKEN` to match the running daemon."
@@ -9920,12 +10117,12 @@ async function cmdQuery(queryText, json, explain) {
9920
10117
  console.error("Usage: remnic query <text>");
9921
10118
  process.exit(1);
9922
10119
  }
9923
- initLogger2();
10120
+ initLogger3();
9924
10121
  const configPath = resolveConfigPath();
9925
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
9926
- const remnicCfg = resolveRemnicConfigRecord5(raw);
9927
- const config = parseConfig6(remnicCfg);
9928
- const orchestrator = new Orchestrator3(config);
10122
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10123
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10124
+ const config = parseConfig7(remnicCfg);
10125
+ const orchestrator = new Orchestrator4(config);
9929
10126
  await orchestrator.initialize();
9930
10127
  const service = new EngramAccessService2(orchestrator);
9931
10128
  const recallRequest = buildQueryRecallRequest(queryText);
@@ -10091,12 +10288,12 @@ async function runXrayCommand(rest, io) {
10091
10288
  async function cmdXray(rest) {
10092
10289
  const { rawQuery, options } = extractXrayRawArgs(rest);
10093
10290
  parseXrayCliOptions(rawQuery, options);
10094
- initLogger2();
10291
+ initLogger3();
10095
10292
  const configPath = resolveConfigPath();
10096
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10097
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10098
- const config = parseConfig6(remnicCfg);
10099
- const orchestrator = new Orchestrator3(config);
10293
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10294
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10295
+ const config = parseConfig7(remnicCfg);
10296
+ const orchestrator = new Orchestrator4(config);
10100
10297
  await orchestrator.initialize();
10101
10298
  await orchestrator.deferredReady;
10102
10299
  const service = new EngramAccessService2(orchestrator);
@@ -10114,11 +10311,11 @@ async function cmdXray(rest) {
10114
10311
  }
10115
10312
  }
10116
10313
  async function cmdVersions(rest) {
10117
- initLogger2();
10314
+ initLogger3();
10118
10315
  const configPath = resolveConfigPath();
10119
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10120
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10121
- const config = parseConfig6(remnicCfg);
10316
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10317
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10318
+ const config = parseConfig7(remnicCfg);
10122
10319
  if (!config.versioningEnabled) {
10123
10320
  console.error("Page versioning is disabled (versioningEnabled = false).");
10124
10321
  process.exit(1);
@@ -10138,7 +10335,7 @@ async function cmdVersions(rest) {
10138
10335
  console.error("Usage: remnic versions list <page-path>");
10139
10336
  process.exit(1);
10140
10337
  }
10141
- const absPath = path17.resolve(pagePath);
10338
+ const absPath = path18.resolve(pagePath);
10142
10339
  const history = await listVersions(absPath, versioningConfig, memDir);
10143
10340
  if (json) {
10144
10341
  console.log(JSON.stringify(history, null, 2));
@@ -10163,7 +10360,7 @@ async function cmdVersions(rest) {
10163
10360
  console.error("Usage: remnic versions show <page-path> <version-id>");
10164
10361
  process.exit(1);
10165
10362
  }
10166
- const absPath = path17.resolve(pagePath);
10363
+ const absPath = path18.resolve(pagePath);
10167
10364
  try {
10168
10365
  const content = await getVersion(absPath, versionId, versioningConfig, memDir);
10169
10366
  console.log(content);
@@ -10181,7 +10378,7 @@ async function cmdVersions(rest) {
10181
10378
  console.error("Usage: remnic versions diff <page-path> <v1> <v2>");
10182
10379
  process.exit(1);
10183
10380
  }
10184
- const absPath = path17.resolve(pagePath);
10381
+ const absPath = path18.resolve(pagePath);
10185
10382
  try {
10186
10383
  const diffOutput = await diffVersions(absPath, v1, v2, versioningConfig, memDir);
10187
10384
  console.log(diffOutput);
@@ -10198,7 +10395,7 @@ async function cmdVersions(rest) {
10198
10395
  console.error("Usage: remnic versions revert <page-path> <version-id>");
10199
10396
  process.exit(1);
10200
10397
  }
10201
- const absPath = path17.resolve(pagePath);
10398
+ const absPath = path18.resolve(pagePath);
10202
10399
  try {
10203
10400
  const version = await revertToVersion(absPath, versionId, versioningConfig, void 0, memDir);
10204
10401
  if (json) {
@@ -10230,15 +10427,15 @@ Options:
10230
10427
  }
10231
10428
  }
10232
10429
  async function cmdEnrich(rest) {
10233
- initLogger2();
10430
+ initLogger3();
10234
10431
  const configPath = resolveConfigPath();
10235
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10236
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10237
- const config = parseConfig6(remnicCfg);
10432
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10433
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10434
+ const config = parseConfig7(remnicCfg);
10238
10435
  const subcommand = rest[0];
10239
10436
  if (subcommand === "audit") {
10240
10437
  const memoryDir2 = expandTilde(config.memoryDir);
10241
- const auditDir2 = path17.join(memoryDir2, "enrichment");
10438
+ const auditDir2 = path18.join(memoryDir2, "enrichment");
10242
10439
  const sinceFlag = resolveFlag(rest.slice(1), "--since");
10243
10440
  const entries = await readAuditLog(auditDir2, sinceFlag ?? void 0);
10244
10441
  if (entries.length === 0) {
@@ -10262,7 +10459,7 @@ async function cmdEnrich(rest) {
10262
10459
  pipelineConfig2.providers = [
10263
10460
  { id: "web-search", enabled: true, costTier: "cheap" }
10264
10461
  ];
10265
- const orchestrator2 = new Orchestrator3(config);
10462
+ const orchestrator2 = new Orchestrator4(config);
10266
10463
  await orchestrator2.initialize();
10267
10464
  await orchestrator2.deferredReady;
10268
10465
  const searchBackend2 = orchestrator2.qmd;
@@ -10298,7 +10495,7 @@ Registered providers:`);
10298
10495
  console.error("Usage: remnic enrich <entity-name> | --all | --dry-run | audit | providers");
10299
10496
  process.exit(1);
10300
10497
  }
10301
- const orchestrator = new Orchestrator3(config);
10498
+ const orchestrator = new Orchestrator4(config);
10302
10499
  await orchestrator.initialize();
10303
10500
  await orchestrator.deferredReady;
10304
10501
  const storage = await orchestrator.getStorage(config.defaultNamespace);
@@ -10363,7 +10560,7 @@ Registered providers:`);
10363
10560
  return;
10364
10561
  }
10365
10562
  const memoryDir = expandTilde(config.memoryDir);
10366
- const auditDir = path17.join(memoryDir, "enrichment");
10563
+ const auditDir = path18.join(memoryDir, "enrichment");
10367
10564
  let totalPersisted = 0;
10368
10565
  for (const result of results) {
10369
10566
  for (const candidate of result.acceptedCandidates) {
@@ -10424,7 +10621,7 @@ Registered providers:`);
10424
10621
  }
10425
10622
  }
10426
10623
  async function cmdProcedural(rest) {
10427
- initLogger2();
10624
+ initLogger3();
10428
10625
  const subcommand = rest[0];
10429
10626
  if (!subcommand || subcommand === "--help" || subcommand === "-h") {
10430
10627
  console.log(`remnic procedural \u2014 Procedural memory operations (issue #567)
@@ -10477,9 +10674,9 @@ Shared with:
10477
10674
  process.exit(1);
10478
10675
  }
10479
10676
  const configPath = resolveConfigPath();
10480
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10481
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10482
- const config = parseConfig6(remnicCfg);
10677
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10678
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10679
+ const config = parseConfig7(remnicCfg);
10483
10680
  const memoryDir = expandTilde(
10484
10681
  typeof memoryDirOverride === "string" && memoryDirOverride.length > 0 ? memoryDirOverride : config.memoryDir ?? resolveMemoryDir()
10485
10682
  );
@@ -10492,11 +10689,11 @@ Shared with:
10492
10689
  process.stdout.write(formatProcedureStatsText(report));
10493
10690
  }
10494
10691
  async function cmdExtensions(action, rest) {
10495
- initLogger2();
10692
+ initLogger3();
10496
10693
  const configPath = resolveConfigPath();
10497
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10498
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10499
- const config = parseConfig6(remnicCfg);
10694
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10695
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10696
+ const config = parseConfig7(remnicCfg);
10500
10697
  const root = resolveExtensionsRoot(config);
10501
10698
  const noopLog = { warn: () => {
10502
10699
  }, debug: () => {
@@ -10545,7 +10742,7 @@ Root: ${root}`);
10545
10742
  const extensions = await discoverMemoryExtensions(root, warnLog);
10546
10743
  let entries = [];
10547
10744
  try {
10548
- entries = fs14.readdirSync(root);
10745
+ entries = fs15.readdirSync(root);
10549
10746
  } catch {
10550
10747
  console.log(`Extensions root does not exist: ${root}`);
10551
10748
  process.exitCode = 0;
@@ -10554,9 +10751,9 @@ Root: ${root}`);
10554
10751
  const validNames = new Set(extensions.map((e) => e.name));
10555
10752
  let errors = 0;
10556
10753
  for (const entry of entries) {
10557
- const entryPath = path17.join(root, entry);
10754
+ const entryPath = path18.join(root, entry);
10558
10755
  try {
10559
- if (!fs14.statSync(entryPath).isDirectory()) continue;
10756
+ if (!fs15.statSync(entryPath).isDirectory()) continue;
10560
10757
  } catch {
10561
10758
  continue;
10562
10759
  }
@@ -10586,11 +10783,11 @@ Root: ${root}`);
10586
10783
  }
10587
10784
  }
10588
10785
  async function cmdBriefing(rest) {
10589
- initLogger2();
10786
+ initLogger3();
10590
10787
  const configPath = resolveConfigPath();
10591
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10592
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10593
- const config = parseConfig6(remnicCfg);
10788
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
10789
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10790
+ const config = parseConfig7(remnicCfg);
10594
10791
  if (!config.briefing.enabled) {
10595
10792
  console.error("Briefing is disabled in config (briefing.enabled = false).");
10596
10793
  process.exit(1);
@@ -10643,7 +10840,7 @@ async function cmdBriefing(rest) {
10643
10840
  process.exit(1);
10644
10841
  }
10645
10842
  const format = effectiveFormatFlag === "json" ? "json" : effectiveFormatFlag === "markdown" ? "markdown" : config.briefing.defaultFormat;
10646
- const orchestrator = new Orchestrator3(config);
10843
+ const orchestrator = new Orchestrator4(config);
10647
10844
  await orchestrator.initialize();
10648
10845
  const storage = await orchestrator.getStorage(config.defaultNamespace);
10649
10846
  const calendarSource = config.briefing.calendarSource ? new FileCalendarSource(config.briefing.calendarSource) : void 0;
@@ -10668,10 +10865,10 @@ async function cmdBriefing(rest) {
10668
10865
  if (save) {
10669
10866
  try {
10670
10867
  const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
10671
- fs14.mkdirSync(saveDir, { recursive: true });
10868
+ fs15.mkdirSync(saveDir, { recursive: true });
10672
10869
  const filename = briefingFilename(new Date(result.window.to), format);
10673
- const filePath = path17.join(saveDir, filename);
10674
- fs14.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
10870
+ const filePath = path18.join(saveDir, filename);
10871
+ fs15.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
10675
10872
  console.error(`Saved briefing: ${filePath}`);
10676
10873
  } catch (err) {
10677
10874
  console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
@@ -10689,7 +10886,7 @@ async function cmdDoctor() {
10689
10886
  detail: `${nodeVersion} (requires >= 22.12.0)`
10690
10887
  });
10691
10888
  const configPath = resolveConfigPath();
10692
- const configExists = fs14.existsSync(configPath);
10889
+ const configExists = fs15.existsSync(configPath);
10693
10890
  checks.push({ name: "Config file", ok: configExists, detail: configPath });
10694
10891
  let standaloneConfig;
10695
10892
  let standaloneConfigError;
@@ -10697,11 +10894,11 @@ async function cmdDoctor() {
10697
10894
  let configuredNs = { invalid: false };
10698
10895
  if (configExists) {
10699
10896
  try {
10700
- const raw = JSON.parse(fs14.readFileSync(configPath, "utf8"));
10701
- const remnicCfg = resolveRemnicConfigRecord5(raw);
10897
+ const raw = JSON.parse(fs15.readFileSync(configPath, "utf8"));
10898
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
10702
10899
  standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
10703
10900
  configuredNs = readConfiguredNamespace(remnicCfg);
10704
- standaloneConfig = parseConfig6(remnicCfg);
10901
+ standaloneConfig = parseConfig7(remnicCfg);
10705
10902
  } catch (err) {
10706
10903
  standaloneConfigError = err instanceof Error ? err.message : String(err);
10707
10904
  }
@@ -10710,10 +10907,10 @@ async function cmdDoctor() {
10710
10907
  try {
10711
10908
  memoryDir = resolveMemoryDir();
10712
10909
  } catch {
10713
- memoryDir = parseConfig6({}).memoryDir;
10910
+ memoryDir = parseConfig7({}).memoryDir;
10714
10911
  }
10715
10912
  try {
10716
- fs14.mkdirSync(memoryDir, { recursive: true });
10913
+ fs15.mkdirSync(memoryDir, { recursive: true });
10717
10914
  checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
10718
10915
  } catch {
10719
10916
  checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
@@ -10742,7 +10939,7 @@ async function cmdDoctor() {
10742
10939
  });
10743
10940
  if (nsPolicyCheck) checks.push(nsPolicyCheck);
10744
10941
  const openclawConfigPath = resolveOpenclawConfigPath();
10745
- const openclawConfigExists = fs14.existsSync(openclawConfigPath);
10942
+ const openclawConfigExists = fs15.existsSync(openclawConfigPath);
10746
10943
  let openclawConfig = {};
10747
10944
  let openclawConfigValid = false;
10748
10945
  let openclawPluginModeConfigured = false;
@@ -10750,7 +10947,7 @@ async function cmdDoctor() {
10750
10947
  let activeOpenclawEntryConfig = null;
10751
10948
  if (openclawConfigExists) {
10752
10949
  try {
10753
- const parsed = JSON.parse(fs14.readFileSync(openclawConfigPath, "utf-8"));
10950
+ const parsed = JSON.parse(fs15.readFileSync(openclawConfigPath, "utf-8"));
10754
10951
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
10755
10952
  openclawConfig = parsed;
10756
10953
  openclawConfigValid = true;
@@ -10826,13 +11023,13 @@ async function cmdDoctor() {
10826
11023
  const rawMemoryDir = entryConfig?.memoryDir;
10827
11024
  const configuredMemoryDir = typeof rawMemoryDir === "string" ? rawMemoryDir : void 0;
10828
11025
  if (configuredMemoryDir) {
10829
- const resolvedMemDir = path17.resolve(expandTilde(configuredMemoryDir));
11026
+ const resolvedMemDir = path18.resolve(expandTilde(configuredMemoryDir));
10830
11027
  let memDirOk = false;
10831
11028
  let memDirDetail = `${resolvedMemDir} (not found)`;
10832
11029
  let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
10833
- if (fs14.existsSync(resolvedMemDir)) {
11030
+ if (fs15.existsSync(resolvedMemDir)) {
10834
11031
  try {
10835
- const stat2 = fs14.statSync(resolvedMemDir);
11032
+ const stat2 = fs15.statSync(resolvedMemDir);
10836
11033
  if (stat2.isDirectory()) {
10837
11034
  memDirOk = true;
10838
11035
  memDirDetail = resolvedMemDir;
@@ -10974,12 +11171,12 @@ async function cmdDoctor() {
10974
11171
  }
10975
11172
  function cmdConfig() {
10976
11173
  const configPath = resolveConfigPath();
10977
- if (!fs14.existsSync(configPath)) {
11174
+ if (!fs15.existsSync(configPath)) {
10978
11175
  console.log("No config file found. Run `remnic init` to create one.");
10979
11176
  return;
10980
11177
  }
10981
11178
  console.log(`Config: ${configPath}`);
10982
- const rawConfig = fs14.readFileSync(configPath, "utf8");
11179
+ const rawConfig = fs15.readFileSync(configPath, "utf8");
10983
11180
  const redacted = rawConfig.replace(
10984
11181
  /("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
10985
11182
  "$1[REDACTED]$3"
@@ -11026,7 +11223,7 @@ async function cmdMigrate(json, rollback) {
11026
11223
  console.log(` Rollback: ${result.rollbackCommand}`);
11027
11224
  }
11028
11225
  function cmdOnboard(dirPath, json) {
11029
- const directory = path17.resolve(dirPath || process.cwd());
11226
+ const directory = path18.resolve(dirPath || process.cwd());
11030
11227
  const result = onboard({ directory });
11031
11228
  if (json) {
11032
11229
  console.log(JSON.stringify(result, null, 2));
@@ -11045,7 +11242,7 @@ Suggested namespace: ${result.plan.suggestedNamespace}`);
11045
11242
  async function cmdCurate(targetPath, json) {
11046
11243
  const memoryDir = resolveMemoryDir();
11047
11244
  const result = await curate({
11048
- targetPath: path17.resolve(targetPath),
11245
+ targetPath: path18.resolve(targetPath),
11049
11246
  memoryDir,
11050
11247
  source: "curation",
11051
11248
  checkDuplicates: true,
@@ -11087,9 +11284,9 @@ async function cmdReview(action, rest) {
11087
11284
  const configPath = resolveConfigPath();
11088
11285
  let tombstonesConfig = null;
11089
11286
  try {
11090
- const rawCfg = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
11091
- const remnicCfg = resolveRemnicConfigRecord5(rawCfg);
11092
- const config = parseConfig6(remnicCfg);
11287
+ const rawCfg = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
11288
+ const remnicCfg = resolveRemnicConfigRecord6(rawCfg);
11289
+ const config = parseConfig7(remnicCfg);
11093
11290
  tombstonesConfig = {
11094
11291
  enabled: config.tombstonesEnabled,
11095
11292
  semanticMatch: config.tombstonesSemanticMatch,
@@ -11175,7 +11372,7 @@ async function cmdSync(action, rest, json) {
11175
11372
  }
11176
11373
  function localOfflineSourceId(memoryDir) {
11177
11374
  const host = os3.hostname() || "unknown-host";
11178
- const dirHash = createHash4("sha256").update(path17.resolve(memoryDir)).digest("hex").slice(0, 16);
11375
+ const dirHash = createHash4("sha256").update(path18.resolve(memoryDir)).digest("hex").slice(0, 16);
11179
11376
  return `remnic-local:${host}:${dirHash}`;
11180
11377
  }
11181
11378
  function normalizeOfflineRemoteUrl(raw) {
@@ -11573,10 +11770,10 @@ var OFFLINE_SYNC_CONTENT_MISSING_RETRY_MAX = 3;
11573
11770
  var OFFLINE_SYNC_CONTENT_MISSING_RETRY_DELAY_MS = 250;
11574
11771
  var OfflineRemoteFileChangedError = class extends Error {
11575
11772
  path;
11576
- constructor(path18) {
11577
- super(`remote file changed while fetching offline content: ${path18}`);
11773
+ constructor(path19) {
11774
+ super(`remote file changed while fetching offline content: ${path19}`);
11578
11775
  this.name = "OfflineRemoteFileChangedError";
11579
- this.path = path18;
11776
+ this.path = path19;
11580
11777
  }
11581
11778
  };
11582
11779
  function isOfflineRemoteFileChangedError(error) {
@@ -11831,13 +12028,13 @@ async function pushOfflineFileContent(args) {
11831
12028
  }
11832
12029
  async function pushOfflineFileContentFromChunkReader(args) {
11833
12030
  const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
11834
- const stat2 = fs14.statSync(filePath);
12031
+ const stat2 = fs15.statSync(filePath);
11835
12032
  if (stat2.mtimeMs !== args.file.mtimeMs) {
11836
12033
  throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
11837
12034
  }
11838
12035
  const hash = createHash4("sha256");
11839
12036
  const chunks = args.readFileChunks({
11840
- root: path17.resolve(args.memoryDir),
12037
+ root: path18.resolve(args.memoryDir),
11841
12038
  path: args.file.path,
11842
12039
  filePath,
11843
12040
  chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
@@ -12322,7 +12519,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
12322
12519
  return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
12323
12520
  }
12324
12521
  async function runOfflineSyncOnce(options) {
12325
- fs14.mkdirSync(options.memoryDir, { recursive: true });
12522
+ fs15.mkdirSync(options.memoryDir, { recursive: true });
12326
12523
  let activeStatePath = options.statePath;
12327
12524
  let priorState = await readOfflineSyncState(activeStatePath);
12328
12525
  let syncNamespace = options.namespace ?? priorState?.namespace;
@@ -12947,7 +13144,7 @@ Environment fallbacks:
12947
13144
  REMNIC_OFFLINE_REMOTE_URL, REMNIC_OFFLINE_TOKEN, REMNIC_AUTH_TOKEN`);
12948
13145
  return;
12949
13146
  }
12950
- const memoryDir = path17.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
13147
+ const memoryDir = path18.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
12951
13148
  const namespace = resolveRequiredValueFlag(rest, "--namespace");
12952
13149
  const includeTranscripts = !hasFlag(rest, "--no-transcripts");
12953
13150
  const stateOverride = resolveRequiredValueFlag(rest, "--state");
@@ -12955,7 +13152,7 @@ Environment fallbacks:
12955
13152
  const configPath = resolveConfigPath();
12956
13153
  let config;
12957
13154
  try {
12958
- const rawConfig = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13155
+ const rawConfig = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
12959
13156
  config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
12960
13157
  } catch {
12961
13158
  throw new Error(
@@ -12967,10 +13164,10 @@ Environment fallbacks:
12967
13164
  const needsRemote = action === "prepare" || action === "sync" || action === "watch";
12968
13165
  const remoteUrl = needsRemote ? resolveOfflineRemoteUrl(rest) : resolveOptionalOfflineRemoteUrl(rest);
12969
13166
  const token = needsRemote ? resolveOfflineToken(rest) : void 0;
12970
- const statePath = statePathExplicit ? path17.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
13167
+ const statePath = statePathExplicit ? path18.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
12971
13168
  if (action === "prepare") {
12972
13169
  if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
12973
- fs14.mkdirSync(memoryDir, { recursive: true });
13170
+ fs15.mkdirSync(memoryDir, { recursive: true });
12974
13171
  const remoteSnapshot = await fetchOfflineSnapshot({
12975
13172
  remoteUrl,
12976
13173
  token,
@@ -13069,7 +13266,7 @@ Environment fallbacks:
13069
13266
  return;
13070
13267
  }
13071
13268
  if (action === "status") {
13072
- fs14.mkdirSync(memoryDir, { recursive: true });
13269
+ fs15.mkdirSync(memoryDir, { recursive: true });
13073
13270
  const state = statePath ? await readOfflineSyncState(statePath) : null;
13074
13271
  if (state && remoteUrl && statePath) {
13075
13272
  assertOfflineStateMatches({
@@ -13149,11 +13346,11 @@ Environment fallbacks:
13149
13346
  failures: result.largeFilePushFailures
13150
13347
  });
13151
13348
  largeFileFailureCounts = advanced.counts;
13152
- for (const path18 of advanced.newlySkipped) {
13153
- if (skippedLargeFiles.has(path18)) continue;
13154
- skippedLargeFiles.add(path18);
13349
+ for (const path19 of advanced.newlySkipped) {
13350
+ if (skippedLargeFiles.has(path19)) continue;
13351
+ skippedLargeFiles.add(path19);
13155
13352
  console.warn(
13156
- `offline sync: permanently skipping ${path18} 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)`
13353
+ `offline sync: permanently skipping ${path19} 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)`
13157
13354
  );
13158
13355
  }
13159
13356
  const pulled = result.pull ? result.pull.upserted + result.pull.deleted : 0;
@@ -13168,11 +13365,11 @@ Environment fallbacks:
13168
13365
  failures: error.failures
13169
13366
  });
13170
13367
  largeFileFailureCounts = advanced.counts;
13171
- for (const path18 of advanced.newlySkipped) {
13172
- if (skippedLargeFiles.has(path18)) continue;
13173
- skippedLargeFiles.add(path18);
13368
+ for (const path19 of advanced.newlySkipped) {
13369
+ if (skippedLargeFiles.has(path19)) continue;
13370
+ skippedLargeFiles.add(path19);
13174
13371
  console.warn(
13175
- `offline sync: permanently skipping ${path18} 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)`
13372
+ `offline sync: permanently skipping ${path19} 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)`
13176
13373
  );
13177
13374
  }
13178
13375
  }
@@ -13207,7 +13404,7 @@ function cmdDedup(json) {
13207
13404
  function readInstalledConnectorConfig(configPath, fallback) {
13208
13405
  if (!configPath) return fallback;
13209
13406
  try {
13210
- const parsed = JSON.parse(fs14.readFileSync(configPath, "utf8"));
13407
+ const parsed = JSON.parse(fs15.readFileSync(configPath, "utf8"));
13211
13408
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
13212
13409
  const { token: _token, ...config } = parsed;
13213
13410
  return config;
@@ -13313,7 +13510,7 @@ async function cmdConnectors(action, rest, json) {
13313
13510
  const connectorDaemonUrl = typeof effectiveConnectorConfig.remnicDaemonUrl === "string" && effectiveConnectorConfig.remnicDaemonUrl.trim().length > 0 ? effectiveConnectorConfig.remnicDaemonUrl.trim() : void 0;
13314
13511
  const pubResult = await pub.publish({
13315
13512
  config: { memoryDir, namespace: connectorNamespace, daemonUrl: connectorDaemonUrl },
13316
- skillsRoot: path17.join(memoryDir, "skills"),
13513
+ skillsRoot: path18.join(memoryDir, "skills"),
13317
13514
  rollbackTokenEntry: preInstallTokenEntry,
13318
13515
  log: { info: console.log, warn: console.warn, error: console.error }
13319
13516
  });
@@ -13385,7 +13582,7 @@ async function cmdConnectors(action, rest, json) {
13385
13582
  const pub = factory();
13386
13583
  const available = await pub.isHostAvailable();
13387
13584
  const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
13388
- const extensionExists = available && extRoot ? fs14.existsSync(extRoot) : false;
13585
+ const extensionExists = available && extRoot ? fs15.existsSync(extRoot) : false;
13389
13586
  publisherChecks.push({
13390
13587
  name: `Publisher: ${targetHostId}`,
13391
13588
  ok: !available || extensionExists,
@@ -13459,7 +13656,7 @@ async function cmdConnectors(action, rest, json) {
13459
13656
  let connectorsCfg;
13460
13657
  const configPath = resolveConfigPath();
13461
13658
  try {
13462
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13659
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
13463
13660
  connectorsCfg = parseConfigQuietly(raw).connectors;
13464
13661
  } catch {
13465
13662
  process.stderr.write(
@@ -13533,12 +13730,12 @@ async function cmdConnectors(action, rest, json) {
13533
13730
  process.exitCode = 2;
13534
13731
  return;
13535
13732
  }
13536
- initLogger2();
13733
+ initLogger3();
13537
13734
  const configPath = resolveConfigPath();
13538
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13539
- const remnicCfg = resolveRemnicConfigRecord5(raw);
13540
- const config = parseConfig6(remnicCfg);
13541
- const orchestrator = new Orchestrator3(config);
13735
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
13736
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
13737
+ const config = parseConfig7(remnicCfg);
13738
+ const orchestrator = new Orchestrator4(config);
13542
13739
  try {
13543
13740
  await orchestrator.initialize();
13544
13741
  await orchestrator.deferredReady;
@@ -13660,9 +13857,9 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
13660
13857
  console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
13661
13858
  process.exit(1);
13662
13859
  }
13663
- const rawConfig = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13664
- const pluginConfig = resolveRemnicConfigRecord5(rawConfig);
13665
- const config = parseConfig6(pluginConfig);
13860
+ const rawConfig = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
13861
+ const pluginConfig = resolveRemnicConfigRecord6(rawConfig);
13862
+ const config = parseConfig7(pluginConfig);
13666
13863
  if (subAction === "generate") {
13667
13864
  let outputDir;
13668
13865
  try {
@@ -13673,22 +13870,22 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
13673
13870
  }
13674
13871
  const manifest = generateMarketplaceManifest();
13675
13872
  await writeMarketplaceManifest(outputDir, manifest);
13676
- const outPath = path17.join(outputDir, "marketplace.json");
13873
+ const outPath = path18.join(outputDir, "marketplace.json");
13677
13874
  if (json) {
13678
13875
  console.log(JSON.stringify({ status: "generated", path: outPath }, null, 2));
13679
13876
  } else {
13680
13877
  console.log(`Generated marketplace.json at ${outPath}`);
13681
13878
  }
13682
13879
  } else if (subAction === "validate") {
13683
- const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path17.join(process.cwd(), "marketplace.json");
13684
- const resolved = path17.resolve(targetPath);
13685
- if (!fs14.existsSync(resolved)) {
13880
+ const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path18.join(process.cwd(), "marketplace.json");
13881
+ const resolved = path18.resolve(targetPath);
13882
+ if (!fs15.existsSync(resolved)) {
13686
13883
  console.error(`File not found: ${resolved}`);
13687
13884
  process.exit(1);
13688
13885
  }
13689
13886
  let parsed;
13690
13887
  try {
13691
- parsed = JSON.parse(fs14.readFileSync(resolved, "utf8"));
13888
+ parsed = JSON.parse(fs15.readFileSync(resolved, "utf8"));
13692
13889
  } catch {
13693
13890
  console.error(`Invalid JSON in ${resolved}`);
13694
13891
  process.exit(1);
@@ -13887,12 +14084,12 @@ async function cmdSpace(action, rest, json) {
13887
14084
  }
13888
14085
  }
13889
14086
  async function cmdLegacyBenchmark(action, rest, json) {
13890
- initLogger2();
14087
+ initLogger3();
13891
14088
  const configPath = resolveConfigPath();
13892
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13893
- const remnicCfg = resolveRemnicConfigRecord5(raw);
13894
- const config = parseConfig6(remnicCfg);
13895
- const orchestrator = new Orchestrator3(config);
14089
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
14090
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
14091
+ const config = parseConfig7(remnicCfg);
14092
+ const orchestrator = new Orchestrator4(config);
13896
14093
  const service = new EngramAccessService2(orchestrator);
13897
14094
  const { runBenchSuite, loadBaseline, checkRegression } = await loadBenchModule();
13898
14095
  const benchConfig = {
@@ -13964,6 +14161,7 @@ async function cmdLegacyBenchmark(action, rest, json) {
13964
14161
  }
13965
14162
  async function cmdBench(rest) {
13966
14163
  if (rest[0] === "coding") return cmdBenchCoding(rest.slice(1));
14164
+ if (rest[0] === "security") return cmdBenchSecurity(rest.slice(1));
13967
14165
  if (rest[0] === "procedural-ablation") {
13968
14166
  await cmdBenchProceduralAblation(rest.slice(1));
13969
14167
  return;
@@ -14090,7 +14288,7 @@ async function cmdBench(rest) {
14090
14288
  }
14091
14289
  const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
14092
14290
  const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
14093
- printBenchStatusLine(parsed.json, `Resuming from: ${path17.basename(latestStatusPath)}`);
14291
+ printBenchStatusLine(parsed.json, `Resuming from: ${path18.basename(latestStatusPath)}`);
14094
14292
  printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
14095
14293
  printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
14096
14294
  const before = selectedBenchmarks.length;
@@ -14258,9 +14456,9 @@ Options:
14258
14456
  );
14259
14457
  process.exit(1);
14260
14458
  } else {
14261
- fixturePath = path17.resolve(expandTilde(fixturePathRaw));
14459
+ fixturePath = path18.resolve(expandTilde(fixturePathRaw));
14262
14460
  }
14263
- const outPath = path17.resolve(expandTilde(outPathRaw));
14461
+ const outPath = path18.resolve(expandTilde(outPathRaw));
14264
14462
  const benchModule = await loadBenchModule();
14265
14463
  const runner = benchModule.runProceduralAblationCli;
14266
14464
  if (typeof runner !== "function") {
@@ -14279,7 +14477,7 @@ Options:
14279
14477
  );
14280
14478
  console.log(`wrote ${outPath}`);
14281
14479
  }
14282
- var LOGS_DIR = path17.join(PID_DIR, "logs");
14480
+ var LOGS_DIR = path18.join(PID_DIR, "logs");
14283
14481
  var LAUNCHD_PLIST_PATHS = launchdPlistPaths(resolveHomeDir());
14284
14482
  var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
14285
14483
  var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
@@ -14293,7 +14491,7 @@ function readPid() {
14293
14491
  function inferPort() {
14294
14492
  try {
14295
14493
  const configPath = resolveConfigPath();
14296
- const raw = JSON.parse(fs14.readFileSync(configPath, "utf8"));
14494
+ const raw = JSON.parse(fs15.readFileSync(configPath, "utf8"));
14297
14495
  return raw.server?.port ?? 4318;
14298
14496
  } catch {
14299
14497
  return 4318;
@@ -14356,7 +14554,7 @@ function selectLaunchdInspection(openclawPluginModeConfigured) {
14356
14554
  for (const plistPath of LAUNCHD_PLIST_PATHS.slice(1)) {
14357
14555
  const legacy = inspectLaunchdPlist(plistPath);
14358
14556
  if (!legacy.installed) continue;
14359
- const label = path17.basename(plistPath, ".plist");
14557
+ const label = path18.basename(plistPath, ".plist");
14360
14558
  return legacy.ok ? {
14361
14559
  ...legacy,
14362
14560
  warn: true,
@@ -14388,13 +14586,13 @@ function daemonInstall() {
14388
14586
  process.exit(1);
14389
14587
  }
14390
14588
  const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
14391
- fs14.mkdirSync(LOGS_DIR, { recursive: true });
14589
+ fs15.mkdirSync(LOGS_DIR, { recursive: true });
14392
14590
  if (isMacOS()) {
14393
- const templatePath = path17.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
14394
- const template = fs14.readFileSync(templatePath, "utf8");
14591
+ const templatePath = path18.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
14592
+ const template = fs15.readFileSync(templatePath, "utf8");
14395
14593
  const plist = renderTemplate(template, vars);
14396
- fs14.mkdirSync(path17.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
14397
- fs14.writeFileSync(LAUNCHD_PLIST_PATH, plist);
14594
+ fs15.mkdirSync(path18.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
14595
+ fs15.writeFileSync(LAUNCHD_PLIST_PATH, plist);
14398
14596
  try {
14399
14597
  launchdLoadPlist(LAUNCHD_PLIST_PATH);
14400
14598
  } catch (err) {
@@ -14410,11 +14608,11 @@ function daemonInstall() {
14410
14608
  console.log(` RunAtLoad: true, KeepAlive: true`);
14411
14609
  console.log(` Logs: ${LOGS_DIR}/daemon.log`);
14412
14610
  } else if (isLinux()) {
14413
- const templatePath = path17.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
14414
- const template = fs14.readFileSync(templatePath, "utf8");
14611
+ const templatePath = path18.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
14612
+ const template = fs15.readFileSync(templatePath, "utf8");
14415
14613
  const unit = renderTemplate(template, vars);
14416
- fs14.mkdirSync(path17.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
14417
- fs14.writeFileSync(SYSTEMD_UNIT_PATH, unit);
14614
+ fs15.mkdirSync(path18.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
14615
+ fs15.writeFileSync(SYSTEMD_UNIT_PATH, unit);
14418
14616
  try {
14419
14617
  childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
14420
14618
  } catch (err) {
@@ -14450,7 +14648,7 @@ function daemonUninstall() {
14450
14648
  } catch {
14451
14649
  }
14452
14650
  try {
14453
- fs14.unlinkSync(plistPath);
14651
+ fs15.unlinkSync(plistPath);
14454
14652
  removed = true;
14455
14653
  console.log(`Removed launchd service: ${plistPath}`);
14456
14654
  } catch {
@@ -14470,7 +14668,7 @@ function daemonUninstall() {
14470
14668
  let removed = false;
14471
14669
  for (const unitPath of SYSTEMD_UNIT_PATHS) {
14472
14670
  try {
14473
- fs14.unlinkSync(unitPath);
14671
+ fs15.unlinkSync(unitPath);
14474
14672
  removed = true;
14475
14673
  console.log(`Removed systemd service: ${unitPath}`);
14476
14674
  } catch {
@@ -14537,13 +14735,13 @@ async function daemonStatus() {
14537
14735
  console.log(` Port: ${port}`);
14538
14736
  console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
14539
14737
  console.log(` Platform: ${process.platform}`);
14540
- console.log(` PID file: ${fs14.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
14541
- console.log(` Log file: ${fs14.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
14738
+ console.log(` PID file: ${fs15.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
14739
+ console.log(` Log file: ${fs15.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
14542
14740
  try {
14543
14741
  const configPath = resolveConfigPath();
14544
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
14545
- const remnicCfg = resolveRemnicConfigRecord5(raw);
14546
- const config = parseConfig6(remnicCfg);
14742
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
14743
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
14744
+ const config = parseConfig7(remnicCfg);
14547
14745
  const extRoot = resolveExtensionsRoot(config);
14548
14746
  const noopLog = { warn: () => {
14549
14747
  }, debug: () => {
@@ -14582,9 +14780,9 @@ function daemonStart() {
14582
14780
  return;
14583
14781
  }
14584
14782
  }
14585
- fs14.mkdirSync(PID_DIR, { recursive: true });
14586
- fs14.mkdirSync(LOGS_DIR, { recursive: true });
14587
- const logStream = fs14.openSync(LOG_FILE, "a");
14783
+ fs15.mkdirSync(PID_DIR, { recursive: true });
14784
+ fs15.mkdirSync(LOGS_DIR, { recursive: true });
14785
+ const logStream = fs15.openSync(LOG_FILE, "a");
14588
14786
  const serverBin = resolveServerBin();
14589
14787
  const isSource = serverBin.endsWith(".ts");
14590
14788
  let cmd;
@@ -14606,7 +14804,7 @@ function daemonStart() {
14606
14804
  }
14607
14805
  });
14608
14806
  child.unref();
14609
- fs14.writeFileSync(PID_FILE, String(child.pid));
14807
+ fs15.writeFileSync(PID_FILE, String(child.pid));
14610
14808
  console.log(`Started remnic server (pid ${child.pid})`);
14611
14809
  console.log(` Log: ${LOG_FILE}`);
14612
14810
  }
@@ -14640,11 +14838,11 @@ function daemonStop() {
14640
14838
  console.log("Process not found (cleaning up PID file)");
14641
14839
  }
14642
14840
  try {
14643
- fs14.unlinkSync(PID_FILE);
14841
+ fs15.unlinkSync(PID_FILE);
14644
14842
  } catch {
14645
14843
  }
14646
14844
  try {
14647
- fs14.unlinkSync(LEGACY_PID_FILE);
14845
+ fs15.unlinkSync(LEGACY_PID_FILE);
14648
14846
  } catch {
14649
14847
  }
14650
14848
  }
@@ -14770,11 +14968,11 @@ async function promptYesNo(question, defaultYes = true) {
14770
14968
  });
14771
14969
  }
14772
14970
  async function cmdBinary(rest) {
14773
- initLogger2();
14971
+ initLogger3();
14774
14972
  const configPath = resolveConfigPath();
14775
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
14776
- const remnicCfg = resolveRemnicConfigRecord5(raw);
14777
- const config = parseConfig6(remnicCfg);
14973
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
14974
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
14975
+ const config = parseConfig7(remnicCfg);
14778
14976
  const memoryDir = resolveMemoryDir();
14779
14977
  const blConfig = {
14780
14978
  enabled: config.binaryLifecycleEnabled,
@@ -14892,7 +15090,7 @@ Clean complete: cleaned=${result.cleaned}`
14892
15090
  }
14893
15091
  async function cmdOpenclawInstall(opts) {
14894
15092
  const configPath = resolveOpenclawConfigPath(opts.configPath);
14895
- const fallbackMemoryDir = path17.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
15093
+ const fallbackMemoryDir = path18.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
14896
15094
  console.log(`OpenClaw config: ${configPath}`);
14897
15095
  const existingConfig = readOpenclawConfig(configPath);
14898
15096
  const { plugins, entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
@@ -14963,7 +15161,7 @@ async function cmdOpenclawInstall(opts) {
14963
15161
  } else if (slotIsActiveLegacy) {
14964
15162
  changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
14965
15163
  }
14966
- if (!fs14.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
15164
+ if (!fs15.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
14967
15165
  if (hasLegacy && migrateLegacy) {
14968
15166
  changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
14969
15167
  }
@@ -14983,8 +15181,8 @@ async function cmdOpenclawInstall(opts) {
14983
15181
  Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
14984
15182
  return;
14985
15183
  }
14986
- if (fs14.existsSync(memoryDir)) {
14987
- const st = fs14.statSync(memoryDir);
15184
+ if (fs15.existsSync(memoryDir)) {
15185
+ const st = fs15.statSync(memoryDir);
14988
15186
  if (!st.isDirectory()) {
14989
15187
  throw new Error(
14990
15188
  `Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
@@ -14992,12 +15190,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
14992
15190
  );
14993
15191
  }
14994
15192
  } else {
14995
- fs14.mkdirSync(memoryDir, { recursive: true });
15193
+ fs15.mkdirSync(memoryDir, { recursive: true });
14996
15194
  console.log(`Created memory directory: ${memoryDir}`);
14997
15195
  }
14998
- const configDir = path17.dirname(configPath);
14999
- if (!fs14.existsSync(configDir)) {
15000
- fs14.mkdirSync(configDir, { recursive: true });
15196
+ const configDir = path18.dirname(configPath);
15197
+ if (!fs15.existsSync(configDir)) {
15198
+ fs15.mkdirSync(configDir, { recursive: true });
15001
15199
  }
15002
15200
  atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
15003
15201
  console.log("\nDone! Summary of changes:");
@@ -15024,12 +15222,12 @@ async function cmdOpenclawUpgrade(opts) {
15024
15222
  const pluginDir = resolveOpenclawPluginDir(opts.pluginDir);
15025
15223
  const managedTargetDir = resolveOpenclawManagedPluginDir();
15026
15224
  const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
15027
- const fallbackMemoryDir = path17.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
15225
+ const fallbackMemoryDir = path18.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
15028
15226
  const packageSpec = buildOpenclawManagedUpgradePackageSpec(opts.version);
15029
- const configExistedBefore = fs14.existsSync(configPath);
15227
+ const configExistedBefore = fs15.existsSync(configPath);
15030
15228
  const existingConfig = readOpenclawConfig(configPath);
15031
15229
  const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
15032
- const preservedMemoryDir = opts.memoryDir ? path17.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
15230
+ const preservedMemoryDir = opts.memoryDir ? path18.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
15033
15231
  console.log(`OpenClaw config: ${configPath}`);
15034
15232
  console.log(`Plugin dir: ${pluginDir}`);
15035
15233
  if (legacyPluginDirForBackup) {
@@ -15037,7 +15235,7 @@ async function cmdOpenclawUpgrade(opts) {
15037
15235
  }
15038
15236
  console.log(`Memory dir: ${preservedMemoryDir}`);
15039
15237
  console.log(`Package spec: ${packageSpec}`);
15040
- console.log(`Backup root: ${path17.join(resolveOpenclawStateDir(), "backups")}`);
15238
+ console.log(`Backup root: ${path18.join(resolveOpenclawStateDir(), "backups")}`);
15041
15239
  const plannedActions = [
15042
15240
  `backup openclaw.json and the existing ${REMNIC_OPENCLAW_PLUGIN_ID} extension`,
15043
15241
  ...legacyPluginDirForBackup ? [`backup the existing ${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID} extension without modifying it`] : [],
@@ -15075,9 +15273,9 @@ async function cmdOpenclawUpgrade(opts) {
15075
15273
  assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
15076
15274
  }
15077
15275
  const backupDir = createOpenclawUpgradeBackupDir();
15078
- const configBackupPath = path17.join(backupDir, "openclaw.json");
15079
- const pluginBackupDir = path17.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
15080
- const legacyPluginBackupDir = legacyPluginDirForBackup ? path17.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
15276
+ const configBackupPath = path18.join(backupDir, "openclaw.json");
15277
+ const pluginBackupDir = path18.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
15278
+ const legacyPluginBackupDir = legacyPluginDirForBackup ? path18.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
15081
15279
  const backupNotes = [];
15082
15280
  if (backupPathIfPresent(configPath, configBackupPath)) {
15083
15281
  backupNotes.push(`+ Backed up config to ${configBackupPath}`);
@@ -15127,7 +15325,7 @@ async function cmdOpenclawUpgrade(opts) {
15127
15325
  const managedRollbackDir = publishedInstallError ? publishedInstallError.managedRollbackDir : installResult?.managedRollbackDir;
15128
15326
  const managedRollbackTargetDir = publishedInstallError?.managedRollbackTargetDir ?? installResult?.managedRollbackTargetDir ?? managedTargetDir;
15129
15327
  const requiresHostManagedRestore = publishedInstallError?.requiresHostManagedRestore ?? installResult?.requiresHostManagedRestore ?? false;
15130
- const managedRollbackSharesPluginDir = managedRollbackDir && path17.resolve(managedRollbackTargetDir) === path17.resolve(pluginDir);
15328
+ const managedRollbackSharesPluginDir = managedRollbackDir && path18.resolve(managedRollbackTargetDir) === path18.resolve(pluginDir);
15131
15329
  const pluginRollbackDir = managedRollbackSharesPluginDir ? requiresHostManagedRestore ? rollbackDir : rollbackDir ?? managedRollbackDir : rollbackDir;
15132
15330
  const shouldRestorePlugin = Boolean(
15133
15331
  installResult && !requiresHostManagedRestore || pluginRollbackDir || publishedInstallError?.shouldRestoreBackup
@@ -15184,7 +15382,7 @@ async function cmdOpenclawUpgrade(opts) {
15184
15382
  rollbackErrors.push(error);
15185
15383
  }
15186
15384
  if (pendingConfigRestoreError) rollbackErrors.push(pendingConfigRestoreError);
15187
- if (managedRollbackDir && path17.resolve(managedRollbackTargetDir) !== path17.resolve(pluginDir) && !requiresHostManagedRestore) {
15385
+ if (managedRollbackDir && path18.resolve(managedRollbackTargetDir) !== path18.resolve(pluginDir) && !requiresHostManagedRestore) {
15188
15386
  try {
15189
15387
  rollbackNotes.push(
15190
15388
  ...rollbackOpenclawUpgrade({
@@ -15250,16 +15448,16 @@ async function cmdOpenclawMigrateEngram(opts) {
15250
15448
  console.log(" - Re-apply any local source patches to the new package only after verifying the published build.");
15251
15449
  }
15252
15450
  function createOpenclawUpgradeBackupDir() {
15253
- const backupsRoot = path17.join(resolveOpenclawStateDir(), "backups");
15254
- fs14.mkdirSync(backupsRoot, { recursive: true });
15255
- return fs14.mkdtempSync(path17.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
15451
+ const backupsRoot = path18.join(resolveOpenclawStateDir(), "backups");
15452
+ fs15.mkdirSync(backupsRoot, { recursive: true });
15453
+ return fs15.mkdtempSync(path18.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
15256
15454
  }
15257
15455
  async function cmdTaxonomy(rest) {
15258
- initLogger2();
15456
+ initLogger3();
15259
15457
  const configPath = resolveConfigPath();
15260
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
15261
- const remnicCfg = resolveRemnicConfigRecord5(raw);
15262
- const config = parseConfig6(remnicCfg);
15458
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
15459
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
15460
+ const config = parseConfig7(remnicCfg);
15263
15461
  if (!config.taxonomyEnabled) {
15264
15462
  console.error(
15265
15463
  "Taxonomy is disabled in config (taxonomyEnabled = false). Enable it to use taxonomy commands."
@@ -15294,9 +15492,9 @@ async function cmdTaxonomy(rest) {
15294
15492
  const doc = generateResolverDocument(taxonomy);
15295
15493
  console.log(doc);
15296
15494
  if (config.taxonomyAutoGenResolver) {
15297
- const resolverPath = path17.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15298
- fs14.mkdirSync(path17.dirname(resolverPath), { recursive: true });
15299
- fs14.writeFileSync(resolverPath, doc);
15495
+ const resolverPath = path18.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15496
+ fs15.mkdirSync(path18.dirname(resolverPath), { recursive: true });
15497
+ fs15.writeFileSync(resolverPath, doc);
15300
15498
  console.error(`Written: ${resolverPath}`);
15301
15499
  }
15302
15500
  break;
@@ -15341,8 +15539,8 @@ async function cmdTaxonomy(rest) {
15341
15539
  console.log(`Added category "${id}" (${name}).`);
15342
15540
  if (config.taxonomyAutoGenResolver) {
15343
15541
  const doc = generateResolverDocument(taxonomy);
15344
- const resolverPath = path17.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15345
- fs14.writeFileSync(resolverPath, doc);
15542
+ const resolverPath = path18.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15543
+ fs15.writeFileSync(resolverPath, doc);
15346
15544
  console.error(`Regenerated: ${resolverPath}`);
15347
15545
  }
15348
15546
  break;
@@ -15372,8 +15570,8 @@ async function cmdTaxonomy(rest) {
15372
15570
  console.log(`Removed category "${id}".`);
15373
15571
  if (config.taxonomyAutoGenResolver) {
15374
15572
  const doc = generateResolverDocument(taxonomy);
15375
- const resolverPath = path17.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15376
- fs14.writeFileSync(resolverPath, doc);
15573
+ const resolverPath = path18.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15574
+ fs15.writeFileSync(resolverPath, doc);
15377
15575
  console.error(`Regenerated: ${resolverPath}`);
15378
15576
  }
15379
15577
  break;
@@ -15564,12 +15762,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
15564
15762
  `Unknown training-export format "${args.format}". ${validList}`
15565
15763
  );
15566
15764
  }
15567
- if (!fs14.existsSync(args.memoryDir)) {
15765
+ if (!fs15.existsSync(args.memoryDir)) {
15568
15766
  throw new Error(
15569
15767
  `--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
15570
15768
  );
15571
15769
  }
15572
- if (!fs14.statSync(args.memoryDir).isDirectory()) {
15770
+ if (!fs15.statSync(args.memoryDir).isDirectory()) {
15573
15771
  throw new Error(
15574
15772
  `--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
15575
15773
  );
@@ -15654,11 +15852,11 @@ async function runTrainingExport(args, stdout = process.stdout) {
15654
15852
  );
15655
15853
  }
15656
15854
  const formatted = adapter.formatRecords(records);
15657
- const outDir = path17.dirname(args.output);
15658
- fs14.mkdirSync(outDir, { recursive: true });
15855
+ const outDir = path18.dirname(args.output);
15856
+ fs15.mkdirSync(outDir, { recursive: true });
15659
15857
  const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
15660
- fs14.writeFileSync(tmpPath, formatted, "utf-8");
15661
- fs14.renameSync(tmpPath, args.output);
15858
+ fs15.writeFileSync(tmpPath, formatted, "utf-8");
15859
+ fs15.renameSync(tmpPath, args.output);
15662
15860
  stdout.write(
15663
15861
  `Exported ${records.length} records to ${args.output} (${adapter.name} format)
15664
15862
  `
@@ -15707,6 +15905,9 @@ async function main(argv = process.argv.slice(2)) {
15707
15905
  case "xray":
15708
15906
  await cmdXray(rest);
15709
15907
  break;
15908
+ case "security":
15909
+ await cmdSecurity(rest);
15910
+ break;
15710
15911
  case "doctor":
15711
15912
  await cmdDoctor();
15712
15913
  break;
@@ -15762,7 +15963,7 @@ async function main(argv = process.argv.slice(2)) {
15762
15963
  case "tree": {
15763
15964
  const subAction = rest[0];
15764
15965
  const json = rest.includes("--json");
15765
- const outputDir = resolveFlag(rest, "--output") ?? path17.join(process.cwd(), ".remnic", "context-tree");
15966
+ const outputDir = resolveFlag(rest, "--output") ?? path18.join(process.cwd(), ".remnic", "context-tree");
15766
15967
  const categoriesFlag = resolveFlag(rest, "--categories");
15767
15968
  const categories = categoriesFlag ? categoriesFlag.split(",") : void 0;
15768
15969
  const maxPerCategoryRaw = resolveFlag(rest, "--max-per-category");
@@ -15827,7 +16028,7 @@ async function main(argv = process.argv.slice(2)) {
15827
16028
  }
15828
16029
  }, 500);
15829
16030
  };
15830
- fs14.watch(memoryDir, { recursive: true }, (_event, filename) => {
16031
+ fs15.watch(memoryDir, { recursive: true }, (_event, filename) => {
15831
16032
  if (filename && filename.startsWith(".")) return;
15832
16033
  rebuild();
15833
16034
  });
@@ -15835,12 +16036,12 @@ async function main(argv = process.argv.slice(2)) {
15835
16036
  });
15836
16037
  } else if (subAction === "validate") {
15837
16038
  const treeDir = outputDir;
15838
- if (!fs14.existsSync(treeDir)) {
16039
+ if (!fs15.existsSync(treeDir)) {
15839
16040
  console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
15840
16041
  process.exit(1);
15841
16042
  }
15842
- const indexPath = path17.join(treeDir, "INDEX.md");
15843
- if (!fs14.existsSync(indexPath)) {
16043
+ const indexPath = path18.join(treeDir, "INDEX.md");
16044
+ if (!fs15.existsSync(indexPath)) {
15844
16045
  console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
15845
16046
  process.exit(1);
15846
16047
  }
@@ -16022,10 +16223,10 @@ Other:
16022
16223
  let wearablesService;
16023
16224
  try {
16024
16225
  const configPath = resolveConfigPath();
16025
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
16026
- const remnicCfg = resolveRemnicConfigRecord5(raw);
16027
- const config = parseConfig6(remnicCfg);
16028
- wearablesOrchestrator = new Orchestrator3(config);
16226
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
16227
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
16228
+ const config = parseConfig7(remnicCfg);
16229
+ wearablesOrchestrator = new Orchestrator4(config);
16029
16230
  await wearablesOrchestrator.initialize();
16030
16231
  await wearablesOrchestrator.deferredReady;
16031
16232
  wearablesService = wearablesOrchestrator.getWearablesService();
@@ -16077,10 +16278,10 @@ Other:
16077
16278
  const targetFactory = async () => {
16078
16279
  if (!orchestratorSingleton) {
16079
16280
  const configPath = resolveConfigPath();
16080
- const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
16081
- const remnicCfg = resolveRemnicConfigRecord5(raw);
16082
- const config = parseConfig6(remnicCfg);
16083
- orchestratorSingleton = new Orchestrator3(config);
16281
+ const raw = fs15.existsSync(configPath) ? JSON.parse(fs15.readFileSync(configPath, "utf8")) : {};
16282
+ const remnicCfg = resolveRemnicConfigRecord6(raw);
16283
+ const config = parseConfig7(remnicCfg);
16284
+ orchestratorSingleton = new Orchestrator4(config);
16084
16285
  await orchestratorSingleton.initialize();
16085
16286
  await orchestratorSingleton.deferredReady;
16086
16287
  }
@@ -16310,9 +16511,9 @@ Usage:
16310
16511
  remnic extensions <list|show|validate|reload> Manage memory extensions
16311
16512
  remnic space <list|switch|create|delete|push|pull|share|promote|audit> Manage spaces
16312
16513
  create accepts --parent <id> to set parent-child relationship
16313
- remnic bench <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|attribute|drift-gen|coding> [benchmark...] [--quick] [--all] [--dataset-dir <path>] [--results-dir <path>] [--baselines-dir <path>] [--threshold <value>] [--detail] [--format <json|csv|html>] [--output <path>] [--target remnic-ai] [--json]
16514
+ remnic bench <list|run|published|datasets|runs|compare|results|baseline|export|publish|ui|providers|judge-calibrate|attribute|drift-gen|coding|security> [benchmark...] [--quick] [--all] [--dataset-dir <path>] [--results-dir <path>] [--baselines-dir <path>] [--threshold <value>] [--detail] [--format <json|csv|html>] [--output <path>] [--target remnic-ai] [--json]
16314
16515
  benchmark is kept as a compatibility alias. check/report remain under that alias.
16315
- remnic benchmark <list|run|datasets|runs|compare|results|baseline|export|publish|ui|providers|check|report|attribute|drift-gen|coding> [queries...] [--explain] [--baseline=<path>] [--report=<path>]
16516
+ remnic benchmark <list|run|datasets|runs|compare|results|baseline|export|publish|ui|providers|check|report|attribute|drift-gen|coding|security> [queries...] [--explain] [--baseline=<path>] [--report=<path>]
16316
16517
  remnic briefing [--since <window>] [--focus <filter>] [--save] [--format markdown|json]
16317
16518
  Daily context briefing. Windows: yesterday, today, NNh, NNd, NNw.
16318
16519
  Focus: person:<name>, project:<name>, topic:<name>.