@remnic/cli 9.50.0 → 9.50.3

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 +599 -464
  2. package/package.json +34 -29
package/dist/index.js CHANGED
@@ -18,12 +18,12 @@ async function persistEnrichmentCandidate(storage, entityName, candidate) {
18
18
  }
19
19
 
20
20
  // src/index.ts
21
- import fs13 from "fs";
22
- import os2 from "os";
23
- import path16 from "path";
21
+ import fs14 from "fs";
22
+ import os3 from "os";
23
+ import path17 from "path";
24
24
  import { createHash as createHash4 } from "crypto";
25
25
  import * as childProcess2 from "child_process";
26
- import { fileURLToPath as fileURLToPath4 } from "url";
26
+ import { fileURLToPath as fileURLToPath5 } from "url";
27
27
  import { gzipSync } from "zlib";
28
28
  import {
29
29
  parseConfig as parseConfig6,
@@ -138,7 +138,7 @@ import {
138
138
  OPERATION_NAMES,
139
139
  validateCapabilitiesForMint
140
140
  } from "@remnic/core";
141
- import { resolveRemnicPluginEntry } from "@remnic/core/plugin-id.js";
141
+ import { PLUGIN_ID as REMNIC_OPENCLAW_PLUGIN_ID, resolveRemnicPluginEntry } from "@remnic/core/plugin-id.js";
142
142
 
143
143
  // src/commands/meetings.ts
144
144
  import fs from "fs";
@@ -4157,33 +4157,6 @@ function atomicCopyFileSync(sourcePath, targetPath, options = {}) {
4157
4157
  throw error;
4158
4158
  }
4159
4159
  }
4160
- function swapDirectoryWithRollback(stagedDir, targetDir, rollbackDir) {
4161
- let hasRollbackCopy = false;
4162
- fs9.mkdirSync(path10.dirname(targetDir), { recursive: true });
4163
- fs9.rmSync(rollbackDir, { recursive: true, force: true });
4164
- if (fs9.existsSync(targetDir)) {
4165
- fs9.renameSync(targetDir, rollbackDir);
4166
- hasRollbackCopy = true;
4167
- }
4168
- try {
4169
- fs9.renameSync(stagedDir, targetDir);
4170
- } catch (swapError) {
4171
- fs9.rmSync(targetDir, { recursive: true, force: true });
4172
- if (hasRollbackCopy && fs9.existsSync(rollbackDir)) {
4173
- try {
4174
- fs9.renameSync(rollbackDir, targetDir);
4175
- hasRollbackCopy = false;
4176
- } catch (restoreError) {
4177
- throw new AggregateError(
4178
- [swapError, restoreError],
4179
- `Failed to stage upgraded plugin and failed to restore the previous plugin copy. The last known-good plugin remains preserved at ${rollbackDir}.`
4180
- );
4181
- }
4182
- }
4183
- throw swapError;
4184
- }
4185
- return { rollbackDir: hasRollbackCopy ? rollbackDir : void 0 };
4186
- }
4187
4160
  function cleanupRollbackDirectory(rollbackDir) {
4188
4161
  if (!rollbackDir) return;
4189
4162
  fs9.rmSync(rollbackDir, { recursive: true, force: true });
@@ -4224,10 +4197,7 @@ function restoreDirectoryFromRollback(targetDir, rollbackDir) {
4224
4197
  { cause: restoreError }
4225
4198
  );
4226
4199
  }
4227
- return cleanupDisplacedDirectoryBestEffort(
4228
- displacedDir,
4229
- `restored the previous plugin copy into ${targetDir}`
4230
- );
4200
+ return cleanupDisplacedDirectoryBestEffort(displacedDir, `restored the previous plugin copy into ${targetDir}`);
4231
4201
  }
4232
4202
  function restoreDirectoryFromBackup(targetDir, backupDir) {
4233
4203
  if (!fs9.existsSync(backupDir)) {
@@ -4260,10 +4230,7 @@ function restoreDirectoryFromBackup(targetDir, backupDir) {
4260
4230
  { cause: restoreError }
4261
4231
  );
4262
4232
  }
4263
- return cleanupDisplacedDirectoryBestEffort(
4264
- displacedDir,
4265
- `restored the plugin backup into ${targetDir}`
4266
- );
4233
+ return cleanupDisplacedDirectoryBestEffort(displacedDir, `restored the plugin backup into ${targetDir}`);
4267
4234
  }
