@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.
- package/dist/index.js +599 -464
- 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
|
|
22
|
-
import
|
|
23
|
-
import
|
|
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
|
|
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/
|
|
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
|
|
4364
|
-
var thisModuleDir =
|
|
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 ??
|
|
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 =
|
|
4387
|
-
const workspaceDistIndex =
|
|
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:
|
|
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:
|
|
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 ??
|
|
4432
|
-
const unlinkSync = options.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
|
|
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,
|
|
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 =
|
|
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,
|
|
4610
|
+
function readProcessCommand(pid, execFileSync4, platform) {
|
|
4477
4611
|
if (platform === "win32") {
|
|
4478
|
-
return readWindowsProcessCommand(pid,
|
|
4612
|
+
return readWindowsProcessCommand(pid, execFileSync4);
|
|
4479
4613
|
}
|
|
4480
|
-
return readPosixProcessCommand(pid,
|
|
4614
|
+
return readPosixProcessCommand(pid, execFileSync4);
|
|
4481
4615
|
}
|
|
4482
|
-
function readPosixProcessCommand(pid,
|
|
4616
|
+
function readPosixProcessCommand(pid, execFileSync4) {
|
|
4483
4617
|
try {
|
|
4484
|
-
return
|
|
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,
|
|
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 =
|
|
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 =
|
|
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 ??
|
|
4533
|
-
const readFileSync4 = options.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 (!
|
|
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
|
|
4774
|
+
if (resolved.startsWith("file:")) return fileURLToPath4(resolved);
|
|
4641
4775
|
return resolved;
|
|
4642
4776
|
}
|
|
4643
4777
|
function packageServerBinFromEntry(packageEntry) {
|
|
4644
|
-
if (
|
|
4645
|
-
return
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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) =>
|
|
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
|
|
5395
|
-
import
|
|
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 (
|
|
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 (!
|
|
5645
|
+
if (!fs13.existsSync(p)) {
|
|
5512
5646
|
throw new Error(`${label} does not exist: ${p}`);
|
|
5513
5647
|
}
|
|
5514
|
-
if (!
|
|
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 =
|
|
5546
|
-
if (
|
|
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
|
|
5666
|
-
import
|
|
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 =
|
|
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) =>
|
|
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 =
|
|
6175
|
+
let candidate = path15.resolve(value);
|
|
6042
6176
|
const missingSegments = [];
|
|
6043
6177
|
while (true) {
|
|
6044
6178
|
try {
|
|
6045
|
-
return
|
|
6179
|
+
return path15.join(await realpath(candidate), ...missingSegments.reverse());
|
|
6046
6180
|
} catch (error) {
|
|
6047
6181
|
if (error.code !== "ENOENT") throw error;
|
|
6048
|
-
const parent =
|
|
6182
|
+
const parent = path15.dirname(candidate);
|
|
6049
6183
|
if (parent === candidate) throw error;
|
|
6050
|
-
missingSegments.push(
|
|
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 =
|
|
6057
|
-
return relative === "" || relative !== ".." && !relative.startsWith(`..${
|
|
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
|
-
|
|
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(
|
|
6085
|
-
const hasMemoryData = await pathExists(
|
|
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 =
|
|
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(
|
|
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 =
|
|
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(
|
|
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
|
|
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 ??
|
|
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 =
|
|
6574
|
-
var LEGACY_PID_DIR =
|
|
6575
|
-
var PID_FILE =
|
|
6576
|
-
var LEGACY_PID_FILE =
|
|
6577
|
-
var LOG_FILE =
|
|
6578
|
-
var LEGACY_LOG_FILE =
|
|
6579
|
-
var CLI_MODULE_DIR =
|
|
6580
|
-
var CLI_REPO_ROOT =
|
|
6581
|
-
var EVAL_RUNNER_PATH =
|
|
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 (!
|
|
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 (!
|
|
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
|
-
|
|
6802
|
-
|
|
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) =>
|
|
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
|
|
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
|
-
|
|
6867
|
-
|
|
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 =
|
|
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 =
|
|
6950
|
-
const candidatePath =
|
|
6951
|
-
const candidateRealPath =
|
|
6952
|
-
const relativeToRoot =
|
|
6953
|
-
if (relativeToRoot.startsWith("..") ||
|
|
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 =
|
|
7010
|
-
if (
|
|
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
|
|
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(
|
|
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 &&
|
|
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
|
|
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 =
|
|
7056
|
-
const roots = [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 =
|
|
7201
|
+
const filePath = path17.join(datasetPath, filename);
|
|
7068
7202
|
try {
|
|
7069
|
-
if (!
|
|
7203
|
+
if (!fs14.statSync(filePath).isFile()) {
|
|
7070
7204
|
return false;
|
|
7071
7205
|
}
|
|
7072
|
-
const raw =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
7280
|
+
const benchUiDir = path17.join(CLI_REPO_ROOT, "packages", "bench-ui");
|
|
7147
7281
|
const pnpmCmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm";
|
|
7148
|
-
if (!
|
|
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 =
|
|
7309
|
+
const repoCandidate = path17.join(CLI_REPO_ROOT, "evals", "datasets");
|
|
7176
7310
|
if (isRepoCheckout()) {
|
|
7177
7311
|
return repoCandidate;
|
|
7178
7312
|
}
|
|
7179
|
-
return
|
|
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 =
|
|
7186
|
-
if (
|
|
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
|
|
7323
|
+
return path17.join(CLI_REPO_ROOT, "evals", "scripts", "download-datasets.sh");
|
|
7190
7324
|
}
|
|
7191
7325
|
function isRepoCheckout() {
|
|
7192
|
-
return
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
7506
|
-
|
|
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 =
|
|
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 (!
|
|
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:
|
|
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 ??
|
|
7834
|
+
parsed.resultsDir ?? path17.join(resolveHomeDir(), ".remnic", "bench", "results")
|
|
7701
7835
|
);
|
|
7702
7836
|
const calibrationDir = expandTilde(
|
|
7703
|
-
parsed.calibrationDir ??
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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 ${
|
|
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] =
|
|
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 ??
|
|
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
|
|
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 =
|
|
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
|
|
9045
|
+
if (cliPath) return path17.resolve(expandTilde(cliPath));
|
|
8912
9046
|
const envPath = readCompatEnv("REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH");
|
|
8913
|
-
if (envPath) return
|
|
9047
|
+
if (envPath) return path17.resolve(expandTilde(envPath));
|
|
8914
9048
|
const candidates = [
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
8918
|
-
|
|
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 (
|
|
9055
|
+
if (fs14.existsSync(candidate)) return candidate;
|
|
8922
9056
|
}
|
|
8923
|
-
return
|
|
9057
|
+
return path17.join(resolveHomeDir(), ".config", "remnic", "config.json");
|
|
8924
9058
|
}
|
|
8925
9059
|
function resolveExistingBenchRemnicConfigPath(cliPath) {
|
|
8926
9060
|
const configPath = resolveConfigPath(cliPath);
|
|
8927
|
-
if (
|
|
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 (
|
|
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
|
|
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 =
|
|
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 =
|
|
9051
|
-
const legacyStandalonePath =
|
|
9052
|
-
const openclawPath =
|
|
9053
|
-
if (
|
|
9054
|
-
if (
|
|
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 (
|
|
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 (!
|
|
9064
|
-
|
|
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
|
-
|
|
9240
|
+
path17.join(resolveOpenclawStateDir(), "openclaw.json")
|
|
9104
9241
|
].filter(Boolean);
|
|
9105
9242
|
function resolveOpenclawConfigPath(cliPath) {
|
|
9106
|
-
if (cliPath) return
|
|
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
|
|
9245
|
+
if (envPath) return path17.resolve(expandTilde(envPath));
|
|
9109
9246
|
for (const candidate of DEFAULT_OPENCLAW_CONFIG_PATHS_FOR_DOCTOR) {
|
|
9110
|
-
if (
|
|
9247
|
+
if (fs14.existsSync(candidate)) return candidate;
|
|
9111
9248
|
}
|
|
9112
|
-
return
|
|
9249
|
+
return path17.join(resolveOpenclawStateDir(), "openclaw.json");
|
|
9113
9250
|
}
|
|
9114
9251
|
function readOpenclawConfig(configPath) {
|
|
9115
|
-
if (!
|
|
9116
|
-
const raw =
|
|
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
|
|
9308
|
+
return path17.resolve(expandTilde(args.requestedMemoryDir));
|
|
9172
9309
|
}
|
|
9173
9310
|
if (existingMemoryDir) {
|
|
9174
|
-
return
|
|
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
|
|
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
|
|
9199
|
-
return
|
|
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
|
|
9203
|
-
return
|
|
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 (!
|
|
9216
|
-
|
|
9217
|
-
|
|
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 =
|
|
9323
|
-
if (
|
|
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:
|
|
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
|
-
|
|
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(
|
|
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,
|
|
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()}${
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
10510
|
+
const entryPath = path17.join(root, entry);
|
|
10458
10511
|
try {
|
|
10459
|
-
if (!
|
|
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 =
|
|
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
|
-
|
|
10624
|
+
fs14.mkdirSync(saveDir, { recursive: true });
|
|
10572
10625
|
const filename = briefingFilename(new Date(result.window.to), format);
|
|
10573
|
-
const filePath =
|
|
10574
|
-
|
|
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 =
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 (
|
|
10786
|
+
if (fs14.existsSync(resolvedMemDir)) {
|
|
10734
10787
|
try {
|
|
10735
|
-
const stat2 =
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
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:
|
|
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 =
|
|
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 =
|
|
11078
|
-
const dirHash = createHash4("sha256").update(
|
|
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(
|
|
11477
|
-
super(`remote file changed while fetching offline content: ${
|
|
11529
|
+
constructor(path18) {
|
|
11530
|
+
super(`remote file changed while fetching offline content: ${path18}`);
|
|
11478
11531
|
this.name = "OfflineRemoteFileChangedError";
|
|
11479
|
-
this.path =
|
|
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 =
|
|
11671
|
-
const target =
|
|
11672
|
-
const relative =
|
|
11673
|
-
if (relative === "" || relative === ".." || relative.startsWith(`..${
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
13057
|
-
if (skippedLargeFiles.has(
|
|
13058
|
-
skippedLargeFiles.add(
|
|
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 ${
|
|
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
|
|
13076
|
-
if (skippedLargeFiles.has(
|
|
13077
|
-
skippedLargeFiles.add(
|
|
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 ${
|
|
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(
|
|
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:
|
|
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 ?
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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] ??
|
|
13588
|
-
const resolved =
|
|
13589
|
-
if (!
|
|
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(
|
|
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 =
|
|
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: ${
|
|
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 =
|
|
14218
|
+
fixturePath = path17.resolve(expandTilde(fixturePathRaw));
|
|
14166
14219
|
}
|
|
14167
|
-
const outPath =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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
|
-
|
|
14348
|
+
fs14.mkdirSync(LOGS_DIR, { recursive: true });
|
|
14296
14349
|
if (isMacOS()) {
|
|
14297
|
-
const templatePath =
|
|
14298
|
-
const template =
|
|
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
|
-
|
|
14301
|
-
|
|
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 =
|
|
14318
|
-
const template =
|
|
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
|
-
|
|
14321
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: ${
|
|
14445
|
-
console.log(` 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 =
|
|
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
|
-
|
|
14490
|
-
|
|
14491
|
-
const logStream =
|
|
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
|
-
|
|
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
|
-
|
|
14600
|
+
fs14.unlinkSync(PID_FILE);
|
|
14548
14601
|
} catch {
|
|
14549
14602
|
}
|
|
14550
14603
|
try {
|
|
14551
|
-
|
|
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 =
|
|
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 =
|
|
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 (!
|
|
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 (
|
|
14891
|
-
const st =
|
|
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
|
-
|
|
14952
|
+
fs14.mkdirSync(memoryDir, { recursive: true });
|
|
14900
14953
|
console.log(`Created memory directory: ${memoryDir}`);
|
|
14901
14954
|
}
|
|
14902
|
-
const configDir =
|
|
14903
|
-
if (!
|
|
14904
|
-
|
|
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 =
|
|
14931
|
-
const packageSpec =
|
|
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 ?
|
|
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: ${
|
|
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
|
-
`
|
|
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 =
|
|
14973
|
-
const pluginBackupDir =
|
|
14974
|
-
const legacyPluginBackupDir = legacyPluginDirForBackup ?
|
|
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(
|
|
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
|
|
15008
|
-
const
|
|
15009
|
-
const
|
|
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
|
-
|
|
15013
|
-
|
|
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
|
-
|
|
15127
|
+
const finalRestoresConfig = shouldRestoreConfig && !usedLocalManagedRestore;
|
|
15017
15128
|
try {
|
|
15018
|
-
rollbackNotes
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
15076
|
-
|
|
15077
|
-
return
|
|
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 =
|
|
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 =
|
|
15120
|
-
|
|
15121
|
-
|
|
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 =
|
|
15167
|
-
|
|
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 =
|
|
15198
|
-
|
|
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 (!
|
|
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 (!
|
|
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 =
|
|
15480
|
-
|
|
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
|
-
|
|
15483
|
-
|
|
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") ??
|
|
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
|
-
|
|
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 (!
|
|
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 =
|
|
15665
|
-
if (!
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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`);
|