4268
4235
  function restoreFileFromBackup(targetPath, backupPath) {
4269
4236
  atomicCopyFileSync(backupPath, targetPath);
@@ -4273,11 +4240,13 @@ function rollbackOpenclawUpgrade({
4273
4240
  configPath,
4274
4241
  pluginBackupDir,
4275
4242
  pluginDir,
4276
- rollbackDir
4243
+ rollbackDir,
4244
+ removeConfigIfUnbacked
4277
4245
  }) {
4278
4246
  const notes = [];
4279
4247
  const errors = [];
4280
4248
  let rollbackRestoreError;
4249
+ let configRemovalAttempted = false;
4281
4250
  let pluginRestored = false;
4282
4251
  try {
4283
4252
  if (rollbackDir && fs9.existsSync(rollbackDir)) {
@@ -4293,9 +4262,7 @@ function rollbackOpenclawUpgrade({
4293
4262
  if (!pluginRestored && pluginBackupDir && fs9.existsSync(pluginBackupDir)) {
4294
4263
  const cleanupWarning = restoreDirectoryFromBackup(pluginDir, pluginBackupDir);
4295
4264
  if (rollbackRestoreError) {
4296
- notes.push(
4297
- `Rollback copy restore failed; restored previous plugin from durable backup at ${pluginBackupDir}`
4298
- );
4265
+ notes.push(`Rollback copy restore failed; restored previous plugin from durable backup at ${pluginBackupDir}`);
4299
4266
  } else {
4300
4267
  notes.push(`Restored previous plugin from backup at ${pluginBackupDir}`);
4301
4268
  }
@@ -4320,10 +4287,14 @@ function rollbackOpenclawUpgrade({
4320
4287
  if (configBackupPath && fs9.existsSync(configBackupPath)) {
4321
4288
  restoreFileFromBackup(configPath, configBackupPath);
4322
4289
  notes.push(`Restored OpenClaw config from backup at ${configBackupPath}`);
4290
+ } else if (removeConfigIfUnbacked && fs9.existsSync(configPath)) {
4291
+ configRemovalAttempted = true;
4292
+ fs9.rmSync(configPath, { force: true });
4293
+ notes.push("Removed OpenClaw config created during the failed upgrade");
4323
4294
  }
4324
4295
  } catch (error) {
4325
4296
  errors.push(
4326
- `Failed to restore OpenClaw config from backup at ${configBackupPath}: ${error instanceof Error ? error.message : String(error)}`
4297
+ configRemovalAttempted || !configBackupPath ? `Failed to remove OpenClaw config created during the failed upgrade: ${error instanceof Error ? error.message : String(error)}` : `Failed to restore OpenClaw config from backup at ${configBackupPath}: ${error instanceof Error ? error.message : String(error)}`
4327
4298
  );
4328
4299
  }
4329
4300
  if (errors.length > 0) {
@@ -4331,6 +4302,19 @@ function rollbackOpenclawUpgrade({
4331
4302
  }
4332
4303
  return notes;
4333
4304
  }
4305
+ function restoreOpenclawConfigWithRetry(options) {
4306
+ try {
4307
+ rollbackOpenclawUpgrade(options);
4308
+ return void 0;
4309
+ } catch (initialRestoreError) {
4310
+ try {
4311
+ rollbackOpenclawUpgrade(options);
4312
+ return "Restored OpenClaw config after a transient rollback failure";
4313
+ } catch (retryRestoreError) {
4314
+ throw new AggregateError([initialRestoreError, retryRestoreError], "OpenClaw config restore failed twice.");
4315
+ }
4316
+ }
4317
+ }
4334
4318
  function createOpenclawUpgradeRollbackFailure(options) {
4335
4319
  const { failurePhase, installError, rollbackError } = options;
4336
4320
  return new AggregateError(
@@ -4356,12 +4340,162 @@ Run this manually when you're ready:
4356
4340
  }
4357
4341
  }
4358
4342
 
4359
- // src/daemon-service.ts
4343
+ // src/openclaw-managed-upgrade-loader.ts
4344
+ import { execFileSync } from "child_process";
4360
4345
  import fs10 from "fs";
4346
+ import os from "os";
4361
4347
  import path11 from "path";
4348
+ import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "url";
4349
+ var MANAGED_UPGRADE_SPECIFIER = "@remnic/plugin-openclaw/managed-upgrade";
4350
+ var OPENCLAW_PLUGIN_PACKAGE = "@remnic/plugin-openclaw";
4351
+ var NPM_INSTALL_TIMEOUT_MS = 12e4;
4352
+ var DIST_TAG_SELECTOR = /^[A-Za-z][0-9A-Za-z._-]*$/;
4353
+ var CARET_SEMVER_RANGE_SELECTOR = /^\^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
4354
+ function semanticVersionCoreLength(selector) {
4355
+ let cursor = selector.startsWith("v") ? 1 : 0;
4356
+ for (let part = 0; part < 3; part += 1) {
4357
+ const partStart = cursor;
4358
+ while (cursor < selector.length) {
4359
+ const code = selector.charCodeAt(cursor);
4360
+ if (code < 48 || code > 57) break;
4361
+ cursor += 1;
4362
+ }
4363
+ if (cursor === partStart || cursor - partStart > 1 && selector.charCodeAt(partStart) === 48) return -1;
4364
+ if (part < 2) {
4365
+ if (selector.charCodeAt(cursor) !== 46) return -1;
4366
+ cursor += 1;
4367
+ }
4368
+ }
4369
+ return cursor;
4370
+ }
4371
+ function areSemverIdentifiersValid(value, start, end, rejectLeadingZeroes) {
4372
+ if (start >= end) return false;
4373
+ let identifierStart = start;
4374
+ let numeric = true;
4375
+ for (let cursor = start; cursor <= end; cursor += 1) {
4376
+ const code = value.charCodeAt(cursor);
4377
+ if (cursor === end || code === 46) {
4378
+ if (cursor === identifierStart) return false;
4379
+ if (rejectLeadingZeroes && numeric && cursor - identifierStart > 1 && value.charCodeAt(identifierStart) === 48) {
4380
+ return false;
4381
+ }
4382
+ identifierStart = cursor + 1;
4383
+ numeric = true;
4384
+ continue;
4385
+ }
4386
+ const alphanumeric = code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 97 && code <= 122;
4387
+ if (!alphanumeric && code !== 45) return false;
4388
+ if (code < 48 || code > 57) numeric = false;
4389
+ }
4390
+ return true;
4391
+ }
4392
+ function isExactSemverSelector(selector) {
4393
+ const coreLength = semanticVersionCoreLength(selector);
4394
+ if (coreLength < 0) return false;
4395
+ if (coreLength === selector.length) return true;
4396
+ const suffixMarker = selector[coreLength];
4397
+ if (suffixMarker === "-") {
4398
+ const plusIndex = selector.indexOf("+", coreLength + 1);
4399
+ const prereleaseEnd = plusIndex < 0 ? selector.length : plusIndex;
4400
+ if (!areSemverIdentifiersValid(selector, coreLength + 1, prereleaseEnd, true)) return false;
4401
+ return plusIndex < 0 || areSemverIdentifiersValid(selector, plusIndex + 1, selector.length, false);
4402
+ }
4403
+ return suffixMarker === "+" && areSemverIdentifiersValid(selector, coreLength + 1, selector.length, false);
4404
+ }
4405
+ function assertRegistrySelector(selector) {
4406
+ const lowerSelector = selector.toLowerCase();
4407
+ const archiveSelector = lowerSelector.endsWith(".tgz") || lowerSelector.endsWith(".tar.gz");
4408
+ if (!isExactSemverSelector(selector) && !DIST_TAG_SELECTOR.test(selector) || archiveSelector) {
4409
+ throw new Error(
4410
+ `Invalid OpenClaw plugin version ${JSON.stringify(selector)}. Use an exact semantic version or npm dist-tag.`
4411
+ );
4412
+ }
4413
+ }
4414
+ function buildOpenclawManagedUpgradePackageSpec(version = "latest") {
4415
+ assertRegistrySelector(version);
4416
+ return `${OPENCLAW_PLUGIN_PACKAGE}@${version}`;
4417
+ }
4418
+ function readCliAdapterRange() {
4419
+ const moduleDir = path11.dirname(fileURLToPath3(import.meta.url));
4420
+ const manifestPath = path11.resolve(moduleDir, "../package.json");
4421
+ const manifest = JSON.parse(fs10.readFileSync(manifestPath, "utf8"));
4422
+ if (manifest.name !== "@remnic/cli") {
4423
+ throw new Error(`Invalid @remnic/cli package manifest at ${manifestPath}.`);
4424
+ }
4425
+ const peerDependencies = manifest.peerDependencies && typeof manifest.peerDependencies === "object" && !Array.isArray(manifest.peerDependencies) ? manifest.peerDependencies : {};
4426
+ const adapterRange = peerDependencies[OPENCLAW_PLUGIN_PACKAGE];
4427
+ if (typeof adapterRange !== "string" || !CARET_SEMVER_RANGE_SELECTOR.test(adapterRange)) {
4428
+ throw new Error(
4429
+ `Invalid ${OPENCLAW_PLUGIN_PACKAGE} peer dependency ${JSON.stringify(adapterRange)} in ${manifestPath}.`
4430
+ );
4431
+ }
4432
+ return adapterRange;
4433
+ }
4434
+ function assertOpenclawManagedUpgradePackageSpec(packageSpec) {
4435
+ const prefix = `${OPENCLAW_PLUGIN_PACKAGE}@`;
4436
+ if (!packageSpec.startsWith(prefix)) {
4437
+ throw new Error(`Invalid OpenClaw plugin package spec ${JSON.stringify(packageSpec)}.`);
4438
+ }
4439
+ assertRegistrySelector(packageSpec.slice(prefix.length));
4440
+ }
4441
+ function runNpmInstall(args) {
4442
+ execFileSync("npm", args, {
4443
+ encoding: "utf8",
4444
+ stdio: ["ignore", "pipe", "pipe"],
4445
+ timeout: NPM_INSTALL_TIMEOUT_MS
4446
+ });
4447
+ }
4448
+ function isManagedUpgradeSubpathMissing(error) {
4449
+ if (!error || typeof error !== "object" || !("code" in error)) return false;
4450
+ if (error.code !== "ERR_PACKAGE_PATH_NOT_EXPORTED" || !("message" in error)) return false;
4451
+ if (typeof error.message !== "string") return false;
4452
+ const namesManagedUpgradeSubpath = error.message.includes("'./managed-upgrade'") || error.message.includes('"./managed-upgrade"');
4453
+ const namesOpenclawAdapter = /[/\\]@remnic[/\\]plugin-openclaw[/\\]package\.json(?:\s|$)/.test(error.message);
4454
+ return namesManagedUpgradeSubpath && namesOpenclawAdapter;
4455
+ }
4456
+ async function loadOpenclawManagedUpgradeModule(packageSpec, hooks = {}) {
4457
+ assertOpenclawManagedUpgradePackageSpec(packageSpec);
4458
+ const importModule = hooks.importModule ?? ((specifier) => import(specifier));
4459
+ try {
4460
+ return await importModule(MANAGED_UPGRADE_SPECIFIER);
4461
+ } catch (error) {
4462
+ const adapterMissing = isSpecifierNotFoundError(error, OPENCLAW_PLUGIN_PACKAGE) || isSpecifierNotFoundError(error, MANAGED_UPGRADE_SPECIFIER) || isManagedUpgradeSubpathMissing(error);
4463
+ if (!adapterMissing) throw error;
4464
+ }
4465
+ const temporaryRoot = fs10.mkdtempSync(path11.join(os.tmpdir(), "remnic-openclaw-upgrade-"));
4466
+ try {
4467
+ const toolingPackageSpec = `${OPENCLAW_PLUGIN_PACKAGE}@${readCliAdapterRange()}`;
4468
+ const installArgs = [
4469
+ "install",
4470
+ "--ignore-scripts",
4471
+ "--no-save",
4472
+ "--omit=peer",
4473
+ "--fund=false",
4474
+ "--prefix",
4475
+ temporaryRoot,
4476
+ toolingPackageSpec
4477
+ ];
4478
+ (hooks.runNpmInstall ?? runNpmInstall)(installArgs);
4479
+ const resolverPath = path11.join(temporaryRoot, "load-managed-upgrade.mjs");
4480
+ fs10.writeFileSync(resolverPath, `export * from ${JSON.stringify(MANAGED_UPGRADE_SPECIFIER)};
4481
+ `, "utf8");
4482
+ return await importModule(pathToFileURL2(resolverPath).href);
4483
+ } finally {
4484
+ try {
4485
+ fs10.rmSync(temporaryRoot, { recursive: true, force: true });
4486
+ } catch (error) {
4487
+ const detail = error instanceof Error ? error.message : String(error);
4488
+ console.warn(`Could not remove temporary managed upgrade project at ${temporaryRoot}: ${detail}`);
4489
+ }
4490
+ }
4491
+ }
4492
+
4493
+ // src/daemon-service.ts
4494
+ import fs11 from "fs";
4495
+ import path12 from "path";
4362
4496
  import * as childProcess from "child_process";
4363
- import { fileURLToPath as fileURLToPath3 } from "url";
4364
- var thisModuleDir = path11.dirname(fileURLToPath3(import.meta.url));
4497
+ import { fileURLToPath as fileURLToPath4 } from "url";
4498
+ var thisModuleDir = path12.dirname(fileURLToPath4(import.meta.url));
4365
4499
  function launchdLoadPlist(plistPath, processApi = childProcess) {
4366
4500
  processApi.execFileSync("launchctl", ["load", "-w", plistPath], { stdio: "pipe" });
4367
4501
  }
@@ -4369,7 +4503,7 @@ function launchdUnloadPlist(plistPath, processApi = childProcess) {
4369
4503
  processApi.execFileSync("launchctl", ["unload", plistPath], { stdio: "pipe" });
4370
4504
  }
4371
4505
  function resolveServerBinDetails(options = {}) {
4372
- const existsSync4 = options.existsSync ?? fs10.existsSync;
4506
+ const existsSync4 = options.existsSync ?? fs11.existsSync;
4373
4507
  const findCommandOnPath2 = options.findCommandOnPath ?? findCommandOnPath;
4374
4508
  const moduleDir = options.moduleDir ?? thisModuleDir;
4375
4509
  const packageResolve = options.packageResolve ?? resolveImportSpecifier;
@@ -4383,8 +4517,8 @@ function resolveServerBinDetails(options = {}) {
4383
4517
  });
4384
4518
  } catch {
4385
4519
  }
4386
- const workspaceServerBin = path11.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
4387
- const workspaceDistIndex = path11.resolve(moduleDir, "../../remnic-server/dist/index.js");
4520
+ const workspaceServerBin = path12.resolve(moduleDir, "../../remnic-server/bin/remnic-server.js");
4521
+ const workspaceDistIndex = path12.resolve(moduleDir, "../../remnic-server/dist/index.js");
4388
4522
  candidates.push(
4389
4523
  {
4390
4524
  path: workspaceServerBin,
@@ -4405,11 +4539,11 @@ function resolveServerBinDetails(options = {}) {
4405
4539
  });
4406
4540
  }
4407
4541
  candidates.push({
4408
- path: path11.resolve(moduleDir, "../../remnic-server/src/index.ts"),
4542
+ path: path12.resolve(moduleDir, "../../remnic-server/src/index.ts"),
4409
4543
  source: "workspace-source"
4410
4544
  });
4411
4545
  const selected = candidates.find((candidate) => isCandidateReady(candidate, existsSync4)) ?? candidates.find((candidate) => existsSync4(candidate.path)) ?? candidates[0] ?? {
4412
- path: path11.resolve(moduleDir, "../../remnic-server/dist/index.js"),
4546
+ path: path12.resolve(moduleDir, "../../remnic-server/dist/index.js"),
4413
4547
  source: "workspace-dist"
4414
4548
  };
4415
4549
  const exists = existsSync4(selected.path);
@@ -4428,11 +4562,11 @@ function resolveServerBin(options = {}) {
4428
4562
  return resolveServerBinDetails(options).path;
4429
4563
  }
4430
4564
  function readVerifiedDaemonPid(options) {
4431
- const readFileSync4 = options.readFileSync ?? fs10.readFileSync;
4432
- const unlinkSync = options.unlinkSync ?? fs10.unlinkSync;
4565
+ const readFileSync4 = options.readFileSync ?? fs11.readFileSync;
4566
+ const unlinkSync = options.unlinkSync ?? fs11.unlinkSync;
4433
4567
  const processKill = options.processKill ?? process.kill;
4434
4568
  const platform = options.platform ?? process.platform;
4435
- const execFileSync3 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
4569
+ const execFileSync4 = options.execFileSync ?? ((command, args, execOptions) => childProcess.execFileSync(command, args, execOptions));
4436
4570
  for (const file of options.pidFiles) {
4437
4571
  let pid;
4438
4572
  try {
@@ -4450,7 +4584,7 @@ function readVerifiedDaemonPid(options) {
4450
4584
  removePidFileBestEffort(file, unlinkSync);
4451
4585
  continue;
4452
4586
  }
4453
- const command = readProcessCommand(pid, execFileSync3, platform);
4587
+ const command = readProcessCommand(pid, execFileSync4, platform);
4454
4588
  if (command === void 0) {
4455
4589
  removePidFileBestEffort(file, unlinkSync);
4456
4590
  continue;
@@ -4464,7 +4598,7 @@ function readVerifiedDaemonPid(options) {
4464
4598
  }
4465
4599
  function doesProcessCommandLookLikeRemnicDaemon(command, expectedServerBin) {
4466
4600
  const normalizedCommand = command.trim();
4467
- const normalizedExpected = path11.resolve(expandTilde(expectedServerBin));
4601
+ const normalizedExpected = path12.resolve(expandTilde(expectedServerBin));
4468
4602
  return normalizedCommand.includes(normalizedExpected) || /(?:^|\s|[/\\])(?:remnic-server|engram-server)(?:\.js)?(?:\s|$)/.test(normalizedCommand) || /@remnic[/\\]server[/\\]/.test(normalizedCommand) || /packages[/\\]remnic-server[/\\](?:bin[/\\]remnic-server\.js|dist[/\\]index\.js|src[/\\]index\.ts)/.test(normalizedCommand);
4469
4603
  }
4470
4604
  function parseDaemonPid(raw) {
@@ -4473,15 +4607,15 @@ function parseDaemonPid(raw) {
4473
4607
  const pid = Number(trimmed);
4474
4608
  return Number.isSafeInteger(pid) && pid > 0 ? pid : void 0;
4475
4609
  }
4476
- function readProcessCommand(pid, execFileSync3, platform) {
4610
+ function readProcessCommand(pid, execFileSync4, platform) {
4477
4611
  if (platform === "win32") {
4478
- return readWindowsProcessCommand(pid, execFileSync3);
4612
+ return readWindowsProcessCommand(pid, execFileSync4);
4479
4613
  }
4480
- return readPosixProcessCommand(pid, execFileSync3);
4614
+ return readPosixProcessCommand(pid, execFileSync4);
4481
4615
  }
4482
- function readPosixProcessCommand(pid, execFileSync3) {
4616
+ function readPosixProcessCommand(pid, execFileSync4) {
4483
4617
  try {
4484
- return execFileSync3("ps", ["-p", String(pid), "-o", "command="], {
4618
+ return execFileSync4("ps", ["-p", String(pid), "-o", "command="], {
4485
4619
  encoding: "utf8",
4486
4620
  stdio: "pipe"
4487
4621
  });
@@ -4489,11 +4623,11 @@ function readPosixProcessCommand(pid, execFileSync3) {
4489
4623
  return void 0;
4490
4624
  }
4491
4625
  }
4492
- function readWindowsProcessCommand(pid, execFileSync3) {
4626
+ function readWindowsProcessCommand(pid, execFileSync4) {
4493
4627
  const powerShellCommand = `$process = Get-CimInstance Win32_Process -Filter "ProcessId = ${pid}"; if ($null -ne $process) { $process.CommandLine }`;
4494
4628
  for (const command of ["powershell.exe", "powershell", "pwsh"]) {
4495
4629
  try {
4496
- const output = execFileSync3(
4630
+ const output = execFileSync4(
4497
4631
  command,
4498
4632
  ["-NoProfile", "-NonInteractive", "-Command", powerShellCommand],
4499
4633
  {
@@ -4508,7 +4642,7 @@ function readWindowsProcessCommand(pid, execFileSync3) {
4508
4642
  }
4509
4643
  }
4510
4644
  try {
4511
- const output = execFileSync3(
4645
+ const output = execFileSync4(
4512
4646
  "wmic",
4513
4647
  ["process", "where", ["processid", String(pid)].join("="), "get", "CommandLine", "/value"],
4514
4648
  {
@@ -4529,8 +4663,8 @@ function removePidFileBestEffort(file, unlinkSync) {
4529
4663
  }
4530
4664
  }
4531
4665
  function inspectLaunchdPlist(plistPath, options = {}) {
4532
- const existsSync4 = options.existsSync ?? fs10.existsSync;
4533
- const readFileSync4 = options.readFileSync ?? fs10.readFileSync;
4666
+ const existsSync4 = options.existsSync ?? fs11.existsSync;
4667
+ const readFileSync4 = options.readFileSync ?? fs11.readFileSync;
4534
4668
  if (!existsSync4(plistPath)) {
4535
4669
  return {
4536
4670
  installed: false,
@@ -4569,7 +4703,7 @@ function inspectLaunchdPlist(plistPath, options = {}) {
4569
4703
  };
4570
4704
  }
4571
4705
  const expandedServerArg = expandTilde(serverArg);
4572
- if (!path11.isAbsolute(expandedServerArg)) {
4706
+ if (!path12.isAbsolute(expandedServerArg)) {
4573
4707
  return {
4574
4708
  installed: true,
4575
4709
  ok: false,
@@ -4637,12 +4771,12 @@ function resolveImportSpecifier(specifier) {
4637
4771
  return resolver.call(import.meta, specifier);
4638
4772
  }
4639
4773
  function normalizeResolvedPath(resolved) {
4640
- if (resolved.startsWith("file:")) return fileURLToPath3(resolved);
4774
+ if (resolved.startsWith("file:")) return fileURLToPath4(resolved);
4641
4775
  return resolved;
4642
4776
  }
4643
4777
  function packageServerBinFromEntry(packageEntry) {
4644
- if (path11.basename(packageEntry) === "index.js" && path11.basename(path11.dirname(packageEntry)) === "dist") {
4645
- return path11.join(path11.dirname(path11.dirname(packageEntry)), "bin", "remnic-server.js");
4778
+ if (path12.basename(packageEntry) === "index.js" && path12.basename(path12.dirname(packageEntry)) === "dist") {
4779
+ return path12.join(path12.dirname(path12.dirname(packageEntry)), "bin", "remnic-server.js");
4646
4780
  }
4647
4781
  return packageEntry;
4648
4782
  }
@@ -4764,7 +4898,7 @@ function stripConfigArgv(args) {
4764
4898
  }
4765
4899
 
4766
4900
  // src/import-dispatch.ts
4767
- import fs11 from "fs";
4901
+ import fs12 from "fs";
4768
4902
  import {
4769
4903
  runImporter,
4770
4904
  validateImportBatchSize,
@@ -4773,7 +4907,7 @@ import {
4773
4907
 
4774
4908
  // src/import-bundle-detect.ts
4775
4909
  import { lstatSync as lstatSync2, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
4776
- import path12 from "path";
4910
+ import path13 from "path";
4777
4911
  function detectBundleEntries(bundleDir, options = {}) {
4778
4912
  const readdir3 = options.readdirImpl ?? defaultReaddir;
4779
4913
  const readFileImpl = options.readFileImpl ?? defaultReadFile;
@@ -4804,7 +4938,7 @@ function detectBundleEntries(bundleDir, options = {}) {
4804
4938
  for (const filePath of roots) {
4805
4939
  if (seenFiles.has(filePath)) continue;
4806
4940
  seenFiles.add(filePath);
4807
- const name = path12.basename(filePath);
4941
+ const name = path13.basename(filePath);
4808
4942
  const match = classifyFile(name, filePath, readFileImpl);
4809
4943
  if (match) entries.push(match);
4810
4944
  }
@@ -4842,7 +4976,7 @@ function collectCandidatePaths(root, readdir3, isDirectory2, isRegularFile) {
4842
4976
  return;
4843
4977
  }
4844
4978
  for (const entry of entries) {
4845
- const full = path12.join(dir, entry);
4979
+ const full = path13.join(dir, entry);
4846
4980
  if (isDirectory2(full)) {
4847
4981
  walk(full, depth + 1);
4848
4982
  } else if (isRegularFile(full)) {
@@ -5278,7 +5412,7 @@ async function cmdImport(rest, targetFactory, disposeTarget, ioOverrides = {}) {
5278
5412
  let materializedTarget;
5279
5413
  let materializePromise;
5280
5414
  const io = {
5281
- readFile: ioOverrides.readFile ?? (async (p) => fs11.promises.readFile(p, "utf-8")),
5415
+ readFile: ioOverrides.readFile ?? (async (p) => fs12.promises.readFile(p, "utf-8")),
5282
5416
  loadAdapter: ioOverrides.loadAdapter ?? (async (name) => (await loadImporterModule(name)).adapter),
5283
5417
  runImporter: ioOverrides.runImporter ?? runImporter,
5284
5418
  getWriteTarget: async () => {
@@ -5391,8 +5525,8 @@ async function cmdCapture(rest, io) {
5391
5525
  }
5392
5526
 
5393
5527
  // src/import-lossless-claw-cmd.ts
5394
- import fs12 from "fs";
5395
- import path13 from "path";
5528
+ import fs13 from "fs";
5529
+ import path14 from "path";
5396
5530
  import {
5397
5531
  applyLcmSchema,
5398
5532
  ensureLcmStateDir,
@@ -5503,15 +5637,15 @@ async function loadImportLosslessClawModule() {
5503
5637
 
5504
5638
  // src/import-lossless-claw-cmd.ts
5505
5639
  function assertDirectoryOrAbsent(p, label) {
5506
- if (fs12.existsSync(p) && !fs12.statSync(p).isDirectory()) {
5640
+ if (fs13.existsSync(p) && !fs13.statSync(p).isDirectory()) {
5507
5641
  throw new Error(`${label} is not a directory: ${p}`);
5508
5642
  }
5509
5643
  }
5510
5644
  function assertFile(p, label) {
5511
- if (!fs12.existsSync(p)) {
5645
+ if (!fs13.existsSync(p)) {
5512
5646
  throw new Error(`${label} does not exist: ${p}`);
5513
5647
  }
5514
- if (!fs12.statSync(p).isFile()) {
5648
+ if (!fs13.statSync(p).isFile()) {
5515
5649
  throw new Error(`${label} is not a file: ${p}`);
5516
5650
  }
5517
5651
  }
@@ -5542,8 +5676,8 @@ async function cmdImportLosslessClaw(argv, io, deps = {}) {
5542
5676
  let destDb;
5543
5677
  try {
5544
5678
  if (parsed.dryRun) {
5545
- const lcmPath = path13.join(memoryDir, "state", "lcm.sqlite");
5546
- if (fs12.existsSync(lcmPath)) {
5679
+ const lcmPath = path14.join(memoryDir, "state", "lcm.sqlite");
5680
+ if (fs13.existsSync(lcmPath)) {
5547
5681
  destDb = mod.openExistingLcmDatabaseReadOnly(lcmPath);
5548
5682
  } else {
5549
5683
  destDb = mod.openInMemoryDestinationDatabase();
@@ -5662,8 +5796,8 @@ function printBenchComparisonSummary(comparison, baseline, candidate) {
5662
5796
 
5663
5797
  // src/bench-coding-commands.ts
5664
5798
  import { lstat as lstat2, readFile as readFile2, realpath, stat } from "fs/promises";
5665
- import os from "os";
5666
- import path14 from "path";
5799
+ import os2 from "os";
5800
+ import path15 from "path";
5667
5801
  var UINT32_MAX = 4294967295;
5668
5802
  var FROZEN_GENERATOR_SEED = 81;
5669
5803
  var FROZEN_TASK_COUNT = 30;
@@ -5673,7 +5807,7 @@ var FROZEN_MAX_STEPS = 12;
5673
5807
  var FROZEN_MAX_TOOL_CALLS = 8;
5674
5808
  var FROZEN_MAX_OUTPUT_CHARS = 16384;
5675
5809
  var MAX_OUTPUT_BYTES = 16384;
5676
- var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR = path14.join(
5810
+ var DEFAULT_REPEATED_FAILURE_OUTPUT_DIR = path15.join(
5677
5811
  resolveHomeDir(),
5678
5812
  ".remnic",
5679
5813
  "bench",
@@ -6007,7 +6141,7 @@ function parseBenchCodingArgs(args) {
6007
6141
  throw new Error(`unknown bench coding subcommand ${args[0]}`);
6008
6142
  }
6009
6143
  function normalizeCommandPaths(command) {
6010
- const resolve2 = (value) => path14.resolve(expandTilde(value));
6144
+ const resolve2 = (value) => path15.resolve(expandTilde(value));
6011
6145
  if (command.kind === "repo-generate") {
6012
6146
  return { ...command, outputDir: resolve2(command.outputDir) };
6013
6147
  }
@@ -6038,23 +6172,23 @@ function normalizeCommandPaths(command) {
6038
6172
  return command;
6039
6173
  }
6040
6174
  async function canonicalProspectivePath(value) {
6041
- let candidate = path14.resolve(value);
6175
+ let candidate = path15.resolve(value);
6042
6176
  const missingSegments = [];
6043
6177
  while (true) {
6044
6178
  try {
6045
- return path14.join(await realpath(candidate), ...missingSegments.reverse());
6179
+ return path15.join(await realpath(candidate), ...missingSegments.reverse());
6046
6180
  } catch (error) {
6047
6181
  if (error.code !== "ENOENT") throw error;
6048
- const parent = path14.dirname(candidate);
6182
+ const parent = path15.dirname(candidate);
6049
6183
  if (parent === candidate) throw error;
6050
- missingSegments.push(path14.basename(candidate));
6184
+ missingSegments.push(path15.basename(candidate));
6051
6185
  candidate = parent;
6052
6186
  }
6053
6187
  }
6054
6188
  }
6055
6189
  function isSameOrDescendant(candidate, root) {
6056
- const relative = path14.relative(root, candidate);
6057
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path14.sep}`) && !path14.isAbsolute(relative);
6190
+ const relative = path15.relative(root, candidate);
6191
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path15.sep}`) && !path15.isAbsolute(relative);
6058
6192
  }
6059
6193
  async function pathExists(value) {
6060
6194
  try {
@@ -6073,7 +6207,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
6073
6207
  const configured = process.env[variable]?.trim();
6074
6208
  if (!configured) continue;
6075
6209
  const memoryRoot = await canonicalProspectivePath(
6076
- path14.resolve(expandTilde(configured))
6210
+ path15.resolve(expandTilde(configured))
6077
6211
  );
6078
6212
  if (isSameOrDescendant(canonicalOutput, memoryRoot)) {
6079
6213
  throw new Error(refusal);
@@ -6081,10 +6215,10 @@ async function assertSafeBenchmarkOutput(outputDir) {
6081
6215
  }
6082
6216
  let candidate = canonicalOutput;
6083
6217
  while (true) {
6084
- const hasProfile = await pathExists(path14.join(candidate, "profile.md"));
6085
- const hasMemoryData = await pathExists(path14.join(candidate, "facts")) || await pathExists(path14.join(candidate, "entities")) || await pathExists(path14.join(candidate, "state"));
6218
+ const hasProfile = await pathExists(path15.join(candidate, "profile.md"));
6219
+ const hasMemoryData = await pathExists(path15.join(candidate, "facts")) || await pathExists(path15.join(candidate, "entities")) || await pathExists(path15.join(candidate, "state"));
6086
6220
  if (hasProfile && hasMemoryData) throw new Error(refusal);
6087
- const parent = path14.dirname(candidate);
6221
+ const parent = path15.dirname(candidate);
6088
6222
  if (parent === candidate) break;
6089
6223
  candidate = parent;
6090
6224
  }
@@ -6096,7 +6230,7 @@ async function assertSafeBenchmarkOutput(outputDir) {
6096
6230
  async function assertH6StatsRunDirectory(runDir, commandName = "stats") {
6097
6231
  try {
6098
6232
  const parsed = JSON.parse(
6099
- await readFile2(path14.join(runDir, "run.json"), "utf8")
6233
+ await readFile2(path15.join(runDir, "run.json"), "utf8")
6100
6234
  );
6101
6235
  if (parsed.schemaVersion !== 1 || typeof parsed.runId !== "string" || parsed.runId.length === 0 || typeof parsed.suiteVersion !== "string" || !parsed.suiteVersion.startsWith("h6-failure-gate-v1-")) {
6102
6236
  throw new Error("invalid H6 metadata");
@@ -6106,7 +6240,7 @@ async function assertH6StatsRunDirectory(runDir, commandName = "stats") {
6106
6240
  }
6107
6241
  }
6108
6242
  function sanitizeOutput(output) {
6109
- const home = os.homedir();
6243
+ const home = os2.homedir();
6110
6244
  const safe = home.length > 1 ? output.replaceAll(home, "~") : output;
6111
6245
  if (Buffer.byteLength(safe, "utf8") <= MAX_OUTPUT_BYTES) return safe.trimEnd();
6112
6246
  const bounded = Buffer.from(safe, "utf8").subarray(0, MAX_OUTPUT_BYTES - 32).toString("utf8");
@@ -6155,7 +6289,7 @@ async function runRepoVerification(command, bench) {
6155
6289
  if (command.directory === void 0) {
6156
6290
  dataset = await requireFunction(bench, "loadCommittedH6BenchmarkDataset")();
6157
6291
  } else {
6158
- const serialized = await readFile2(path14.join(command.directory, "dataset.json"), "utf8").catch(
6292
+ const serialized = await readFile2(path15.join(command.directory, "dataset.json"), "utf8").catch(
6159
6293
  () => void 0
6160
6294
  );
6161
6295
  if (serialized === void 0) {
@@ -6283,7 +6417,7 @@ async function cmdBenchCoding(args) {
6283
6417
  }
6284
6418
 
6285
6419
  // src/bench-research-commands.ts
6286
- import path15 from "path";
6420
+ import path16 from "path";
6287
6421
  function emit(result) {
6288
6422
  if (result.output) {
6289
6423
  console.log(result.output);
@@ -6301,7 +6435,7 @@ async function runBenchResearchCommand(parsed) {
6301
6435
  emit(
6302
6436
  await runAttributeCliCommand({
6303
6437
  runRef: parsed.runRef,
6304
- resultsDir: parsed.resultsDir ?? path15.join(resolveHomeDir(), ".remnic", "bench", "results"),
6438
+ resultsDir: parsed.resultsDir ?? path16.join(resolveHomeDir(), ".remnic", "bench", "results"),
6305
6439
  memoryDir: parsed.memoryDir,
6306
6440
  qmdPath: parsed.qmdPath,
6307
6441
  collection: parsed.collection,
@@ -6570,15 +6704,15 @@ registerPublisher("omp", () => new LazyPluginPiPublisher("omp", (mod) => mod.Omp
6570
6704
  function readCompatEnv(primary, legacy) {
6571
6705
  return process.env[primary] ?? process.env[legacy];
6572
6706
  }
6573
- var PID_DIR = path16.join(resolveHomeDir(), ".remnic");
6574
- var LEGACY_PID_DIR = path16.join(resolveHomeDir(), ".engram");
6575
- var PID_FILE = path16.join(PID_DIR, "server.pid");
6576
- var LEGACY_PID_FILE = path16.join(LEGACY_PID_DIR, "server.pid");
6577
- var LOG_FILE = path16.join(PID_DIR, "server.log");
6578
- var LEGACY_LOG_FILE = path16.join(LEGACY_PID_DIR, "server.log");
6579
- var CLI_MODULE_DIR = path16.dirname(fileURLToPath4(import.meta.url));
6580
- var CLI_REPO_ROOT = path16.resolve(CLI_MODULE_DIR, "../../..");
6581
- var EVAL_RUNNER_PATH = path16.join(CLI_REPO_ROOT, "evals", "run.ts");
6707
+ var PID_DIR = path17.join(resolveHomeDir(), ".remnic");
6708
+ var LEGACY_PID_DIR = path17.join(resolveHomeDir(), ".engram");
6709
+ var PID_FILE = path17.join(PID_DIR, "server.pid");
6710
+ var LEGACY_PID_FILE = path17.join(LEGACY_PID_DIR, "server.pid");
6711
+ var LOG_FILE = path17.join(PID_DIR, "server.log");
6712
+ var LEGACY_LOG_FILE = path17.join(LEGACY_PID_DIR, "server.log");
6713
+ var CLI_MODULE_DIR = path17.dirname(fileURLToPath5(import.meta.url));
6714
+ var CLI_REPO_ROOT = path17.resolve(CLI_MODULE_DIR, "../../..");
6715
+ var EVAL_RUNNER_PATH = path17.join(CLI_REPO_ROOT, "evals", "run.ts");
6582
6716
  var OPENCLAW_GATEWAY_LABEL = "ai.openclaw.gateway";
6583
6717
  var CLI_SUCCESS_EXIT_GRACE_MS = 5e3;
6584
6718
  var CLI_OUTPUT_FLUSH_GRACE_MS = 250;
@@ -6743,7 +6877,7 @@ async function resolveAllBenchmarks() {
6743
6877
  if (packageBenchmarks) {
6744
6878
  return packageBenchmarks.filter((entry) => entry.runnerAvailable).map((entry) => entry.id);
6745
6879
  }
6746
- if (!fs13.existsSync(EVAL_RUNNER_PATH)) {
6880
+ if (!fs14.existsSync(EVAL_RUNNER_PATH)) {
6747
6881
  return [];
6748
6882
  }
6749
6883
  return BENCHMARK_CATALOG.filter((entry) => entry.category !== "ingestion").map((entry) => entry.id);
@@ -6791,17 +6925,17 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
6791
6925
  `Fallback benchmark runner does not support provider-backed, gateway, or thinking/timeout flags (${unsupportedOptions.join(", ")}). Build/install @remnic/bench to use those options.`
6792
6926
  );
6793
6927
  }
6794
- if (!fs13.existsSync(EVAL_RUNNER_PATH)) {
6928
+ if (!fs14.existsSync(EVAL_RUNNER_PATH)) {
6795
6929
  console.error(
6796
6930
  "Benchmark runner not found. Expected eval runner at evals/run.ts or a phase-1 @remnic/bench runtime export."
6797
6931
  );
6798
6932
  process.exit(1);
6799
6933
  }
6800
6934
  const tsxCandidates = [
6801
- path16.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
6802
- path16.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
6935
+ path17.join(CLI_REPO_ROOT, "node_modules", ".bin", "tsx"),
6936
+ path17.join(CLI_REPO_ROOT, "packages", "remnic-cli", "node_modules", ".bin", "tsx")
6803
6937
  ];
6804
- const tsxCmd = tsxCandidates.find((candidate) => fs13.existsSync(candidate)) ?? "tsx";
6938
+ const tsxCmd = tsxCandidates.find((candidate) => fs14.existsSync(candidate)) ?? "tsx";
6805
6939
  const fallbackOutputDir = createFallbackBenchOutputDir(
6806
6940
  parsed.resultsDir ?? resolveBenchOutputDir(),
6807
6941
  benchmarkId,
@@ -6818,7 +6952,7 @@ async function runBenchViaFallback(parsed, benchmarkId, runtimeProfile) {
6818
6952
  return resolveFallbackBenchResultPath(fallbackOutputDir);
6819
6953
  }
6820
6954
  function resolveBenchOutputDir() {
6821
- return path16.join(resolveHomeDir(), ".remnic", "bench", "results");
6955
+ return path17.join(resolveHomeDir(), ".remnic", "bench", "results");
6822
6956
  }
6823
6957
  var DOWNLOADABLE_BENCHMARK_DATASETS = [
6824
6958
  "ama-bench",
@@ -6863,8 +6997,8 @@ var MEMORY_AGENT_BENCH_SPLIT_FILENAMES = [
6863
6997
  ];
6864
6998
  var MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES = [
6865
6999
  "entity2id.json",
6866
- path16.join("processed_data", "Recsys_Redial", "entity2id.json"),
6867
- path16.join("Recsys_Redial", "entity2id.json")
7000
+ path17.join("processed_data", "Recsys_Redial", "entity2id.json"),
7001
+ path17.join("Recsys_Redial", "entity2id.json")
6868
7002
  ];
6869
7003
  var DOWNLOADED_DATASET_MARKERS = {
6870
7004
  "ama-bench": { anyOf: ["open_end_qa_set.jsonl"] },
@@ -6939,18 +7073,18 @@ var PERSONAMEM_DATASET_FILE_CANDIDATES = [
6939
7073
  "benchmark/benchmark.csv",
6940
7074
  "benchmark.csv"
6941
7075
  ];
6942
- var PERSONAMEM_COMPLETION_MARKER = path16.join(
7076
+ var PERSONAMEM_COMPLETION_MARKER = path17.join(
6943
7077
  "data",
6944
7078
  "chat_history_32k",
6945
7079
  ".download-complete"
6946
7080
  );
6947
7081
  function resolveRealpathWithinDataset(datasetPath, relativePath) {
6948
7082
  try {
6949
- const datasetRoot = fs13.realpathSync(datasetPath);
6950
- const candidatePath = path16.resolve(datasetRoot, relativePath);
6951
- const candidateRealPath = fs13.realpathSync(candidatePath);
6952
- const relativeToRoot = path16.relative(datasetRoot, candidateRealPath);
6953
- if (relativeToRoot.startsWith("..") || path16.isAbsolute(relativeToRoot)) {
7083
+ const datasetRoot = fs14.realpathSync(datasetPath);
7084
+ const candidatePath = path17.resolve(datasetRoot, relativePath);
7085
+ const candidateRealPath = fs14.realpathSync(candidatePath);
7086
+ const relativeToRoot = path17.relative(datasetRoot, candidateRealPath);
7087
+ if (relativeToRoot.startsWith("..") || path17.isAbsolute(relativeToRoot)) {
6954
7088
  return null;
6955
7089
  }
6956
7090
  return candidateRealPath;
@@ -7006,15 +7140,15 @@ function parseCsvRows(raw) {
7006
7140
  }
7007
7141
  function isPersonaMemDatasetComplete(datasetPath) {
7008
7142
  try {
7009
- const completionMarkerPath = path16.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
7010
- if (fs13.statSync(completionMarkerPath).isFile()) {
7143
+ const completionMarkerPath = path17.join(datasetPath, PERSONAMEM_COMPLETION_MARKER);
7144
+ if (fs14.statSync(completionMarkerPath).isFile()) {
7011
7145
  return true;
7012
7146
  }
7013
7147
  } catch {
7014
7148
  }
7015
7149
  const datasetFile = PERSONAMEM_DATASET_FILE_CANDIDATES.find((candidate) => {
7016
7150
  try {
7017
- return fs13.statSync(path16.join(datasetPath, candidate)).isFile();
7151
+ return fs14.statSync(path17.join(datasetPath, candidate)).isFile();
7018
7152
  } catch {
7019
7153
  return false;
7020
7154
  }
@@ -7023,7 +7157,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
7023
7157
  return false;
7024
7158
  }
7025
7159
  try {
7026
- const rows = parseCsvRows(fs13.readFileSync(path16.join(datasetPath, datasetFile), "utf8"));
7160
+ const rows = parseCsvRows(fs14.readFileSync(path17.join(datasetPath, datasetFile), "utf8"));
7027
7161
  if (rows.length < 2) {
7028
7162
  return false;
7029
7163
  }
@@ -7038,7 +7172,7 @@ function isPersonaMemDatasetComplete(datasetPath) {
7038
7172
  }
7039
7173
  return historyPaths.every((relativePath) => {
7040
7174
  const resolvedPath = resolveRealpathWithinDataset(datasetPath, relativePath);
7041
- return resolvedPath !== null && fs13.statSync(resolvedPath).isFile();
7175
+ return resolvedPath !== null && fs14.statSync(resolvedPath).isFile();
7042
7176
  });
7043
7177
  } catch {
7044
7178
  return false;
@@ -7046,14 +7180,14 @@ function isPersonaMemDatasetComplete(datasetPath) {
7046
7180
  }
7047
7181
  function hasDatasetFile(datasetPath, relativePath) {
7048
7182
  try {
7049
- return fs13.statSync(path16.join(datasetPath, relativePath)).isFile();
7183
+ return fs14.statSync(path17.join(datasetPath, relativePath)).isFile();
7050
7184
  } catch {
7051
7185
  return false;
7052
7186
  }
7053
7187
  }
7054
7188
  function hasMemoryAgentBenchEntityMapping(datasetPath) {
7055
- const absoluteDatasetPath = path16.resolve(datasetPath);
7056
- const roots = [absoluteDatasetPath, path16.dirname(absoluteDatasetPath)];
7189
+ const absoluteDatasetPath = path17.resolve(datasetPath);
7190
+ const roots = [absoluteDatasetPath, path17.dirname(absoluteDatasetPath)];
7057
7191
  return hasDatasetFile(absoluteDatasetPath, "entity2id.json") || roots.some(
7058
7192
  (root) => MEMORY_AGENT_BENCH_ENTITY_MAPPING_CANDIDATES.filter((relativePath) => relativePath !== "entity2id.json").some((relativePath) => hasDatasetFile(root, relativePath))
7059
7193
  );
@@ -7064,12 +7198,12 @@ function memoryAgentBenchDatasetHasRecSysSamples(datasetPath) {
7064
7198
  ...MEMORY_AGENT_BENCH_SPLIT_FILENAMES
7065
7199
  ];
7066
7200
  return candidateFilenames.some((filename) => {
7067
- const filePath = path16.join(datasetPath, filename);
7201
+ const filePath = path17.join(datasetPath, filename);
7068
7202
  try {
7069
- if (!fs13.statSync(filePath).isFile()) {
7203
+ if (!fs14.statSync(filePath).isFile()) {
7070
7204
  return false;
7071
7205
  }
7072
- const raw = fs13.readFileSync(filePath, "utf8");
7206
+ const raw = fs14.readFileSync(filePath, "utf8");
7073
7207
  return /"source"\s*:\s*"recsys[_-]/i.test(raw);
7074
7208
  } catch {
7075
7209
  return false;
@@ -7085,7 +7219,7 @@ function isMemoryAgentBenchDatasetComplete(datasetPath) {
7085
7219
  function isDatasetDownloaded(datasetPath, benchmarkId) {
7086
7220
  let stats;
7087
7221
  try {
7088
- stats = fs13.statSync(datasetPath);
7222
+ stats = fs14.statSync(datasetPath);
7089
7223
  } catch {
7090
7224
  return false;
7091
7225
  }
@@ -7095,7 +7229,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7095
7229
  const marker = DOWNLOADED_DATASET_MARKERS[benchmarkId];
7096
7230
  if (!marker) {
7097
7231
  try {
7098
- return fs13.readdirSync(datasetPath).length > 0;
7232
+ return fs14.readdirSync(datasetPath).length > 0;
7099
7233
  } catch {
7100
7234
  return false;
7101
7235
  }
@@ -7103,7 +7237,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7103
7237
  if (marker.allOf) {
7104
7238
  const hasAllRequiredFiles = marker.allOf.every((name) => {
7105
7239
  try {
7106
- return fs13.statSync(path16.join(datasetPath, name)).isFile();
7240
+ return fs14.statSync(path17.join(datasetPath, name)).isFile();
7107
7241
  } catch {
7108
7242
  return false;
7109
7243
  }
@@ -7115,7 +7249,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7115
7249
  if (marker.anyOf) {
7116
7250
  const hasMarkerFile = marker.anyOf.some((name) => {
7117
7251
  try {
7118
- return fs13.statSync(path16.join(datasetPath, name)).isFile();
7252
+ return fs14.statSync(path17.join(datasetPath, name)).isFile();
7119
7253
  } catch {
7120
7254
  return false;
7121
7255
  }
@@ -7133,7 +7267,7 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7133
7267
  }
7134
7268
  if (marker.ext) {
7135
7269
  try {
7136
- return fs13.readdirSync(datasetPath).some(
7270
+ return fs14.readdirSync(datasetPath).some(
7137
7271
  (name) => name.endsWith(marker.ext) && !marker.exclude?.includes(name)
7138
7272
  );
7139
7273
  } catch {
@@ -7143,9 +7277,9 @@ function isDatasetDownloaded(datasetPath, benchmarkId) {
7143
7277
  return false;
7144
7278
  }
7145
7279
  async function launchBenchUi(resultsDir) {
7146
- const benchUiDir = path16.join(CLI_REPO_ROOT, "packages", "bench-ui");
7280
+ const benchUiDir = path17.join(CLI_REPO_ROOT, "packages", "bench-ui");
7147
7281
  const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
7148
- if (!fs13.existsSync(path16.join(benchUiDir, "package.json"))) {
7282
+ if (!fs14.existsSync(path17.join(benchUiDir, "package.json"))) {
7149
7283
  console.error("ERROR: @remnic/bench-ui is not available in this checkout.");
7150
7284
  process.exit(1);
7151
7285
  }
@@ -7172,24 +7306,24 @@ async function launchBenchUi(resultsDir) {
7172
7306
  });
7173
7307
  }
7174
7308
  function resolveRepoDatasetRoot() {
7175
- const repoCandidate = path16.join(CLI_REPO_ROOT, "evals", "datasets");
7309
+ const repoCandidate = path17.join(CLI_REPO_ROOT, "evals", "datasets");
7176
7310
  if (isRepoCheckout()) {
7177
7311
  return repoCandidate;
7178
7312
  }
7179
- return path16.join(resolveHomeDir(), ".remnic", "bench", "datasets");
7313
+ return path17.join(resolveHomeDir(), ".remnic", "bench", "datasets");
7180
7314
  }
7181
7315
  function listDownloadableBenchmarks() {
7182
7316
  return [...DOWNLOADABLE_BENCHMARK_DATASETS];
7183
7317
  }
7184
7318
  function resolveDatasetDownloadScriptPath() {
7185
- const bundled = path16.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
7186
- if (fs13.existsSync(bundled)) {
7319
+ const bundled = path17.join(CLI_MODULE_DIR, "assets", "download-datasets.sh");
7320
+ if (fs14.existsSync(bundled)) {
7187
7321
  return bundled;
7188
7322
  }
7189
- return path16.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
7323
+ return path17.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
7190
7324
  }
7191
7325
  function isRepoCheckout() {
7192
- return fs13.existsSync(path16.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs13.existsSync(path16.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
7326
+ return fs14.existsSync(path17.join(CLI_REPO_ROOT, "pnpm-workspace.yaml")) && fs14.existsSync(path17.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh"));
7193
7327
  }
7194
7328
  function runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, jsonMode) {
7195
7329
  const stdio = jsonMode ? ["inherit", process.stderr, "inherit"] : "inherit";
@@ -7240,7 +7374,7 @@ function resolveBenchDatasetDir(benchmarkId, quick, datasetDirOverride) {
7240
7374
  if (quick) {
7241
7375
  return void 0;
7242
7376
  }
7243
- const datasetDir = path16.join(resolveRepoDatasetRoot(), benchmarkId);
7377
+ const datasetDir = path17.join(resolveRepoDatasetRoot(), benchmarkId);
7244
7378
  if (isDatasetDownloaded(datasetDir, benchmarkId)) {
7245
7379
  return datasetDir;
7246
7380
  }
@@ -7497,13 +7631,13 @@ async function exportBenchPackageResult(parsed) {
7497
7631
  process.exit(1);
7498
7632
  }
7499
7633
  const result = await loadBenchmarkResult(summary.path);
7500
- const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path16.dirname(summary.path), result.meta.id) : void 0;
7634
+ const reportCardProvenance = parsed.format === "html" ? await loadBenchmarkReportCardProvenance(path17.dirname(summary.path), result.meta.id) : void 0;
7501
7635
  const rendered = renderBenchmarkResultExport(result, parsed.format, {
7502
7636
  ...reportCardProvenance ? { reportCardProvenance } : {}
7503
7637
  });
7504
7638
  if (parsed.output) {
7505
- fs13.mkdirSync(path16.dirname(parsed.output), { recursive: true });
7506
- fs13.writeFileSync(parsed.output, rendered);
7639
+ fs14.mkdirSync(path17.dirname(parsed.output), { recursive: true });
7640
+ fs14.writeFileSync(parsed.output, rendered);
7507
7641
  console.log(`Exported ${summary.id} as ${parsed.format} to ${parsed.output}`);
7508
7642
  return;
7509
7643
  }
@@ -7520,7 +7654,7 @@ async function manageBenchDatasets(parsed) {
7520
7654
  process.exit(1);
7521
7655
  }
7522
7656
  const status = supported.map((benchmarkId) => {
7523
- const datasetPath = path16.join(datasetRoot, benchmarkId);
7657
+ const datasetPath = path17.join(datasetRoot, benchmarkId);
7524
7658
  return {
7525
7659
  benchmark: benchmarkId,
7526
7660
  downloaded: isDatasetDownloaded(datasetPath, benchmarkId),
@@ -7548,7 +7682,7 @@ async function manageBenchDatasets(parsed) {
7548
7682
  process.exit(1);
7549
7683
  }
7550
7684
  const scriptPath = resolveDatasetDownloadScriptPath();
7551
- if (!fs13.existsSync(scriptPath)) {
7685
+ if (!fs14.existsSync(scriptPath)) {
7552
7686
  console.error(`ERROR: dataset download script not found: ${scriptPath}`);
7553
7687
  process.exit(1);
7554
7688
  }
@@ -7558,7 +7692,7 @@ async function manageBenchDatasets(parsed) {
7558
7692
  runDatasetDownloadScript(scriptPath, benchmarkId, datasetRoot, parsed.json === true);
7559
7693
  downloaded.push({
7560
7694
  benchmark: benchmarkId,
7561
- path: path16.join(datasetRoot, benchmarkId)
7695
+ path: path17.join(datasetRoot, benchmarkId)
7562
7696
  });
7563
7697
  }
7564
7698
  if (parsed.json) {
@@ -7697,10 +7831,10 @@ async function calibrateBenchJudges(parsed, rawArgs) {
7697
7831
  }
7698
7832
  const bench = await loadBenchModule();
7699
7833
  const resultsDir = expandTilde(
7700
- parsed.resultsDir ?? path16.join(resolveHomeDir(), ".remnic", "bench", "results")
7834
+ parsed.resultsDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "results")
7701
7835
  );
7702
7836
  const calibrationDir = expandTilde(
7703
- parsed.calibrationDir ?? path16.join(resolveHomeDir(), ".remnic", "bench", "calibration")
7837
+ parsed.calibrationDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "calibration")
7704
7838
  );
7705
7839
  const stored = await bench.listBenchmarkResults(resultsDir);
7706
7840
  const allForBenchmark = stored.filter((entry) => entry.benchmark === benchmarkId);
@@ -7748,7 +7882,7 @@ async function calibrateBenchJudges(parsed, rawArgs) {
7748
7882
  );
7749
7883
  process.exit(1);
7750
7884
  }
7751
- const sourceResultSha256 = createHash4("sha256").update(fs13.readFileSync(latest.path)).digest("hex");
7885
+ const sourceResultSha256 = createHash4("sha256").update(fs14.readFileSync(latest.path)).digest("hex");
7752
7886
  const expandedManifestPath = expandTilde(manifestPath);
7753
7887
  if (!bench.resolveLocalLabJudgeProviderConfig) {
7754
7888
  console.error(
@@ -8163,7 +8297,7 @@ function loadPinnedLoCoMoTaskSelector(parsed) {
8163
8297
  }
8164
8298
  let decoded;
8165
8299
  try {
8166
- decoded = JSON.parse(fs13.readFileSync(parsed.taskIdsFile, "utf8"));
8300
+ decoded = JSON.parse(fs14.readFileSync(parsed.taskIdsFile, "utf8"));
8167
8301
  } catch (error) {
8168
8302
  throw new Error(
8169
8303
  `Unable to read --task-ids-file ${parsed.taskIdsFile}: ${error instanceof Error ? error.message : String(error)}`
@@ -8260,7 +8394,7 @@ async function loadPublishedPromotionHelpers() {
8260
8394
  return {
8261
8395
  async promoteArtifactsToPublished(args) {
8262
8396
  const { mkdirSync, readFileSync: readFileSync4, writeFileSync } = await import("fs");
8263
- const path17 = await import("path");
8397
+ const path18 = await import("path");
8264
8398
  mkdirSync(args.publishedOutDir, { recursive: true });
8265
8399
  if (args.artifactPaths.length === 0) {
8266
8400
  console.warn(
@@ -8277,13 +8411,13 @@ async function loadPublishedPromotionHelpers() {
8277
8411
  const modelSlug = args.model.replace(/[^a-zA-Z0-9_.-]/g, "-");
8278
8412
  const rawProfile = parsedObj.config?.runtimeProfile;
8279
8413
  const profileSlug = typeof rawProfile === "string" && rawProfile.length > 0 ? `-${rawProfile.replace(/[^a-zA-Z0-9_.-]/g, "-")}` : "";
8280
- const target = path17.join(
8414
+ const target = path18.join(
8281
8415
  args.publishedOutDir,
8282
8416
  `${today}-${args.benchmarkId}-${modelSlug}${profileSlug}-${gitShaShort}.json`
8283
8417
  );
8284
8418
  writeFileSync(target, raw, "utf8");
8285
8419
  console.log(
8286
- `[bench published] Promoted ${path17.basename(artifactPath)} \u2192 ${target}`
8420
+ `[bench published] Promoted ${path18.basename(artifactPath)} \u2192 ${target}`
8287
8421
  );
8288
8422
  }
8289
8423
  void benchModule;
@@ -8390,7 +8524,7 @@ async function runBenchViaPackage(parsed, benchmarkId, runtimeProfile, benchStat
8390
8524
  const previousCodexDiagnosticsDir = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV];
8391
8525
  const previousCodexDiagnosticsMode = process.env[CODEX_CLI_BENCH_DIAGNOSTICS_MODE_ENV];
8392
8526
  if (!previousCodexDiagnosticsDir) {
8393
- process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path16.join(
8527
+ process.env[CODEX_CLI_BENCH_DIAGNOSTICS_DIR_ENV] = path17.join(
8394
8528
  outputDir,
8395
8529
  "codex-cli-diagnostics"
8396
8530
  );
@@ -8538,7 +8672,7 @@ async function preparePersistedJudgeCalibrationAttachment(benchModule, benchmark
8538
8672
  );
8539
8673
  }
8540
8674
  const calibrationDir = expandTilde(
8541
- calibrationBinding.calibrationDir ?? path16.join(resolveHomeDir(), ".remnic", "bench", "calibration")
8675
+ calibrationBinding.calibrationDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "calibration")
8542
8676
  );
8543
8677
  const state = await benchModule.loadJudgeCalibrationState?.(benchmarkId, calibrationDir);
8544
8678
  if (!state) {
@@ -8835,7 +8969,7 @@ function resolveBenchReproDatasetDir(datasetDir) {
8835
8969
  return void 0;
8836
8970
  }
8837
8971
  try {
8838
- return fs13.realpathSync(datasetDir);
8972
+ return fs14.realpathSync(datasetDir);
8839
8973
  } catch {
8840
8974
  return datasetDir;
8841
8975
  }
@@ -8889,7 +9023,7 @@ async function writeBenchReproManifestForPackageRun(args) {
8889
9023
  }
8890
9024
  function loadStandaloneConvergeCommandConfig() {
8891
9025
  const configPath = resolveConfigPath();
8892
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
9026
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
8893
9027
  return parseConfig6(resolveRemnicConfigRecord5(raw));
8894
9028
  }
8895
9029
  function parseConvergePluginConfig(value) {
@@ -8908,23 +9042,23 @@ function loadConvergeCommandConfig() {
8908
9042
  return loadStandaloneConvergeCommandConfig();
8909
9043
  }
8910
9044
  function resolveConfigPath(cliPath) {
8911
- if (cliPath) return path16.resolve(expandTilde(cliPath));
9045
+ if (cliPath) return path17.resolve(expandTilde(cliPath));
8912
9046
  const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
8913
- if (envPath) return path16.resolve(expandTilde(envPath));
9047
+ if (envPath) return path17.resolve(expandTilde(envPath));
8914
9048
  const candidates = [
8915
- path16.join(process.cwd(), "remnic.config.json"),
8916
- path16.join(process.cwd(), "engram.config.json"),
8917
- path16.join(resolveHomeDir(), ".config", "remnic", "config.json"),
8918
- path16.join(resolveHomeDir(), ".config", "engram", "config.json")
9049
+ path17.join(process.cwd(), "remnic.config.json"),
9050
+ path17.join(process.cwd(), "engram.config.json"),
9051
+ path17.join(resolveHomeDir(), ".config", "remnic", "config.json"),
9052
+ path17.join(resolveHomeDir(), ".config", "engram", "config.json")
8919
9053
  ];
8920
9054
  for (const candidate of candidates) {
8921
- if (fs13.existsSync(candidate)) return candidate;
9055
+ if (fs14.existsSync(candidate)) return candidate;
8922
9056
  }
8923
- return path16.join(resolveHomeDir(), ".config", "remnic", "config.json");
9057
+ return path17.join(resolveHomeDir(), ".config", "remnic", "config.json");
8924
9058
  }
8925
9059
  function resolveExistingBenchRemnicConfigPath(cliPath) {
8926
9060
  const configPath = resolveConfigPath(cliPath);
8927
- if (fs13.existsSync(configPath)) {
9061
+ if (fs14.existsSync(configPath)) {
8928
9062
  return configPath;
8929
9063
  }
8930
9064
  if (cliPath) {
@@ -8934,7 +9068,7 @@ function resolveExistingBenchRemnicConfigPath(cliPath) {
8934
9068
  }
8935
9069
  function resolveExistingBenchOpenclawConfigPath(cliPath) {
8936
9070
  const configPath = resolveOpenclawConfigPath(cliPath);
8937
- if (fs13.existsSync(configPath)) {
9071
+ if (fs14.existsSync(configPath)) {
8938
9072
  return configPath;
8939
9073
  }
8940
9074
  if (cliPath) {
@@ -9034,34 +9168,34 @@ async function resolvePackageBenchRuntime(benchModule, parsed, runtimeProfile) {
9034
9168
  );
9035
9169
  }
9036
9170
  function normalizeMemoryDirPath(memoryDir) {
9037
- return path16.resolve(expandTilde(memoryDir));
9171
+ return path17.resolve(expandTilde(memoryDir));
9038
9172
  }
9039
9173
  function resolveMemoryDir() {
9040
9174
  const configMemoryDir = (() => {
9041
9175
  const envMemoryDir = readCompatEnv("REMNIC_MEMORY_DIR", "ENGRAM_MEMORY_DIR");
9042
9176
  if (envMemoryDir) return normalizeMemoryDirPath(envMemoryDir);
9043
9177
  const configPath = resolveConfigPath();
9044
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
9178
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
9045
9179
  const remnicCfg = resolveRemnicConfigRecord5(raw);
9046
9180
  if (typeof remnicCfg.memoryDir === "string" && remnicCfg.memoryDir.length > 0) {
9047
9181
  return normalizeMemoryDirPath(remnicCfg.memoryDir);
9048
9182
  }
9049
9183
  const home = resolveHomeDir();
9050
- const standalonePath = path16.join(home, ".remnic", "memory");
9051
- const legacyStandalonePath = path16.join(home, ".engram", "memory");
9052
- const openclawPath = path16.join(home, ".openclaw", "workspace", "memory", "local");
9053
- if (fs13.existsSync(standalonePath)) return standalonePath;
9054
- if (fs13.existsSync(legacyStandalonePath)) return legacyStandalonePath;
9184
+ const standalonePath = path17.join(home, ".remnic", "memory");
9185
+ const legacyStandalonePath = path17.join(home, ".engram", "memory");
9186
+ const openclawPath = path17.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
9187
+ if (fs14.existsSync(standalonePath)) return standalonePath;
9188
+ if (fs14.existsSync(legacyStandalonePath)) return legacyStandalonePath;
9055
9189
  return openclawPath;
9056
9190
  })();
9057
9191
  const manifestPath = getManifestPath();
9058
- if (fs13.existsSync(manifestPath)) {
9192
+ if (fs14.existsSync(manifestPath)) {
9059
9193
  try {
9060
9194
  const active = getActiveSpace();
9061
9195
  if (active?.memoryDir) {
9062
9196
  const activeMemoryDir = normalizeMemoryDirPath(active.memoryDir);
9063
- if (!fs13.existsSync(activeMemoryDir)) {
9064
- fs13.mkdirSync(activeMemoryDir, { recursive: true });
9197
+ if (!fs14.existsSync(activeMemoryDir)) {
9198
+ fs14.mkdirSync(activeMemoryDir, { recursive: true });
9065
9199
  }
9066
9200
  return activeMemoryDir;
9067
9201
  }
@@ -9095,25 +9229,28 @@ function resolveFlagStrict(args, flag) {
9095
9229
  }
9096
9230
  return value;
9097
9231
  }
9098
- var REMNIC_OPENCLAW_PLUGIN_ID = "openclaw-remnic";
9099
9232
  var REMNIC_OPENCLAW_LEGACY_PLUGIN_ID = "openclaw-engram";
9233
+ function resolveOpenclawStateDir() {
9234
+ const configuredStateDir = process.env.OPENCLAW_STATE_DIR?.trim();
9235
+ return configuredStateDir ? path17.resolve(expandTilde(configuredStateDir)) : path17.join(resolveHomeDir(), ".openclaw");
9236
+ }
9100
9237
  var DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR = [
9101
9238
  process.env.OPENCLAW_CONFIG_PATH,
9102
9239
  process.env.OPENCLAW_ENGRAM_CONFIG_PATH,
9103
- path16.join(resolveHomeDir(), ".openclaw", "openclaw.json")
9240
+ path17.join(resolveOpenclawStateDir(), "openclaw.json")
9104
9241
  ].filter(Boolean);
9105
9242
  function resolveOpenclawConfigPath(cliPath) {
9106
- if (cliPath) return path16.resolve(expandTilde(cliPath));
9243
+ if (cliPath) return path17.resolve(expandTilde(cliPath));
9107
9244
  const envPath = process.env.OPENCLAW_CONFIG_PATH || process.env.OPENCLAW_ENGRAM_CONFIG_PATH;
9108
- if (envPath) return path16.resolve(expandTilde(envPath));
9245
+ if (envPath) return path17.resolve(expandTilde(envPath));
9109
9246
  for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
9110
- if (fs13.existsSync(candidate)) return candidate;
9247
+ if (fs14.existsSync(candidate)) return candidate;
9111
9248
  }
9112
- return path16.join(resolveHomeDir(), ".openclaw", "openclaw.json");
9249
+ return path17.join(resolveOpenclawStateDir(), "openclaw.json");
9113
9250
  }
9114
9251
  function readOpenclawConfig(configPath) {
9115
- if (!fs13.existsSync(configPath)) return {};
9116
- const raw = fs13.readFileSync(configPath, "utf-8");
9252
+ if (!fs14.existsSync(configPath)) return {};
9253
+ const raw = fs14.readFileSync(configPath, "utf-8");
9117
9254
  let parsed;
9118
9255
  try {
9119
9256
  parsed = JSON.parse(raw);
@@ -9168,10 +9305,10 @@ function buildRemnicOpenclawHooksPolicy(legacyHooks, existingHooks) {
9168
9305
  function resolveOpenclawInstallMemoryDir(args) {
9169
9306
  const existingMemoryDir = (typeof args.existingNewEntryConfig.memoryDir === "string" ? args.existingNewEntryConfig.memoryDir : void 0) || (args.migrateLegacy && typeof args.legacyConfigToMerge.memoryDir === "string" ? args.legacyConfigToMerge.memoryDir : void 0);
9170
9307
  if (args.requestedMemoryDir) {
9171
- return path16.resolve(expandTilde(args.requestedMemoryDir));
9308
+ return path17.resolve(expandTilde(args.requestedMemoryDir));
9172
9309
  }
9173
9310
  if (existingMemoryDir) {
9174
- return path16.resolve(expandTilde(existingMemoryDir));
9311
+ return path17.resolve(expandTilde(existingMemoryDir));
9175
9312
  }
9176
9313
  return args.fallbackMemoryDir;
9177
9314
  }
@@ -9189,18 +9326,21 @@ function resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir) {
9189
9326
  if (!config || typeof config !== "object" || Array.isArray(config)) continue;
9190
9327
  const memoryDir = config.memoryDir;
9191
9328
  if (typeof memoryDir === "string" && memoryDir.trim().length > 0) {
9192
- return path16.resolve(expandTilde(memoryDir));
9329
+ return path17.resolve(expandTilde(memoryDir));
9193
9330
  }
9194
9331
  }
9195
9332
  return fallbackMemoryDir;
9196
9333
  }
9197
9334
  function resolveOpenclawPluginDir(cliPath) {
9198
- if (cliPath) return path16.resolve(expandTilde(cliPath));
9199
- return path16.join(resolveHomeDir(), ".openclaw", "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
9335
+ if (cliPath) return path17.resolve(expandTilde(cliPath));
9336
+ return resolveOpenclawManagedPluginDir();
9337
+ }
9338
+ function resolveOpenclawManagedPluginDir() {
9339
+ return path17.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
9200
9340
  }
9201
9341
  function resolveOpenclawLegacyPluginDir(cliPath) {
9202
- if (cliPath) return path16.resolve(expandTilde(cliPath));
9203
- return path16.join(resolveHomeDir(), ".openclaw", "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
9342
+ if (cliPath) return path17.resolve(expandTilde(cliPath));
9343
+ return path17.join(resolveOpenclawStateDir(), "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID);
9204
9344
  }
9205
9345
  function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
9206
9346
  const yyyy = now.getFullYear().toString();
@@ -9212,98 +9352,11 @@ function formatOpenclawUpgradeStamp(now = /* @__PURE__ */ new Date()) {
9212
9352
  return `${yyyy}${mm}${dd}-${hh}${min}${ss}`;
9213
9353
  }
9214
9354
  function backupPathIfPresent(sourcePath, backupPath) {
9215
- if (!fs13.existsSync(sourcePath)) return false;
9216
- fs13.mkdirSync(path16.dirname(backupPath), { recursive: true });
9217
- fs13.cpSync(sourcePath, backupPath, { recursive: true });
9355
+ if (!fs14.existsSync(sourcePath)) return false;
9356
+ fs14.mkdirSync(path17.dirname(backupPath), { recursive: true });
9357
+ fs14.cpSync(sourcePath, backupPath, { recursive: true });
9218
9358
  return true;
9219
9359
  }
9220
- function assertDirectoryPathOrMissing(targetPath, label) {
9221
- if (!fs13.existsSync(targetPath)) return;
9222
- const stat2 = fs13.statSync(targetPath);
9223
- if (!stat2.isDirectory()) {
9224
- throw new Error(`${label} must be a directory when it already exists: ${targetPath}`);
9225
- }
9226
- }
9227
- function describeErrorWithCause(error) {
9228
- const message = error instanceof Error ? error.message : String(error);
9229
- if (!(error instanceof Error) || !("cause" in error)) return message;
9230
- const cause = error.cause;
9231
- if (cause === void 0 || cause === null) return message;
9232
- const causeText = cause instanceof Error ? cause.message : String(cause);
9233
- if (!causeText || causeText === message) return message;
9234
- return `${message} Cause: ${causeText}`;
9235
- }
9236
- var PublishedOpenclawPluginInstallError = class extends Error {
9237
- rollbackDir;
9238
- shouldRestoreBackup;
9239
- constructor(message, options = {}) {
9240
- super(message, options);
9241
- this.name = "PublishedOpenclawPluginInstallError";
9242
- this.rollbackDir = options.rollbackDir;
9243
- this.shouldRestoreBackup = options.shouldRestoreBackup ?? false;
9244
- }
9245
- };
9246
- function installPublishedOpenclawPlugin(spec, pluginDir) {
9247
- const tempRoot = fs13.mkdtempSync(path16.join(os2.tmpdir(), "remnic-openclaw-upgrade-"));
9248
- const stagedDir = `${pluginDir}.next-${process.pid}-${Date.now()}`;
9249
- const rollbackDir = `${pluginDir}.rollback-${process.pid}-${Date.now()}`;
9250
- let swapRollbackDir;
9251
- let shouldRestoreBackup = false;
9252
- try {
9253
- const packOutput = childProcess2.execFileSync("npm", ["pack", spec], {
9254
- cwd: tempRoot,
9255
- encoding: "utf8",
9256
- stdio: ["ignore", "pipe", "pipe"]
9257
- });
9258
- const tarballName = packOutput.trim().split(/\r?\n/).map((line) => line.trim()).filter(Boolean).at(-1);
9259
- if (!tarballName) {
9260
- throw new Error(`npm pack ${spec} did not return a tarball name`);
9261
- }
9262
- const unpackDir = path16.join(tempRoot, "unpacked");
9263
- fs13.mkdirSync(unpackDir, { recursive: true });
9264
- childProcess2.execFileSync("tar", ["-xzf", path16.join(tempRoot, tarballName), "-C", unpackDir], {
9265
- stdio: ["ignore", "pipe", "pipe"]
9266
- });
9267
- const packagedDir = path16.join(unpackDir, "package");
9268
- if (!fs13.existsSync(packagedDir)) {
9269
- throw new Error(`npm pack ${spec} did not contain a package/ directory`);
9270
- }
9271
- fs13.rmSync(stagedDir, { recursive: true, force: true });
9272
- fs13.cpSync(packagedDir, stagedDir, { recursive: true });
9273
- childProcess2.execFileSync("npm", ["install", "--omit=dev"], {
9274
- cwd: stagedDir,
9275
- stdio: ["ignore", "pipe", "pipe"]
9276
- });
9277
- assertDirectoryPathOrMissing(pluginDir, "OpenClaw plugin dir");
9278
- const swapResult = (() => {
9279
- try {
9280
- return swapDirectoryWithRollback(stagedDir, pluginDir, rollbackDir);
9281
- } catch (swapError) {
9282
- shouldRestoreBackup = swapError instanceof AggregateError;
9283
- throw swapError;
9284
- }
9285
- })();
9286
- swapRollbackDir = swapResult.rollbackDir;
9287
- const installedPackageJsonPath = path16.join(pluginDir, "package.json");
9288
- const installedPackage = fs13.existsSync(installedPackageJsonPath) ? JSON.parse(fs13.readFileSync(installedPackageJsonPath, "utf8")) : {};
9289
- return {
9290
- rollbackDir: swapRollbackDir,
9291
- version: typeof installedPackage.version === "string" ? installedPackage.version : void 0
9292
- };
9293
- } catch (error) {
9294
- throw new PublishedOpenclawPluginInstallError(
9295
- `Failed to install published OpenClaw plugin from ${spec}.`,
9296
- {
9297
- cause: error,
9298
- rollbackDir: swapRollbackDir,
9299
- shouldRestoreBackup
9300
- }
9301
- );
9302
- } finally {
9303
- fs13.rmSync(stagedDir, { recursive: true, force: true });
9304
- fs13.rmSync(tempRoot, { recursive: true, force: true });
9305
- }
9306
- }
9307
9360
  function restartOpenclawGateway() {
9308
9361
  if (process.platform !== "darwin") {
9309
9362
  throw new Error(
@@ -9319,15 +9372,15 @@ function restartOpenclawGateway() {
9319
9372
  });
9320
9373
  }
9321
9374
  function cmdInit() {
9322
- const configPath = path16.join(process.cwd(), "remnic.config.json");
9323
- if (fs13.existsSync(configPath)) {
9375
+ const configPath = path17.join(process.cwd(), "remnic.config.json");
9376
+ if (fs14.existsSync(configPath)) {
9324
9377
  console.log(`Config already exists: ${configPath}`);
9325
9378
  return;
9326
9379
  }
9327
9380
  const template = {
9328
9381
  remnic: {
9329
9382
  openaiApiKey: "${OPENAI_API_KEY}",
9330
- memoryDir: path16.join(process.cwd(), ".remnic", "memory"),
9383
+ memoryDir: path17.join(process.cwd(), ".remnic", "memory"),
9331
9384
  memoryOsPreset: "balanced"
9332
9385
  },
9333
9386
  server: {
@@ -9336,7 +9389,7 @@ function cmdInit() {
9336
9389
  authToken: "${REMNIC_AUTH_TOKEN}"
9337
9390
  }
9338
9391
  };
9339
- fs13.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
9392
+ fs14.writeFileSync(configPath, JSON.stringify(template, null, 2) + "\n");
9340
9393
  console.log(`Created ${configPath}`);
9341
9394
  console.log("\nSet these environment variables:");
9342
9395
  console.log(" export OPENAI_API_KEY=sk-...");
@@ -9406,7 +9459,7 @@ async function cmdStatus(json) {
9406
9459
  }
9407
9460
  function oauthReadConfigRecord(configPath) {
9408
9461
  try {
9409
- const parsed = JSON.parse(fs13.readFileSync(configPath, "utf8"));
9462
+ const parsed = JSON.parse(fs14.readFileSync(configPath, "utf8"));
9410
9463
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
9411
9464
  return parsed;
9412
9465
  }
@@ -9464,7 +9517,7 @@ function oauthResolveOperatorToken() {
9464
9517
  }
9465
9518
  return void 0;
9466
9519
  }
9467
- async function oauthFetch(method, path17, token, body) {
9520
+ async function oauthFetch(method, path18, token, body) {
9468
9521
  const controller = new AbortController();
9469
9522
  const timeoutId = setTimeout(() => controller.abort(), 5e3);
9470
9523
  try {
@@ -9483,7 +9536,7 @@ async function oauthFetch(method, path17, token, body) {
9483
9536
  if (body !== void 0) {
9484
9537
  init.body = JSON.stringify(body);
9485
9538
  }
9486
- const response = await fetch(`${oauthResolveBaseUrl()}${path17}`, init);
9539
+ const response = await fetch(`${oauthResolveBaseUrl()}${path18}`, init);
9487
9540
  if (response.status === 401) {
9488
9541
  throw new Error(
9489
9542
  "operator token rejected by remnic-server (HTTP 401). Update `server.authToken` or `REMNIC_AUTH_TOKEN` to match the running daemon."
@@ -9822,7 +9875,7 @@ async function cmdQuery(queryText, json, explain) {
9822
9875
  }
9823
9876
  initLogger2();
9824
9877
  const configPath = resolveConfigPath();
9825
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
9878
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
9826
9879
  const remnicCfg = resolveRemnicConfigRecord5(raw);
9827
9880
  const config = parseConfig6(remnicCfg);
9828
9881
  const orchestrator = new Orchestrator3(config);
@@ -9993,7 +10046,7 @@ async function cmdXray(rest) {
9993
10046
  parseXrayCliOptions(rawQuery, options);
9994
10047
  initLogger2();
9995
10048
  const configPath = resolveConfigPath();
9996
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
10049
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
9997
10050
  const remnicCfg = resolveRemnicConfigRecord5(raw);
9998
10051
  const config = parseConfig6(remnicCfg);
9999
10052
  const orchestrator = new Orchestrator3(config);
@@ -10016,7 +10069,7 @@ async function cmdXray(rest) {
10016
10069
  async function cmdVersions(rest) {
10017
10070
  initLogger2();
10018
10071
  const configPath = resolveConfigPath();
10019
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
10072
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10020
10073
  const remnicCfg = resolveRemnicConfigRecord5(raw);
10021
10074
  const config = parseConfig6(remnicCfg);
10022
10075
  if (!config.versioningEnabled) {
@@ -10038,7 +10091,7 @@ async function cmdVersions(rest) {
10038
10091
  console.error("Usage: remnic versions list <page-path>");
10039
10092
  process.exit(1);
10040
10093
  }
10041
- const absPath = path16.resolve(pagePath);
10094
+ const absPath = path17.resolve(pagePath);
10042
10095
  const history = await listVersions(absPath, versioningConfig, memDir);
10043
10096
  if (json) {
10044
10097
  console.log(JSON.stringify(history, null, 2));
@@ -10063,7 +10116,7 @@ async function cmdVersions(rest) {
10063
10116
  console.error("Usage: remnic versions show <page-path> <version-id>");
10064
10117
  process.exit(1);
10065
10118
  }
10066
- const absPath = path16.resolve(pagePath);
10119
+ const absPath = path17.resolve(pagePath);
10067
10120
  try {
10068
10121
  const content = await getVersion(absPath, versionId, versioningConfig, memDir);
10069
10122
  console.log(content);
@@ -10081,7 +10134,7 @@ async function cmdVersions(rest) {
10081
10134
  console.error("Usage: remnic versions diff <page-path> <v1> <v2>");
10082
10135
  process.exit(1);
10083
10136
  }
10084
- const absPath = path16.resolve(pagePath);
10137
+ const absPath = path17.resolve(pagePath);
10085
10138
  try {
10086
10139
  const diffOutput = await diffVersions(absPath, v1, v2, versioningConfig, memDir);
10087
10140
  console.log(diffOutput);
@@ -10098,7 +10151,7 @@ async function cmdVersions(rest) {
10098
10151
  console.error("Usage: remnic versions revert <page-path> <version-id>");
10099
10152
  process.exit(1);
10100
10153
  }
10101
- const absPath = path16.resolve(pagePath);
10154
+ const absPath = path17.resolve(pagePath);
10102
10155
  try {
10103
10156
  const version = await revertToVersion(absPath, versionId, versioningConfig, void 0, memDir);
10104
10157
  if (json) {
@@ -10132,13 +10185,13 @@ Options:
10132
10185
  async function cmdEnrich(rest) {
10133
10186
  initLogger2();
10134
10187
  const configPath = resolveConfigPath();
10135
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
10188
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10136
10189
  const remnicCfg = resolveRemnicConfigRecord5(raw);
10137
10190
  const config = parseConfig6(remnicCfg);
10138
10191
  const subcommand = rest[0];
10139
10192
  if (subcommand === "audit") {
10140
10193
  const memoryDir2 = expandTilde(config.memoryDir);
10141
- const auditDir2 = path16.join(memoryDir2, "enrichment");
10194
+ const auditDir2 = path17.join(memoryDir2, "enrichment");
10142
10195
  const sinceFlag = resolveFlag(rest.slice(1), "--since");
10143
10196
  const entries = await readAuditLog(auditDir2, sinceFlag ?? void 0);
10144
10197
  if (entries.length === 0) {
@@ -10263,7 +10316,7 @@ Registered providers:`);
10263
10316
  return;
10264
10317
  }
10265
10318
  const memoryDir = expandTilde(config.memoryDir);
10266
- const auditDir = path16.join(memoryDir, "enrichment");
10319
+ const auditDir = path17.join(memoryDir, "enrichment");
10267
10320
  let totalPersisted = 0;
10268
10321
  for (const result of results) {
10269
10322
  for (const candidate of result.acceptedCandidates) {
@@ -10377,7 +10430,7 @@ Shared with:
10377
10430
  process.exit(1);
10378
10431
  }
10379
10432
  const configPath = resolveConfigPath();
10380
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
10433
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10381
10434
  const remnicCfg = resolveRemnicConfigRecord5(raw);
10382
10435
  const config = parseConfig6(remnicCfg);
10383
10436
  const memoryDir = expandTilde(
@@ -10394,7 +10447,7 @@ Shared with:
10394
10447
  async function cmdExtensions(action, rest) {
10395
10448
  initLogger2();
10396
10449
  const configPath = resolveConfigPath();
10397
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
10450
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10398
10451
  const remnicCfg = resolveRemnicConfigRecord5(raw);
10399
10452
  const config = parseConfig6(remnicCfg);
10400
10453
  const root = resolveExtensionsRoot(config);
@@ -10445,7 +10498,7 @@ Root: ${root}`);
10445
10498
  const extensions = await discoverMemoryExtensions(root, warnLog);
10446
10499
  let entries = [];
10447
10500
  try {
10448
- entries = fs13.readdirSync(root);
10501
+ entries = fs14.readdirSync(root);
10449
10502
  } catch {
10450
10503
  console.log(`Extensions root does not exist: ${root}`);
10451
10504
  process.exitCode = 0;
@@ -10454,9 +10507,9 @@ Root: ${root}`);
10454
10507
  const validNames = new Set(extensions.map((e) => e.name));
10455
10508
  let errors = 0;
10456
10509
  for (const entry of entries) {
10457
- const entryPath = path16.join(root, entry);
10510
+ const entryPath = path17.join(root, entry);
10458
10511
  try {
10459
- if (!fs13.statSync(entryPath).isDirectory()) continue;
10512
+ if (!fs14.statSync(entryPath).isDirectory()) continue;
10460
10513
  } catch {
10461
10514
  continue;
10462
10515
  }
@@ -10488,7 +10541,7 @@ Root: ${root}`);
10488
10541
  async function cmdBriefing(rest) {
10489
10542
  initLogger2();
10490
10543
  const configPath = resolveConfigPath();
10491
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
10544
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10492
10545
  const remnicCfg = resolveRemnicConfigRecord5(raw);
10493
10546
  const config = parseConfig6(remnicCfg);
10494
10547
  if (!config.briefing.enabled) {
@@ -10568,10 +10621,10 @@ async function cmdBriefing(rest) {
10568
10621
  if (save) {
10569
10622
  try {
10570
10623
  const saveDir = resolveBriefingSaveDir(config.briefing.saveDir);
10571
- fs13.mkdirSync(saveDir, { recursive: true });
10624
+ fs14.mkdirSync(saveDir, { recursive: true });
10572
10625
  const filename = briefingFilename(new Date(result.window.to), format);
10573
- const filePath = path16.join(saveDir, filename);
10574
- fs13.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
10626
+ const filePath = path17.join(saveDir, filename);
10627
+ fs14.writeFileSync(filePath, payload + (payload.endsWith("\n") ? "" : "\n"));
10575
10628
  console.error(`Saved briefing: ${filePath}`);
10576
10629
  } catch (err) {
10577
10630
  console.error(`Failed to save briefing: ${err instanceof Error ? err.message : String(err)}`);
@@ -10589,7 +10642,7 @@ async function cmdDoctor() {
10589
10642
  detail: `${nodeVersion} (requires >= 22.12.0)`
10590
10643
  });
10591
10644
  const configPath = resolveConfigPath();
10592
- const configExists = fs13.existsSync(configPath);
10645
+ const configExists = fs14.existsSync(configPath);
10593
10646
  checks.push({ name: "Config file", ok: configExists, detail: configPath });
10594
10647
  let standaloneConfig;
10595
10648
  let standaloneConfigError;
@@ -10597,7 +10650,7 @@ async function cmdDoctor() {
10597
10650
  let configuredNs = { invalid: false };
10598
10651
  if (configExists) {
10599
10652
  try {
10600
- const raw = JSON.parse(fs13.readFileSync(configPath, "utf8"));
10653
+ const raw = JSON.parse(fs14.readFileSync(configPath, "utf8"));
10601
10654
  const remnicCfg = resolveRemnicConfigRecord5(raw);
10602
10655
  standaloneOpenaiApiKeyExplicitlyFalse = isOpenaiApiKeyDisabled(remnicCfg.openaiApiKey);
10603
10656
  configuredNs = readConfiguredNamespace(remnicCfg);
@@ -10613,7 +10666,7 @@ async function cmdDoctor() {
10613
10666
  memoryDir = parseConfig6({}).memoryDir;
10614
10667
  }
10615
10668
  try {
10616
- fs13.mkdirSync(memoryDir, { recursive: true });
10669
+ fs14.mkdirSync(memoryDir, { recursive: true });
10617
10670
  checks.push({ name: "Memory directory", ok: true, detail: memoryDir });
10618
10671
  } catch {
10619
10672
  checks.push({ name: "Memory directory", ok: false, detail: `cannot create ${memoryDir}` });
@@ -10642,7 +10695,7 @@ async function cmdDoctor() {
10642
10695
  });
10643
10696
  if (nsPolicyCheck) checks.push(nsPolicyCheck);
10644
10697
  const openclawConfigPath = resolveOpenclawConfigPath();
10645
- const openclawConfigExists = fs13.existsSync(openclawConfigPath);
10698
+ const openclawConfigExists = fs14.existsSync(openclawConfigPath);
10646
10699
  let openclawConfig = {};
10647
10700
  let openclawConfigValid = false;
10648
10701
  let openclawPluginModeConfigured = false;
@@ -10650,7 +10703,7 @@ async function cmdDoctor() {
10650
10703
  let activeOpenclawEntryConfig = null;
10651
10704
  if (openclawConfigExists) {
10652
10705
  try {
10653
- const parsed = JSON.parse(fs13.readFileSync(openclawConfigPath, "utf-8"));
10706
+ const parsed = JSON.parse(fs14.readFileSync(openclawConfigPath, "utf-8"));
10654
10707
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
10655
10708
  openclawConfig = parsed;
10656
10709
  openclawConfigValid = true;
@@ -10726,13 +10779,13 @@ async function cmdDoctor() {
10726
10779
  const rawMemoryDir = entryConfig?.memoryDir;
10727
10780
  const configuredMemoryDir = typeof rawMemoryDir === "string" ? rawMemoryDir : void 0;
10728
10781
  if (configuredMemoryDir) {
10729
- const resolvedMemDir = path16.resolve(expandTilde(configuredMemoryDir));
10782
+ const resolvedMemDir = path17.resolve(expandTilde(configuredMemoryDir));
10730
10783
  let memDirOk = false;
10731
10784
  let memDirDetail = `${resolvedMemDir} (not found)`;
10732
10785
  let memDirRemediation = `Run \`remnic openclaw install --memory-dir "${resolvedMemDir}"\` to create the directory.`;
10733
- if (fs13.existsSync(resolvedMemDir)) {
10786
+ if (fs14.existsSync(resolvedMemDir)) {
10734
10787
  try {
10735
- const stat2 = fs13.statSync(resolvedMemDir);
10788
+ const stat2 = fs14.statSync(resolvedMemDir);
10736
10789
  if (stat2.isDirectory()) {
10737
10790
  memDirOk = true;
10738
10791
  memDirDetail = resolvedMemDir;
@@ -10874,12 +10927,12 @@ async function cmdDoctor() {
10874
10927
  }
10875
10928
  function cmdConfig() {
10876
10929
  const configPath = resolveConfigPath();
10877
- if (!fs13.existsSync(configPath)) {
10930
+ if (!fs14.existsSync(configPath)) {
10878
10931
  console.log("No config file found. Run `remnic init` to create one.");
10879
10932
  return;
10880
10933
  }
10881
10934
  console.log(`Config: ${configPath}`);
10882
- const rawConfig = fs13.readFileSync(configPath, "utf8");
10935
+ const rawConfig = fs14.readFileSync(configPath, "utf8");
10883
10936
  const redacted = rawConfig.replace(
10884
10937
  /("(?:openaiApiKey|localLlmApiKey|authToken|apiKey|remoteSearchApiKey|meilisearchApiKey|opikApiKey)"\s*:\s*")([^"]*)(")/g,
10885
10938
  "$1[REDACTED]$3"
@@ -10926,7 +10979,7 @@ async function cmdMigrate(json, rollback) {
10926
10979
  console.log(` Rollback: ${result.rollbackCommand}`);
10927
10980
  }
10928
10981
  function cmdOnboard(dirPath, json) {
10929
- const directory = path16.resolve(dirPath || process.cwd());
10982
+ const directory = path17.resolve(dirPath || process.cwd());
10930
10983
  const result = onboard({ directory });
10931
10984
  if (json) {
10932
10985
  console.log(JSON.stringify(result, null, 2));
@@ -10945,7 +10998,7 @@ Suggested namespace: ${result.plan.suggestedNamespace}`);
10945
10998
  async function cmdCurate(targetPath, json) {
10946
10999
  const memoryDir = resolveMemoryDir();
10947
11000
  const result = await curate({
10948
- targetPath: path16.resolve(targetPath),
11001
+ targetPath: path17.resolve(targetPath),
10949
11002
  memoryDir,
10950
11003
  source: "curation",
10951
11004
  checkDuplicates: true,
@@ -10987,7 +11040,7 @@ async function cmdReview(action, rest) {
10987
11040
  const configPath = resolveConfigPath();
10988
11041
  let tombstonesConfig = null;
10989
11042
  try {
10990
- const rawCfg = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
11043
+ const rawCfg = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
10991
11044
  const remnicCfg = resolveRemnicConfigRecord5(rawCfg);
10992
11045
  const config = parseConfig6(remnicCfg);
10993
11046
  tombstonesConfig = {
@@ -11074,8 +11127,8 @@ async function cmdSync(action, rest, json) {
11074
11127
  }
11075
11128
  }
11076
11129
  function localOfflineSourceId(memoryDir) {
11077
- const host = os2.hostname() || "unknown-host";
11078
- const dirHash = createHash4("sha256").update(path16.resolve(memoryDir)).digest("hex").slice(0, 16);
11130
+ const host = os3.hostname() || "unknown-host";
11131
+ const dirHash = createHash4("sha256").update(path17.resolve(memoryDir)).digest("hex").slice(0, 16);
11079
11132
  return `remnic-local:${host}:${dirHash}`;
11080
11133
  }
11081
11134
  function normalizeOfflineRemoteUrl(raw) {
@@ -11473,10 +11526,10 @@ var OFFLINE_SYNC_CONTENT_MISSING_RETRY_MAX = 3;
11473
11526
  var OFFLINE_SYNC_CONTENT_MISSING_RETRY_DELAY_MS = 250;
11474
11527
  var OfflineRemoteFileChangedError = class extends Error {
11475
11528
  path;
11476
- constructor(path17) {
11477
- super(`remote file changed while fetching offline content: ${path17}`);
11529
+ constructor(path18) {
11530
+ super(`remote file changed while fetching offline content: ${path18}`);
11478
11531
  this.name = "OfflineRemoteFileChangedError";
11479
- this.path = path17;
11532
+ this.path = path18;
11480
11533
  }
11481
11534
  };
11482
11535
  function isOfflineRemoteFileChangedError(error) {
@@ -11667,10 +11720,10 @@ function offlineDirectPushFiles(options) {
11667
11720
  }).sort((left, right) => right.bytes - left.bytes || left.path.localeCompare(right.path));
11668
11721
  }
11669
11722
  function resolveOfflineDirectHydrationPath(memoryDir, relPath) {
11670
- const base = path16.resolve(memoryDir);
11671
- const target = path16.resolve(base, relPath);
11672
- const relative = path16.relative(base, target);
11673
- if (relative === "" || relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
11723
+ const base = path17.resolve(memoryDir);
11724
+ const target = path17.resolve(base, relPath);
11725
+ const relative = path17.relative(base, target);
11726
+ if (relative === "" || relative === ".." || relative.startsWith(`..${path17.sep}`) || path17.isAbsolute(relative)) {
11674
11727
  throw new Error(`offline sync direct hydration path escapes memory dir: ${relPath}`);
11675
11728
  }
11676
11729
  return target;
@@ -11740,13 +11793,13 @@ async function pushOfflineFileContent(args) {
11740
11793
  }
11741
11794
  async function pushOfflineFileContentFromChunkReader(args) {
11742
11795
  const filePath = resolveOfflineDirectHydrationPath(args.memoryDir, args.file.path);
11743
- const stat2 = fs13.statSync(filePath);
11796
+ const stat2 = fs14.statSync(filePath);
11744
11797
  if (stat2.mtimeMs !== args.file.mtimeMs) {
11745
11798
  throw new Error(`local file changed while pushing offline content: ${args.file.path}`);
11746
11799
  }
11747
11800
  const hash = createHash4("sha256");
11748
11801
  const chunks = args.readFileChunks({
11749
- root: path16.resolve(args.memoryDir),
11802
+ root: path17.resolve(args.memoryDir),
11750
11803
  path: args.file.path,
11751
11804
  filePath,
11752
11805
  chunkSize: OFFLINE_SYNC_FILE_CONTENT_UPLOAD_CHUNK_BYTES
@@ -12231,7 +12284,7 @@ function advanceOfflineBaseFilesForSuccessfulPush(options) {
12231
12284
  return [...next.values()].sort((left, right) => left.path.localeCompare(right.path));
12232
12285
  }
12233
12286
  async function runOfflineSyncOnce(options) {
12234
- fs13.mkdirSync(options.memoryDir, { recursive: true });
12287
+ fs14.mkdirSync(options.memoryDir, { recursive: true });
12235
12288
  let activeStatePath = options.statePath;
12236
12289
  let priorState = await readOfflineSyncState(activeStatePath);
12237
12290
  let syncNamespace = options.namespace ?? priorState?.namespace;
@@ -12851,7 +12904,7 @@ Environment fallbacks:
12851
12904
  REMNIC_OFFLINE_REMOTE_URL, REMNIC_OFFLINE_TOKEN, REMNIC_AUTH_TOKEN`);
12852
12905
  return;
12853
12906
  }
12854
- const memoryDir = path16.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
12907
+ const memoryDir = path17.resolve(expandTilde(resolveRequiredValueFlag(rest, "--memory-dir") ?? resolveMemoryDir()));
12855
12908
  const namespace = resolveRequiredValueFlag(rest, "--namespace");
12856
12909
  const includeTranscripts = !hasFlag(rest, "--no-transcripts");
12857
12910
  const stateOverride = resolveRequiredValueFlag(rest, "--state");
@@ -12859,7 +12912,7 @@ Environment fallbacks:
12859
12912
  const configPath = resolveConfigPath();
12860
12913
  let config;
12861
12914
  try {
12862
- const rawConfig = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
12915
+ const rawConfig = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
12863
12916
  config = parseConfigQuietly(pickOfflineConfigRecord(rawConfig));
12864
12917
  } catch {
12865
12918
  throw new Error(
@@ -12871,10 +12924,10 @@ Environment fallbacks:
12871
12924
  const needsRemote = action === "prepare" || action === "sync" || action === "watch";
12872
12925
  const remoteUrl = needsRemote ? resolveOfflineRemoteUrl(rest) : resolveOptionalOfflineRemoteUrl(rest);
12873
12926
  const token = needsRemote ? resolveOfflineToken(rest) : void 0;
12874
- const statePath = statePathExplicit ? path16.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
12927
+ const statePath = statePathExplicit ? path17.resolve(expandTilde(stateOverride)) : remoteUrl !== void 0 ? defaultOfflineSyncStatePath(memoryDir, remoteUrl, namespace) : void 0;
12875
12928
  if (action === "prepare") {
12876
12929
  if (!remoteUrl || !token || !statePath) throw new Error("offline prepare requires remote URL and token");
12877
- fs13.mkdirSync(memoryDir, { recursive: true });
12930
+ fs14.mkdirSync(memoryDir, { recursive: true });
12878
12931
  const remoteSnapshot = await fetchOfflineSnapshot({
12879
12932
  remoteUrl,
12880
12933
  token,
@@ -12973,7 +13026,7 @@ Environment fallbacks:
12973
13026
  return;
12974
13027
  }
12975
13028
  if (action === "status") {
12976
- fs13.mkdirSync(memoryDir, { recursive: true });
13029
+ fs14.mkdirSync(memoryDir, { recursive: true });
12977
13030
  const state = statePath ? await readOfflineSyncState(statePath) : null;
12978
13031
  if (state && remoteUrl && statePath) {
12979
13032
  assertOfflineStateMatches({
@@ -13053,11 +13106,11 @@ Environment fallbacks:
13053
13106
  failures: result.largeFilePushFailures
13054
13107
  });
13055
13108
  largeFileFailureCounts = advanced.counts;
13056
- for (const path17 of advanced.newlySkipped) {
13057
- if (skippedLargeFiles.has(path17)) continue;
13058
- skippedLargeFiles.add(path17);
13109
+ for (const path18 of advanced.newlySkipped) {
13110
+ if (skippedLargeFiles.has(path18)) continue;
13111
+ skippedLargeFiles.add(path18);
13059
13112
  console.warn(
13060
- `offline sync: permanently skipping ${path17} 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)`
13113
+ `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)`
13061
13114
  );
13062
13115
  }
13063
13116
  const pulled = result.pull ? result.pull.upserted + result.pull.deleted : 0;
@@ -13072,11 +13125,11 @@ Environment fallbacks:
13072
13125
  failures: error.failures
13073
13126
  });
13074
13127
  largeFileFailureCounts = advanced.counts;
13075
- for (const path17 of advanced.newlySkipped) {
13076
- if (skippedLargeFiles.has(path17)) continue;
13077
- skippedLargeFiles.add(path17);
13128
+ for (const path18 of advanced.newlySkipped) {
13129
+ if (skippedLargeFiles.has(path18)) continue;
13130
+ skippedLargeFiles.add(path18);
13078
13131
  console.warn(
13079
- `offline sync: permanently skipping ${path17} 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)`
13132
+ `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)`
13080
13133
  );
13081
13134
  }
13082
13135
  }
@@ -13111,7 +13164,7 @@ function cmdDedup(json) {
13111
13164
  function readInstalledConnectorConfig(configPath, fallback) {
13112
13165
  if (!configPath) return fallback;
13113
13166
  try {
13114
- const parsed = JSON.parse(fs13.readFileSync(configPath, "utf8"));
13167
+ const parsed = JSON.parse(fs14.readFileSync(configPath, "utf8"));
13115
13168
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return fallback;
13116
13169
  const { token: _token, ...config } = parsed;
13117
13170
  return config;
@@ -13217,7 +13270,7 @@ async function cmdConnectors(action, rest, json) {
13217
13270
  const connectorDaemonUrl = typeof effectiveConnectorConfig.remnicDaemonUrl === "string" && effectiveConnectorConfig.remnicDaemonUrl.trim().length > 0 ? effectiveConnectorConfig.remnicDaemonUrl.trim() : void 0;
13218
13271
  const pubResult = await pub.publish({
13219
13272
  config: { memoryDir, namespace: connectorNamespace, daemonUrl: connectorDaemonUrl },
13220
- skillsRoot: path16.join(memoryDir, "skills"),
13273
+ skillsRoot: path17.join(memoryDir, "skills"),
13221
13274
  rollbackTokenEntry: preInstallTokenEntry,
13222
13275
  log: { info: console.log, warn: console.warn, error: console.error }
13223
13276
  });
@@ -13289,7 +13342,7 @@ async function cmdConnectors(action, rest, json) {
13289
13342
  const pub = factory();
13290
13343
  const available = await pub.isHostAvailable();
13291
13344
  const extRoot = available ? await pub.resolveExtensionRoot() : "(host not installed)";
13292
- const extensionExists = available && extRoot ? fs13.existsSync(extRoot) : false;
13345
+ const extensionExists = available && extRoot ? fs14.existsSync(extRoot) : false;
13293
13346
  publisherChecks.push({
13294
13347
  name: `Publisher: ${targetHostId}`,
13295
13348
  ok: !available || extensionExists,
@@ -13363,7 +13416,7 @@ async function cmdConnectors(action, rest, json) {
13363
13416
  let connectorsCfg;
13364
13417
  const configPath = resolveConfigPath();
13365
13418
  try {
13366
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
13419
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13367
13420
  connectorsCfg = parseConfigQuietly(raw).connectors;
13368
13421
  } catch {
13369
13422
  process.stderr.write(
@@ -13439,7 +13492,7 @@ async function cmdConnectors(action, rest, json) {
13439
13492
  }
13440
13493
  initLogger2();
13441
13494
  const configPath = resolveConfigPath();
13442
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
13495
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13443
13496
  const remnicCfg = resolveRemnicConfigRecord5(raw);
13444
13497
  const config = parseConfig6(remnicCfg);
13445
13498
  const orchestrator = new Orchestrator3(config);
@@ -13564,7 +13617,7 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
13564
13617
  console.error(`connectors marketplace: ${err instanceof Error ? err.message : String(err)}`);
13565
13618
  process.exit(1);
13566
13619
  }
13567
- const rawConfig = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
13620
+ const rawConfig = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13568
13621
  const pluginConfig = resolveRemnicConfigRecord5(rawConfig);
13569
13622
  const config = parseConfig6(pluginConfig);
13570
13623
  if (subAction === "generate") {
@@ -13577,22 +13630,22 @@ async function cmdConnectorsMarketplace(subAction, rest, json) {
13577
13630
  }
13578
13631
  const manifest = generateMarketplaceManifest();
13579
13632
  await writeMarketplaceManifest(outputDir, manifest);
13580
- const outPath = path16.join(outputDir, "marketplace.json");
13633
+ const outPath = path17.join(outputDir, "marketplace.json");
13581
13634
  if (json) {
13582
13635
  console.log(JSON.stringify({ status: "generated", path: outPath }, null, 2));
13583
13636
  } else {
13584
13637
  console.log(`Generated marketplace.json at ${outPath}`);
13585
13638
  }
13586
13639
  } else if (subAction === "validate") {
13587
- const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path16.join(process.cwd(), "marketplace.json");
13588
- const resolved = path16.resolve(targetPath);
13589
- if (!fs13.existsSync(resolved)) {
13640
+ const targetPath = rest.filter((a) => !a.startsWith("--"))[0] ?? path17.join(process.cwd(), "marketplace.json");
13641
+ const resolved = path17.resolve(targetPath);
13642
+ if (!fs14.existsSync(resolved)) {
13590
13643
  console.error(`File not found: ${resolved}`);
13591
13644
  process.exit(1);
13592
13645
  }
13593
13646
  let parsed;
13594
13647
  try {
13595
- parsed = JSON.parse(fs13.readFileSync(resolved, "utf8"));
13648
+ parsed = JSON.parse(fs14.readFileSync(resolved, "utf8"));
13596
13649
  } catch {
13597
13650
  console.error(`Invalid JSON in ${resolved}`);
13598
13651
  process.exit(1);
@@ -13793,7 +13846,7 @@ async function cmdSpace(action, rest, json) {
13793
13846
  async function cmdLegacyBenchmark(action, rest, json) {
13794
13847
  initLogger2();
13795
13848
  const configPath = resolveConfigPath();
13796
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
13849
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
13797
13850
  const remnicCfg = resolveRemnicConfigRecord5(raw);
13798
13851
  const config = parseConfig6(remnicCfg);
13799
13852
  const orchestrator = new Orchestrator3(config);
@@ -13994,7 +14047,7 @@ async function cmdBench(rest) {
13994
14047
  }
13995
14048
  const completeCount = prevStatus.benchmarks.filter((b) => b.status === "complete").length;
13996
14049
  const failedCount = prevStatus.benchmarks.filter((b) => b.status === "failed").length;
13997
- printBenchStatusLine(parsed.json, `Resuming from: ${path16.basename(latestStatusPath)}`);
14050
+ printBenchStatusLine(parsed.json, `Resuming from: ${path17.basename(latestStatusPath)}`);
13998
14051
  printBenchStatusLine(parsed.json, ` Previous run: ${prevStatus.startedAt}`);
13999
14052
  printBenchStatusLine(parsed.json, ` Benchmarks: ${prevStatus.benchmarks.length} total, ${completeCount} complete, ${failedCount} failed`);
14000
14053
  const before = selectedBenchmarks.length;
@@ -14162,9 +14215,9 @@ Options:
14162
14215
  );
14163
14216
  process.exit(1);
14164
14217
  } else {
14165
- fixturePath = path16.resolve(expandTilde(fixturePathRaw));
14218
+ fixturePath = path17.resolve(expandTilde(fixturePathRaw));
14166
14219
  }
14167
- const outPath = path16.resolve(expandTilde(outPathRaw));
14220
+ const outPath = path17.resolve(expandTilde(outPathRaw));
14168
14221
  const benchModule = await loadBenchModule();
14169
14222
  const runner = benchModule.runProceduralAblationCli;
14170
14223
  if (typeof runner !== "function") {
@@ -14183,7 +14236,7 @@ Options:
14183
14236
  );
14184
14237
  console.log(`wrote ${outPath}`);
14185
14238
  }
14186
- var LOGS_DIR = path16.join(PID_DIR, "logs");
14239
+ var LOGS_DIR = path17.join(PID_DIR, "logs");
14187
14240
  var LAUNCHD_PLIST_PATHS = launchdPlistPaths(resolveHomeDir());
14188
14241
  var [LAUNCHD_PLIST_PATH] = LAUNCHD_PLIST_PATHS;
14189
14242
  var SYSTEMD_UNIT_PATHS = systemdUnitPaths(resolveHomeDir());
@@ -14197,7 +14250,7 @@ function readPid() {
14197
14250
  function inferPort() {
14198
14251
  try {
14199
14252
  const configPath = resolveConfigPath();
14200
- const raw = JSON.parse(fs13.readFileSync(configPath, "utf8"));
14253
+ const raw = JSON.parse(fs14.readFileSync(configPath, "utf8"));
14201
14254
  return raw.server?.port ?? 4318;
14202
14255
  } catch {
14203
14256
  return 4318;
@@ -14260,7 +14313,7 @@ function selectLaunchdInspection(openclawPluginModeConfigured) {
14260
14313
  for (const plistPath of LAUNCHD_PLIST_PATHS.slice(1)) {
14261
14314
  const legacy = inspectLaunchdPlist(plistPath);
14262
14315
  if (!legacy.installed) continue;
14263
- const label = path16.basename(plistPath, ".plist");
14316
+ const label = path17.basename(plistPath, ".plist");
14264
14317
  return legacy.ok ? {
14265
14318
  ...legacy,
14266
14319
  warn: true,
@@ -14292,13 +14345,13 @@ function daemonInstall() {
14292
14345
  process.exit(1);
14293
14346
  }
14294
14347
  const vars = { HOME: home, NODE_PATH: nodePath, REMNIC_SERVER_BIN: serverBin };
14295
- fs13.mkdirSync(LOGS_DIR, { recursive: true });
14348
+ fs14.mkdirSync(LOGS_DIR, { recursive: true });
14296
14349
  if (isMacOS()) {
14297
- const templatePath = path16.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
14298
- const template = fs13.readFileSync(templatePath, "utf8");
14350
+ const templatePath = path17.resolve(import.meta.dirname, "../templates/launchd/ai.remnic.daemon.plist");
14351
+ const template = fs14.readFileSync(templatePath, "utf8");
14299
14352
  const plist = renderTemplate(template, vars);
14300
- fs13.mkdirSync(path16.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
14301
- fs13.writeFileSync(LAUNCHD_PLIST_PATH, plist);
14353
+ fs14.mkdirSync(path17.dirname(LAUNCHD_PLIST_PATH), { recursive: true });
14354
+ fs14.writeFileSync(LAUNCHD_PLIST_PATH, plist);
14302
14355
  try {
14303
14356
  launchdLoadPlist(LAUNCHD_PLIST_PATH);
14304
14357
  } catch (err) {
@@ -14314,11 +14367,11 @@ function daemonInstall() {
14314
14367
  console.log(` RunAtLoad: true, KeepAlive: true`);
14315
14368
  console.log(` Logs: ${LOGS_DIR}/daemon.log`);
14316
14369
  } else if (isLinux()) {
14317
- const templatePath = path16.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
14318
- const template = fs13.readFileSync(templatePath, "utf8");
14370
+ const templatePath = path17.resolve(import.meta.dirname, "../templates/systemd/remnic.service");
14371
+ const template = fs14.readFileSync(templatePath, "utf8");
14319
14372
  const unit = renderTemplate(template, vars);
14320
- fs13.mkdirSync(path16.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
14321
- fs13.writeFileSync(SYSTEMD_UNIT_PATH, unit);
14373
+ fs14.mkdirSync(path17.dirname(SYSTEMD_UNIT_PATH), { recursive: true });
14374
+ fs14.writeFileSync(SYSTEMD_UNIT_PATH, unit);
14322
14375
  try {
14323
14376
  childProcess2.execSync("systemctl --user daemon-reload", { stdio: "pipe" });
14324
14377
  } catch (err) {
@@ -14354,7 +14407,7 @@ function daemonUninstall() {
14354
14407
  } catch {
14355
14408
  }
14356
14409
  try {
14357
- fs13.unlinkSync(plistPath);
14410
+ fs14.unlinkSync(plistPath);
14358
14411
  removed = true;
14359
14412
  console.log(`Removed launchd service: ${plistPath}`);
14360
14413
  } catch {
@@ -14374,7 +14427,7 @@ function daemonUninstall() {
14374
14427
  let removed = false;
14375
14428
  for (const unitPath of SYSTEMD_UNIT_PATHS) {
14376
14429
  try {
14377
- fs13.unlinkSync(unitPath);
14430
+ fs14.unlinkSync(unitPath);
14378
14431
  removed = true;
14379
14432
  console.log(`Removed systemd service: ${unitPath}`);
14380
14433
  } catch {
@@ -14441,11 +14494,11 @@ async function daemonStatus() {
14441
14494
  console.log(` Port: ${port}`);
14442
14495
  console.log(` Service: ${serviceInstalled ? "installed" : "not installed"}`);
14443
14496
  console.log(` Platform: ${process.platform}`);
14444
- console.log(` PID file: ${fs13.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
14445
- console.log(` Log file: ${fs13.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
14497
+ console.log(` PID file: ${fs14.existsSync(PID_FILE) ? PID_FILE : LEGACY_PID_FILE}`);
14498
+ console.log(` Log file: ${fs14.existsSync(LOG_FILE) ? LOG_FILE : LEGACY_LOG_FILE}`);
14446
14499
  try {
14447
14500
  const configPath = resolveConfigPath();
14448
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
14501
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
14449
14502
  const remnicCfg = resolveRemnicConfigRecord5(raw);
14450
14503
  const config = parseConfig6(remnicCfg);
14451
14504
  const extRoot = resolveExtensionsRoot(config);
@@ -14486,9 +14539,9 @@ function daemonStart() {
14486
14539
  return;
14487
14540
  }
14488
14541
  }
14489
- fs13.mkdirSync(PID_DIR, { recursive: true });
14490
- fs13.mkdirSync(LOGS_DIR, { recursive: true });
14491
- const logStream = fs13.openSync(LOG_FILE, "a");
14542
+ fs14.mkdirSync(PID_DIR, { recursive: true });
14543
+ fs14.mkdirSync(LOGS_DIR, { recursive: true });
14544
+ const logStream = fs14.openSync(LOG_FILE, "a");
14492
14545
  const serverBin = resolveServerBin();
14493
14546
  const isSource = serverBin.endsWith(".ts");
14494
14547
  let cmd;
@@ -14510,7 +14563,7 @@ function daemonStart() {
14510
14563
  }
14511
14564
  });
14512
14565
  child.unref();
14513
- fs13.writeFileSync(PID_FILE, String(child.pid));
14566
+ fs14.writeFileSync(PID_FILE, String(child.pid));
14514
14567
  console.log(`Started remnic server (pid ${child.pid})`);
14515
14568
  console.log(` Log: ${LOG_FILE}`);
14516
14569
  }
@@ -14544,11 +14597,11 @@ function daemonStop() {
14544
14597
  console.log("Process not found (cleaning up PID file)");
14545
14598
  }
14546
14599
  try {
14547
- fs13.unlinkSync(PID_FILE);
14600
+ fs14.unlinkSync(PID_FILE);
14548
14601
  } catch {
14549
14602
  }
14550
14603
  try {
14551
- fs13.unlinkSync(LEGACY_PID_FILE);
14604
+ fs14.unlinkSync(LEGACY_PID_FILE);
14552
14605
  } catch {
14553
14606
  }
14554
14607
  }
@@ -14676,7 +14729,7 @@ async function promptYesNo(question, defaultYes = true) {
14676
14729
  async function cmdBinary(rest) {
14677
14730
  initLogger2();
14678
14731
  const configPath = resolveConfigPath();
14679
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
14732
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
14680
14733
  const remnicCfg = resolveRemnicConfigRecord5(raw);
14681
14734
  const config = parseConfig6(remnicCfg);
14682
14735
  const memoryDir = resolveMemoryDir();
@@ -14796,7 +14849,7 @@ Clean complete: cleaned=${result.cleaned}`
14796
14849
  }
14797
14850
  async function cmdOpenclawInstall(opts) {
14798
14851
  const configPath = resolveOpenclawConfigPath(opts.configPath);
14799
- const fallbackMemoryDir = path16.join(resolveHomeDir(), ".openclaw", "workspace", "memory", "local");
14852
+ const fallbackMemoryDir = path17.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
14800
14853
  console.log(`OpenClaw config: ${configPath}`);
14801
14854
  const existingConfig = readOpenclawConfig(configPath);
14802
14855
  const { plugins, entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
@@ -14867,7 +14920,7 @@ async function cmdOpenclawInstall(opts) {
14867
14920
  } else if (slotIsActiveLegacy) {
14868
14921
  changes.push(` Slot left as "${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}" \u2014 re-run with --yes to activate the new entry`);
14869
14922
  }
14870
- if (!fs13.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
14923
+ if (!fs14.existsSync(memoryDir)) changes.push(`+ Will create memory directory: ${memoryDir}`);
14871
14924
  if (hasLegacy && migrateLegacy) {
14872
14925
  changes.push(`~ Legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry retained (safe to remove after verifying hooks fire)`);
14873
14926
  }
@@ -14887,8 +14940,8 @@ async function cmdOpenclawInstall(opts) {
14887
14940
  Resulting plugins.slots.memory: ${dryRunPlugins.slots?.memory ?? "(unset)"}`);
14888
14941
  return;
14889
14942
  }
14890
- if (fs13.existsSync(memoryDir)) {
14891
- const st = fs13.statSync(memoryDir);
14943
+ if (fs14.existsSync(memoryDir)) {
14944
+ const st = fs14.statSync(memoryDir);
14892
14945
  if (!st.isDirectory()) {
14893
14946
  throw new Error(
14894
14947
  `Cannot use ${memoryDir} as the memory directory \u2014 a file already exists at that path.
@@ -14896,12 +14949,12 @@ Remove it first and re-run, or choose a different path with --memory-dir.`
14896
14949
  );
14897
14950
  }
14898
14951
  } else {
14899
- fs13.mkdirSync(memoryDir, { recursive: true });
14952
+ fs14.mkdirSync(memoryDir, { recursive: true });
14900
14953
  console.log(`Created memory directory: ${memoryDir}`);
14901
14954
  }
14902
- const configDir = path16.dirname(configPath);
14903
- if (!fs13.existsSync(configDir)) {
14904
- fs13.mkdirSync(configDir, { recursive: true });
14955
+ const configDir = path17.dirname(configPath);
14956
+ if (!fs14.existsSync(configDir)) {
14957
+ fs14.mkdirSync(configDir, { recursive: true });
14905
14958
  }
14906
14959
  atomicWriteFileSync(configPath, JSON.stringify(updatedConfig, null, 2) + "\n");
14907
14960
  console.log("\nDone! Summary of changes:");
@@ -14926,16 +14979,14 @@ Note: The legacy '${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID}' entry has been kept along
14926
14979
  async function cmdOpenclawUpgrade(opts) {
14927
14980
  const configPath = resolveOpenclawConfigPath(opts.configPath);
14928
14981
  const pluginDir = resolveOpenclawPluginDir(opts.pluginDir);
14982
+ const managedTargetDir = resolveOpenclawManagedPluginDir();
14929
14983
  const legacyPluginDirForBackup = opts.legacyPluginDirForBackup ? resolveOpenclawLegacyPluginDir(opts.legacyPluginDirForBackup) : void 0;
14930
- const fallbackMemoryDir = path16.join(resolveHomeDir(), ".openclaw", "workspace", "memory", "local");
14931
- const packageSpec = `@remnic/plugin-openclaw@${opts.version ?? "latest"}`;
14984
+ const fallbackMemoryDir = path17.join(resolveOpenclawStateDir(), "workspace", "memory", "local");
14985
+ const packageSpec = buildOpenclawManagedUpgradePackageSpec(opts.version);
14986
+ const configExistedBefore = fs14.existsSync(configPath);
14932
14987
  const existingConfig = readOpenclawConfig(configPath);
14933
14988
  const { entries, slots } = parseOpenclawPluginState(existingConfig, configPath);
14934
- const preservedMemoryDir = opts.memoryDir ? path16.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
14935
- assertDirectoryPathOrMissing(pluginDir, "OpenClaw plugin dir");
14936
- if (legacyPluginDirForBackup) {
14937
- assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
14938
- }
14989
+ const preservedMemoryDir = opts.memoryDir ? path17.resolve(expandTilde(opts.memoryDir)) : resolveCurrentOpenclawMemoryDir(entries, slots, fallbackMemoryDir);
14939
14990
  console.log(`OpenClaw config: ${configPath}`);
14940
14991
  console.log(`Plugin dir: ${pluginDir}`);
14941
14992
  if (legacyPluginDirForBackup) {
@@ -14943,11 +14994,12 @@ async function cmdOpenclawUpgrade(opts) {
14943
14994
  }
14944
14995
  console.log(`Memory dir: ${preservedMemoryDir}`);
14945
14996
  console.log(`Package spec: ${packageSpec}`);
14946
- console.log(`Backup root: ${path16.join(resolveHomeDir(), ".openclaw", "backups")}`);
14997
+ console.log(`Backup root: ${path17.join(resolveOpenclawStateDir(), "backups")}`);
14947
14998
  const plannedActions = [
14948
14999
  `backup openclaw.json and the existing ${REMNIC_OPENCLAW_PLUGIN_ID} extension`,
14949
15000
  ...legacyPluginDirForBackup ? [`backup the existing ${REMNIC_OPENCLAW_LEGACY_PLUGIN_ID} extension without modifying it`] : [],
14950
- `npm pack ${packageSpec} and stage a clean plugin copy before swap`,
15001
+ `install ${packageSpec} through OpenClaw's managed plugin project`,
15002
+ `remove the old unmanaged extension and verify OpenClaw can load the managed plugin`,
14951
15003
  `re-run remnic openclaw install with the preserved memory dir`,
14952
15004
  opts.restartGateway ? "restart the OpenClaw gateway with launchctl kickstart" : "leave gateway restart to the operator (--no-restart)"
14953
15005
  ];
@@ -14968,10 +15020,21 @@ async function cmdOpenclawUpgrade(opts) {
14968
15020
  return;
14969
15021
  }
14970
15022
  }
15023
+ const {
15024
+ assertDirectoryPathOrMissing,
15025
+ describeErrorWithCause,
15026
+ installPublishedOpenclawPlugin,
15027
+ PublishedOpenclawPluginInstallError
15028
+ } = await loadOpenclawManagedUpgradeModule(packageSpec);
15029
+ assertDirectoryPathOrMissing(pluginDir, "OpenClaw plugin dir");
15030
+ assertDirectoryPathOrMissing(managedTargetDir, "Managed OpenClaw plugin dir");
15031
+ if (legacyPluginDirForBackup) {
15032
+ assertDirectoryPathOrMissing(legacyPluginDirForBackup, "Legacy OpenClaw plugin dir");
15033
+ }
14971
15034
  const backupDir = createOpenclawUpgradeBackupDir();
14972
- const configBackupPath = path16.join(backupDir, "openclaw.json");
14973
- const pluginBackupDir = path16.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
14974
- const legacyPluginBackupDir = legacyPluginDirForBackup ? path16.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
15035
+ const configBackupPath = path17.join(backupDir, "openclaw.json");
15036
+ const pluginBackupDir = path17.join(backupDir, "extensions", REMNIC_OPENCLAW_PLUGIN_ID);
15037
+ const legacyPluginBackupDir = legacyPluginDirForBackup ? path17.join(backupDir, "extensions", REMNIC_OPENCLAW_LEGACY_PLUGIN_ID) : void 0;
14975
15038
  const backupNotes = [];
14976
15039
  if (backupPathIfPresent(configPath, configBackupPath)) {
14977
15040
  backupNotes.push(`+ Backed up config to ${configBackupPath}`);
@@ -14990,9 +15053,23 @@ async function cmdOpenclawUpgrade(opts) {
14990
15053
  backupNotes.push(` No existing legacy plugin dir found at ${legacyPluginDirForBackup}; nothing to preserve`);
14991
15054
  }
14992
15055
  }
15056
+ const runOpenclawCommand = (args, { timeoutMs }) => childProcess2.execFileSync("openclaw", [...args], {
15057
+ encoding: "utf8",
15058
+ env: {
15059
+ ...process.env,
15060
+ OPENCLAW_CONFIG_PATH: configPath
15061
+ },
15062
+ stdio: ["ignore", "pipe", "pipe"],
15063
+ timeout: timeoutMs
15064
+ });
14993
15065
  let installResult;
14994
15066
  try {
14995
- installResult = installPublishedOpenclawPlugin(packageSpec, pluginDir);
15067
+ installResult = installPublishedOpenclawPlugin(
15068
+ packageSpec,
15069
+ pluginDir,
15070
+ managedTargetDir,
15071
+ runOpenclawCommand
15072
+ );
14996
15073
  await cmdOpenclawInstall({
14997
15074
  yes: true,
14998
15075
  dryRun: false,
@@ -15004,25 +15081,81 @@ async function cmdOpenclawUpgrade(opts) {
15004
15081
  const installErrorText = describeErrorWithCause(installError);
15005
15082
  const publishedInstallError = installError instanceof PublishedOpenclawPluginInstallError ? installError : void 0;
15006
15083
  const rollbackDir = publishedInstallError ? publishedInstallError.rollbackDir : installResult?.rollbackDir;
15007
- const shouldRestorePlugin = Boolean(installResult || rollbackDir || publishedInstallError?.shouldRestoreBackup);
15008
- const shouldRestoreConfig = Boolean(installResult);
15009
- const shouldRollback = shouldRestorePlugin || shouldRestoreConfig;
15084
+ const managedRollbackDir = publishedInstallError ? publishedInstallError.managedRollbackDir : installResult?.managedRollbackDir;
15085
+ const managedRollbackTargetDir = publishedInstallError?.managedRollbackTargetDir ?? installResult?.managedRollbackTargetDir ?? managedTargetDir;
15086
+ const requiresHostManagedRestore = publishedInstallError?.requiresHostManagedRestore ?? installResult?.requiresHostManagedRestore ?? false;
15087
+ const managedRollbackSharesPluginDir = managedRollbackDir && path17.resolve(managedRollbackTargetDir) === path17.resolve(pluginDir);
15088
+ const pluginRollbackDir = managedRollbackSharesPluginDir ? requiresHostManagedRestore ? rollbackDir : rollbackDir ?? managedRollbackDir : rollbackDir;
15089
+ const shouldRestorePlugin = Boolean(
15090
+ installResult && !requiresHostManagedRestore || pluginRollbackDir || publishedInstallError?.shouldRestoreBackup
15091
+ );
15092
+ const shouldRestoreConfig = Boolean(installResult || publishedInstallError?.shouldRestoreConfig);
15093
+ const shouldRollback = shouldRestorePlugin || shouldRestoreConfig || Boolean(managedRollbackDir);
15010
15094
  if (!shouldRollback) {
15011
- throw new Error(
15012
- `OpenClaw upgrade failed while ${failurePhase}. Original failure: ${installErrorText}.`,
15013
- { cause: installError }
15014
- );
15095
+ throw new Error(`OpenClaw upgrade failed while ${failurePhase}. Original failure: ${installErrorText}.`, {
15096
+ cause: installError
15097
+ });
15098
+ }
15099
+ const rollbackErrors = [];
15100
+ let pendingConfigRestoreError;
15101
+ let usedLocalManagedRestore = Boolean(publishedInstallError?.managedRestoreNote);
15102
+ const rollbackNotes = publishedInstallError?.managedRestoreNote ? [publishedInstallError.managedRestoreNote] : [];
15103
+ if (installResult && shouldRestoreConfig) {
15104
+ try {
15105
+ const configRestoreNote = restoreOpenclawConfigWithRetry({
15106
+ configBackupPath,
15107
+ configPath,
15108
+ pluginDir,
15109
+ removeConfigIfUnbacked: !configExistedBefore
15110
+ });
15111
+ if (configRestoreNote) rollbackNotes.push(configRestoreNote);
15112
+ } catch (error) {
15113
+ pendingConfigRestoreError = error;
15114
+ }
15115
+ }
15116
+ if (installResult) {
15117
+ try {
15118
+ const managedRestoreNote = installResult.rollbackManagedInstall();
15119
+ if (managedRestoreNote) {
15120
+ usedLocalManagedRestore = true;
15121
+ rollbackNotes.push(managedRestoreNote);
15122
+ }
15123
+ } catch (error) {
15124
+ rollbackErrors.push(error);
15125
+ }
15015
15126
  }
15016
- let rollbackNotes;
15127
+ const finalRestoresConfig = shouldRestoreConfig && !usedLocalManagedRestore;
15017
15128
  try {
15018
- rollbackNotes = rollbackOpenclawUpgrade({
15019
- configBackupPath: shouldRestoreConfig ? configBackupPath : void 0,
15020
- configPath,
15021
- pluginBackupDir: shouldRestorePlugin ? pluginBackupDir : void 0,
15022
- pluginDir,
15023
- rollbackDir
15024
- });
15025
- } catch (rollbackError) {
15129
+ rollbackNotes.push(
15130
+ ...rollbackOpenclawUpgrade({
15131
+ configBackupPath: finalRestoresConfig ? configBackupPath : void 0,
15132
+ configPath,
15133
+ pluginBackupDir: shouldRestorePlugin ? pluginBackupDir : void 0,
15134
+ pluginDir,
15135
+ rollbackDir: pluginRollbackDir,
15136
+ removeConfigIfUnbacked: finalRestoresConfig && !configExistedBefore
15137
+ })
15138
+ );
15139
+ if (finalRestoresConfig) pendingConfigRestoreError = void 0;
15140
+ } catch (error) {
15141
+ rollbackErrors.push(error);
15142
+ }
15143
+ if (pendingConfigRestoreError) rollbackErrors.push(pendingConfigRestoreError);
15144
+ if (managedRollbackDir && path17.resolve(managedRollbackTargetDir) !== path17.resolve(pluginDir) && !requiresHostManagedRestore) {
15145
+ try {
15146
+ rollbackNotes.push(
15147
+ ...rollbackOpenclawUpgrade({
15148
+ configPath,
15149
+ pluginDir: managedRollbackTargetDir,
15150
+ rollbackDir: managedRollbackDir
15151
+ })
15152
+ );
15153
+ } catch (error) {
15154
+ rollbackErrors.push(error);
15155
+ }
15156
+ }
15157
+ if (rollbackErrors.length > 0) {
15158
+ const rollbackError = rollbackErrors.length > 1 ? new AggregateError(rollbackErrors, "One or more managed, file, or config rollback steps failed.") : rollbackErrors[0];
15026
15159
  throw createOpenclawUpgradeRollbackFailure({
15027
15160
  failurePhase,
15028
15161
  installError,
@@ -15034,18 +15167,20 @@ async function cmdOpenclawUpgrade(opts) {
15034
15167
  { cause: installError }
15035
15168
  );
15036
15169
  }
15037
- const rollbackCleanupWarning = cleanupRollbackDirectoryBestEffort(
15038
- installResult?.rollbackDir
15039
- );
15170
+ const rollbackCleanupWarning = cleanupRollbackDirectoryBestEffort(installResult?.rollbackDir);
15171
+ const managedRollbackCleanupWarning = cleanupRollbackDirectoryBestEffort(installResult?.managedRollbackDir);
15040
15172
  console.log("\nUpgrade backups:");
15041
15173
  for (const note of backupNotes) console.log(` ${note}`);
15042
15174
  console.log(
15043
15175
  `
15044
- Installed published plugin from npm pack ${packageSpec}${installResult.version ? ` (version ${installResult.version})` : ""}.`
15176
+ Installed published plugin through OpenClaw from ${packageSpec}${installResult?.version ? ` (version ${installResult?.version})` : ""}.`
15045
15177
  );
15046
15178
  if (rollbackCleanupWarning) {
15047
15179
  console.warn(rollbackCleanupWarning);
15048
15180
  }
15181
+ if (managedRollbackCleanupWarning) {
15182
+ console.warn(managedRollbackCleanupWarning);
15183
+ }
15049
15184
  if (opts.restartGateway) {
15050
15185
  const restartResult = runBestEffortGatewayRestart(restartOpenclawGateway, OPENCLAW_GATEWAY_LABEL);
15051
15186
  console.log(restartResult.message);
@@ -15072,14 +15207,14 @@ async function cmdOpenclawMigrateEngram(opts) {
15072
15207
  console.log(" - Re-apply any local source patches to the new package only after verifying the published build.");
15073
15208
  }
15074
15209
  function createOpenclawUpgradeBackupDir() {
15075
- const backupsRoot = path16.join(resolveHomeDir(), ".openclaw", "backups");
15076
- fs13.mkdirSync(backupsRoot, { recursive: true });
15077
- return fs13.mkdtempSync(path16.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
15210
+ const backupsRoot = path17.join(resolveOpenclawStateDir(), "backups");
15211
+ fs14.mkdirSync(backupsRoot, { recursive: true });
15212
+ return fs14.mkdtempSync(path17.join(backupsRoot, `remnic-openclaw-upgrade-${formatOpenclawUpgradeStamp()}-`));
15078
15213
  }
15079
15214
  async function cmdTaxonomy(rest) {
15080
15215
  initLogger2();
15081
15216
  const configPath = resolveConfigPath();
15082
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
15217
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
15083
15218
  const remnicCfg = resolveRemnicConfigRecord5(raw);
15084
15219
  const config = parseConfig6(remnicCfg);
15085
15220
  if (!config.taxonomyEnabled) {
@@ -15116,9 +15251,9 @@ async function cmdTaxonomy(rest) {
15116
15251
  const doc = generateResolverDocument(taxonomy);
15117
15252
  console.log(doc);
15118
15253
  if (config.taxonomyAutoGenResolver) {
15119
- const resolverPath = path16.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15120
- fs13.mkdirSync(path16.dirname(resolverPath), { recursive: true });
15121
- fs13.writeFileSync(resolverPath, doc);
15254
+ const resolverPath = path17.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15255
+ fs14.mkdirSync(path17.dirname(resolverPath), { recursive: true });
15256
+ fs14.writeFileSync(resolverPath, doc);
15122
15257
  console.error(`Written: ${resolverPath}`);
15123
15258
  }
15124
15259
  break;
@@ -15163,8 +15298,8 @@ async function cmdTaxonomy(rest) {
15163
15298
  console.log(`Added category "${id}" (${name}).`);
15164
15299
  if (config.taxonomyAutoGenResolver) {
15165
15300
  const doc = generateResolverDocument(taxonomy);
15166
- const resolverPath = path16.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15167
- fs13.writeFileSync(resolverPath, doc);
15301
+ const resolverPath = path17.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15302
+ fs14.writeFileSync(resolverPath, doc);
15168
15303
  console.error(`Regenerated: ${resolverPath}`);
15169
15304
  }
15170
15305
  break;
@@ -15194,8 +15329,8 @@ async function cmdTaxonomy(rest) {
15194
15329
  console.log(`Removed category "${id}".`);
15195
15330
  if (config.taxonomyAutoGenResolver) {
15196
15331
  const doc = generateResolverDocument(taxonomy);
15197
- const resolverPath = path16.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15198
- fs13.writeFileSync(resolverPath, doc);
15332
+ const resolverPath = path17.join(config.memoryDir, ".taxonomy", "RESOLVER.md");
15333
+ fs14.writeFileSync(resolverPath, doc);
15199
15334
  console.error(`Regenerated: ${resolverPath}`);
15200
15335
  }
15201
15336
  break;
@@ -15386,12 +15521,12 @@ async function runTrainingExport(args, stdout = process.stdout) {
15386
15521
  `Unknown training-export format "${args.format}". ${validList}`
15387
15522
  );
15388
15523
  }
15389
- if (!fs13.existsSync(args.memoryDir)) {
15524
+ if (!fs14.existsSync(args.memoryDir)) {
15390
15525
  throw new Error(
15391
15526
  `--memory-dir "${args.memoryDir}" does not exist. Provide the path to an existing memory directory.`
15392
15527
  );
15393
15528
  }
15394
- if (!fs13.statSync(args.memoryDir).isDirectory()) {
15529
+ if (!fs14.statSync(args.memoryDir).isDirectory()) {
15395
15530
  throw new Error(
15396
15531
  `--memory-dir "${args.memoryDir}" is not a directory. Provide the path to a memory directory, not a file.`
15397
15532
  );
@@ -15476,11 +15611,11 @@ async function runTrainingExport(args, stdout = process.stdout) {
15476
15611
  );
15477
15612
  }
15478
15613
  const formatted = adapter.formatRecords(records);
15479
- const outDir = path16.dirname(args.output);
15480
- fs13.mkdirSync(outDir, { recursive: true });
15614
+ const outDir = path17.dirname(args.output);
15615
+ fs14.mkdirSync(outDir, { recursive: true });
15481
15616
  const tmpPath = `${args.output}.tmp-${process.pid}-${Date.now()}`;
15482
- fs13.writeFileSync(tmpPath, formatted, "utf-8");
15483
- fs13.renameSync(tmpPath, args.output);
15617
+ fs14.writeFileSync(tmpPath, formatted, "utf-8");
15618
+ fs14.renameSync(tmpPath, args.output);
15484
15619
  stdout.write(
15485
15620
  `Exported ${records.length} records to ${args.output} (${adapter.name} format)
15486
15621
  `
@@ -15584,7 +15719,7 @@ async function main(argv = process.argv.slice(2)) {
15584
15719
  case "tree": {
15585
15720
  const subAction = rest[0];
15586
15721
  const json = rest.includes("--json");
15587
- const outputDir = resolveFlag(rest, "--output") ?? path16.join(process.cwd(), ".remnic", "context-tree");
15722
+ const outputDir = resolveFlag(rest, "--output") ?? path17.join(process.cwd(), ".remnic", "context-tree");
15588
15723
  const categoriesFlag = resolveFlag(rest, "--categories");
15589
15724
  const categories = categoriesFlag ? categoriesFlag.split(",") : void 0;
15590
15725
  const maxPerCategoryRaw = resolveFlag(rest, "--max-per-category");
@@ -15649,7 +15784,7 @@ async function main(argv = process.argv.slice(2)) {
15649
15784
  }
15650
15785
  }, 500);
15651
15786
  };
15652
- fs13.watch(memoryDir, { recursive: true }, (_event, filename) => {
15787
+ fs14.watch(memoryDir, { recursive: true }, (_event, filename) => {
15653
15788
  if (filename && filename.startsWith(".")) return;
15654
15789
  rebuild();
15655
15790
  });
@@ -15657,12 +15792,12 @@ async function main(argv = process.argv.slice(2)) {
15657
15792
  });
15658
15793
  } else if (subAction === "validate") {
15659
15794
  const treeDir = outputDir;
15660
- if (!fs13.existsSync(treeDir)) {
15795
+ if (!fs14.existsSync(treeDir)) {
15661
15796
  console.error(`Context tree not found at ${treeDir}. Run 'remnic tree generate' first.`);
15662
15797
  process.exit(1);
15663
15798
  }
15664
- const indexPath = path16.join(treeDir, "INDEX.md");
15665
- if (!fs13.existsSync(indexPath)) {
15799
+ const indexPath = path17.join(treeDir, "INDEX.md");
15800
+ if (!fs14.existsSync(indexPath)) {
15666
15801
  console.error(`INDEX.md missing in ${treeDir}. Tree may be corrupt \u2014 regenerate.`);
15667
15802
  process.exit(1);
15668
15803
  }
@@ -15844,7 +15979,7 @@ Other:
15844
15979
  let wearablesService;
15845
15980
  try {
15846
15981
  const configPath = resolveConfigPath();
15847
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
15982
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
15848
15983
  const remnicCfg = resolveRemnicConfigRecord5(raw);
15849
15984
  const config = parseConfig6(remnicCfg);
15850
15985
  wearablesOrchestrator = new Orchestrator3(config);
@@ -15899,7 +16034,7 @@ Other:
15899
16034
  const targetFactory = async () => {
15900
16035
  if (!orchestratorSingleton) {
15901
16036
  const configPath = resolveConfigPath();
15902
- const raw = fs13.existsSync(configPath) ? JSON.parse(fs13.readFileSync(configPath, "utf8")) : {};
16037
+ const raw = fs14.existsSync(configPath) ? JSON.parse(fs14.readFileSync(configPath, "utf8")) : {};
15903
16038
  const remnicCfg = resolveRemnicConfigRecord5(raw);
15904
16039
  const config = parseConfig6(remnicCfg);
15905
16040
  orchestratorSingleton = new Orchestrator3(config);
@@ -16061,15 +16196,15 @@ Run 'remnic capsule <subcommand> --help' for subcommand details.`);
16061
16196
  @remnic/plugin-openclaw while backing up the legacy extension.
16062
16197
 
16063
16198
  Sets plugins.entries["${REMNIC_OPENCLAW_PLUGIN_ID}"] and plugins.slots.memory
16064
- in ~/.openclaw/openclaw.json (or $OPENCLAW_CONFIG_PATH).
16199
+ in $OPENCLAW_STATE_DIR/openclaw.json, ~/.openclaw/openclaw.json, or $OPENCLAW_CONFIG_PATH.
16065
16200
 
16066
16201
  Options:
16067
16202
  --yes / -y / --force Skip interactive prompts, assume Y
16068
16203
  --dry-run Print resulting config diff without writing
16069
- --memory-dir <path> Override default memory dir (~/.openclaw/workspace/memory/local)
16204
+ --memory-dir <path> Override the OpenClaw state-root memory dir
16070
16205
  --config <path> Override OpenClaw config path
16071
16206
  --version <tag> Upgrade @remnic/plugin-openclaw from a specific npm tag/version
16072
- --plugin-dir <path> Override OpenClaw extension dir (~/.openclaw/extensions/openclaw-remnic)
16207
+ --plugin-dir <path> Override the OpenClaw state-root extension dir
16073
16208
  --legacy-plugin-dir <path>
16074
16209
  Override legacy extension dir backed up by migrate-engram
16075
16210
  --no-restart Skip the final launchctl kickstart after upgrade`);