@remnic/plugin-openclaw 9.65.2 → 9.65.4
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 +162 -76
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3180,7 +3180,7 @@ __reExport(access_http_exports, access_http_star);
|
|
|
3180
3180
|
import * as access_http_star from "@remnic/core/access-http";
|
|
3181
3181
|
|
|
3182
3182
|
// ../../src/index.ts
|
|
3183
|
-
import
|
|
3183
|
+
import path11 from "path";
|
|
3184
3184
|
import os from "os";
|
|
3185
3185
|
|
|
3186
3186
|
// ../../src/opik-exporter.ts
|
|
@@ -4443,8 +4443,8 @@ function parseProcessedMarkerChunks(rawChunks) {
|
|
|
4443
4443
|
}
|
|
4444
4444
|
async function readProcessedMarker(markerPath) {
|
|
4445
4445
|
try {
|
|
4446
|
-
const
|
|
4447
|
-
if (
|
|
4446
|
+
const stat3 = await lstat2(markerPath);
|
|
4447
|
+
if (stat3.isSymbolicLink() || !stat3.isFile()) return void 0;
|
|
4448
4448
|
return parseProcessedMarker(await readFile(markerPath, "utf8"));
|
|
4449
4449
|
} catch (error) {
|
|
4450
4450
|
if (error?.code === "ENOENT") return void 0;
|
|
@@ -4501,8 +4501,8 @@ function isMeaningfulFlushPlanContent(content) {
|
|
|
4501
4501
|
}
|
|
4502
4502
|
async function isSafeFlushPlanAppendTarget(flushPlanPath) {
|
|
4503
4503
|
try {
|
|
4504
|
-
const
|
|
4505
|
-
return !
|
|
4504
|
+
const stat3 = await lstat2(flushPlanPath);
|
|
4505
|
+
return !stat3.isSymbolicLink() && stat3.isFile();
|
|
4506
4506
|
} catch (error) {
|
|
4507
4507
|
if (error?.code === "ENOENT") return true;
|
|
4508
4508
|
throw error;
|
|
@@ -4603,21 +4603,21 @@ async function validateFlushPlanLocation(params) {
|
|
|
4603
4603
|
let currentPath = workspaceRoot;
|
|
4604
4604
|
for (const segment of parentSegments) {
|
|
4605
4605
|
currentPath = path2.join(currentPath, segment);
|
|
4606
|
-
let
|
|
4606
|
+
let stat3;
|
|
4607
4607
|
try {
|
|
4608
|
-
|
|
4608
|
+
stat3 = await lstat2(currentPath);
|
|
4609
4609
|
} catch (error) {
|
|
4610
4610
|
if (error?.code === "ENOENT") break;
|
|
4611
4611
|
throw error;
|
|
4612
4612
|
}
|
|
4613
|
-
if (
|
|
4613
|
+
if (stat3.isSymbolicLink()) {
|
|
4614
4614
|
return {
|
|
4615
4615
|
status: "skipped",
|
|
4616
4616
|
path: params.flushPlanPath,
|
|
4617
4617
|
reason: "flush plan parent path contains a symlink"
|
|
4618
4618
|
};
|
|
4619
4619
|
}
|
|
4620
|
-
if (!
|
|
4620
|
+
if (!stat3.isDirectory()) {
|
|
4621
4621
|
return {
|
|
4622
4622
|
status: "skipped",
|
|
4623
4623
|
path: params.flushPlanPath,
|
|
@@ -4663,14 +4663,14 @@ async function recoverInterruptedCleanupSnapshots(params) {
|
|
|
4663
4663
|
if (error?.code !== "ENOENT") throw error;
|
|
4664
4664
|
}
|
|
4665
4665
|
for (const cleanupPath of cleanupPaths) {
|
|
4666
|
-
let
|
|
4666
|
+
let stat3;
|
|
4667
4667
|
try {
|
|
4668
|
-
|
|
4668
|
+
stat3 = await lstat2(cleanupPath);
|
|
4669
4669
|
} catch (error) {
|
|
4670
4670
|
if (error?.code === "ENOENT") continue;
|
|
4671
4671
|
throw error;
|
|
4672
4672
|
}
|
|
4673
|
-
if (
|
|
4673
|
+
if (stat3.isSymbolicLink() || !stat3.isFile()) {
|
|
4674
4674
|
params.logger?.warn(
|
|
4675
4675
|
`OpenClaw flush-plan cleanup recovery skipped unsafe snapshot ${path2.basename(cleanupPath)}`
|
|
4676
4676
|
);
|
|
@@ -5002,23 +5002,23 @@ function buildFlushPlanImportTurns(params) {
|
|
|
5002
5002
|
);
|
|
5003
5003
|
}
|
|
5004
5004
|
async function readFlushPlanSnapshot(flushPlanPath) {
|
|
5005
|
-
let
|
|
5005
|
+
let stat3;
|
|
5006
5006
|
try {
|
|
5007
|
-
|
|
5007
|
+
stat3 = await lstat2(flushPlanPath);
|
|
5008
5008
|
} catch (error) {
|
|
5009
5009
|
if (error?.code === "ENOENT") {
|
|
5010
5010
|
return { status: "missing", path: flushPlanPath };
|
|
5011
5011
|
}
|
|
5012
5012
|
throw error;
|
|
5013
5013
|
}
|
|
5014
|
-
if (
|
|
5014
|
+
if (stat3.isSymbolicLink()) {
|
|
5015
5015
|
return {
|
|
5016
5016
|
status: "skipped",
|
|
5017
5017
|
path: flushPlanPath,
|
|
5018
5018
|
reason: "flush plan path is a symlink"
|
|
5019
5019
|
};
|
|
5020
5020
|
}
|
|
5021
|
-
if (!
|
|
5021
|
+
if (!stat3.isFile()) {
|
|
5022
5022
|
return {
|
|
5023
5023
|
status: "skipped",
|
|
5024
5024
|
path: flushPlanPath,
|
|
@@ -5088,8 +5088,8 @@ async function removeProcessedFlushPlanContent(params) {
|
|
|
5088
5088
|
const processedBytes = Buffer.byteLength(params.processedContent, "utf8");
|
|
5089
5089
|
let cleanupPath;
|
|
5090
5090
|
try {
|
|
5091
|
-
const
|
|
5092
|
-
if (
|
|
5091
|
+
const stat3 = await lstat2(params.flushPlanPath);
|
|
5092
|
+
if (stat3.isSymbolicLink()) {
|
|
5093
5093
|
return {
|
|
5094
5094
|
status: "processed_cleanup_deferred",
|
|
5095
5095
|
path: params.flushPlanPath,
|
|
@@ -5097,7 +5097,7 @@ async function removeProcessedFlushPlanContent(params) {
|
|
|
5097
5097
|
reason: "flush plan path became a symlink before cleanup"
|
|
5098
5098
|
};
|
|
5099
5099
|
}
|
|
5100
|
-
if (!
|
|
5100
|
+
if (!stat3.isFile()) {
|
|
5101
5101
|
return {
|
|
5102
5102
|
status: "processed_cleanup_deferred",
|
|
5103
5103
|
path: params.flushPlanPath,
|
|
@@ -5395,7 +5395,7 @@ async function processOpenClawFlushPlanFile(params) {
|
|
|
5395
5395
|
}
|
|
5396
5396
|
|
|
5397
5397
|
// src/delegate-runtime.ts
|
|
5398
|
-
import
|
|
5398
|
+
import path9 from "path";
|
|
5399
5399
|
import {
|
|
5400
5400
|
renderMemoryContextPrompt
|
|
5401
5401
|
} from "@remnic/core";
|
|
@@ -6902,12 +6902,93 @@ function daemonTargetFor(bridge) {
|
|
|
6902
6902
|
}
|
|
6903
6903
|
|
|
6904
6904
|
// src/delegate-flush-plan-ingest.ts
|
|
6905
|
-
import { constants } from "fs";
|
|
6906
|
-
import { lstat as
|
|
6907
|
-
import
|
|
6905
|
+
import { constants as constants2 } from "fs";
|
|
6906
|
+
import { lstat as lstat4, open as open2, rename as rename2, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
|
|
6907
|
+
import path8 from "path";
|
|
6908
6908
|
import { log as log4 } from "@remnic/core/logger";
|
|
6909
6909
|
import { withHeldFileLock } from "@remnic/core/utils/serialize-mutations";
|
|
6910
6910
|
|
|
6911
|
+
// src/delegate-flush-plan-directory.ts
|
|
6912
|
+
import { constants } from "fs";
|
|
6913
|
+
import { lstat as lstat3, open, stat as stat2 } from "fs/promises";
|
|
6914
|
+
import path7 from "path";
|
|
6915
|
+
function buildSnapshotPaths(planPath) {
|
|
6916
|
+
return {
|
|
6917
|
+
plan: planPath,
|
|
6918
|
+
inflight: `${planPath}.inflight`,
|
|
6919
|
+
rotating: `${planPath}.rotating`,
|
|
6920
|
+
oversized: `${planPath}.oversized`,
|
|
6921
|
+
lock: `${planPath}.lock`,
|
|
6922
|
+
oversizedLabel: `${planPath}.oversized`
|
|
6923
|
+
};
|
|
6924
|
+
}
|
|
6925
|
+
function descriptorDirectoryRoot(platform = process.platform) {
|
|
6926
|
+
if (platform === "linux") return "/proc/self/fd";
|
|
6927
|
+
if (platform === "darwin" || platform === "freebsd" || platform === "openbsd") return "/dev/fd";
|
|
6928
|
+
return void 0;
|
|
6929
|
+
}
|
|
6930
|
+
async function pinSnapshotDirectory(paths, options = {}) {
|
|
6931
|
+
const descriptorRoot = options.descriptorRoot ?? descriptorDirectoryRoot();
|
|
6932
|
+
if (descriptorRoot === void 0) return { kind: "unsupported" };
|
|
6933
|
+
const directory = path7.dirname(paths.plan);
|
|
6934
|
+
let before;
|
|
6935
|
+
try {
|
|
6936
|
+
before = await lstat3(directory);
|
|
6937
|
+
} catch {
|
|
6938
|
+
return { kind: "unstable" };
|
|
6939
|
+
}
|
|
6940
|
+
if (before.isSymbolicLink() || !before.isDirectory()) return { kind: "unstable" };
|
|
6941
|
+
let handle;
|
|
6942
|
+
try {
|
|
6943
|
+
handle = await open(directory, constants.O_RDONLY | constants.O_DIRECTORY | constants.O_NOFOLLOW);
|
|
6944
|
+
} catch {
|
|
6945
|
+
return { kind: "unstable" };
|
|
6946
|
+
}
|
|
6947
|
+
try {
|
|
6948
|
+
const opened = await handle.stat();
|
|
6949
|
+
const after = await lstat3(directory);
|
|
6950
|
+
if (!opened.isDirectory() || after.isSymbolicLink() || !after.isDirectory() || !isSameInode(before, opened) || !isSameInode(after, opened)) {
|
|
6951
|
+
await closeQuietly(handle);
|
|
6952
|
+
return { kind: "unstable" };
|
|
6953
|
+
}
|
|
6954
|
+
const pinnedDirectory = path7.join(descriptorRoot, String(handle.fd));
|
|
6955
|
+
let anchored;
|
|
6956
|
+
try {
|
|
6957
|
+
anchored = await stat2(pinnedDirectory);
|
|
6958
|
+
} catch {
|
|
6959
|
+
await closeQuietly(handle);
|
|
6960
|
+
return { kind: "unsupported" };
|
|
6961
|
+
}
|
|
6962
|
+
if (!anchored.isDirectory() || !isSameInode(anchored, opened)) {
|
|
6963
|
+
await closeQuietly(handle);
|
|
6964
|
+
return { kind: "unsupported" };
|
|
6965
|
+
}
|
|
6966
|
+
return {
|
|
6967
|
+
kind: "pinned",
|
|
6968
|
+
paths: {
|
|
6969
|
+
...paths,
|
|
6970
|
+
plan: anchoredChild(pinnedDirectory, paths.plan),
|
|
6971
|
+
inflight: anchoredChild(pinnedDirectory, paths.inflight),
|
|
6972
|
+
rotating: anchoredChild(pinnedDirectory, paths.rotating),
|
|
6973
|
+
oversized: anchoredChild(pinnedDirectory, paths.oversized)
|
|
6974
|
+
},
|
|
6975
|
+
close: () => closeQuietly(handle)
|
|
6976
|
+
};
|
|
6977
|
+
} catch (err) {
|
|
6978
|
+
await closeQuietly(handle);
|
|
6979
|
+
throw err;
|
|
6980
|
+
}
|
|
6981
|
+
}
|
|
6982
|
+
function anchoredChild(pinnedDirectory, realPath) {
|
|
6983
|
+
return path7.join(pinnedDirectory, path7.basename(realPath));
|
|
6984
|
+
}
|
|
6985
|
+
function isSameInode(left, right) {
|
|
6986
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
6987
|
+
}
|
|
6988
|
+
async function closeQuietly(handle) {
|
|
6989
|
+
await handle.close().catch(() => void 0);
|
|
6990
|
+
}
|
|
6991
|
+
|
|
6911
6992
|
// src/memory-flush-plan.ts
|
|
6912
6993
|
var DEFAULT_MAX_TURN_CHARS = 8e3;
|
|
6913
6994
|
var MIN_MAX_TURN_CHARS = 1e3;
|
|
@@ -6993,17 +7074,11 @@ var MAX_RECLAIM_PASSES = 4;
|
|
|
6993
7074
|
async function ingestFlushPlanNotes(options) {
|
|
6994
7075
|
if (options.workspaceDir === void 0) return;
|
|
6995
7076
|
const workspaceDir = options.workspaceDir;
|
|
6996
|
-
const planPath =
|
|
7077
|
+
const planPath = path8.join(
|
|
6997
7078
|
workspaceDir,
|
|
6998
7079
|
...buildMemoryFlushPlan({ serviceId: options.serviceId }).relativePath.split("/")
|
|
6999
7080
|
);
|
|
7000
|
-
const paths =
|
|
7001
|
-
plan: planPath,
|
|
7002
|
-
inflight: `${planPath}.inflight`,
|
|
7003
|
-
rotating: `${planPath}.rotating`,
|
|
7004
|
-
oversized: `${planPath}.oversized`,
|
|
7005
|
-
lock: `${planPath}.lock`
|
|
7006
|
-
};
|
|
7081
|
+
const paths = buildSnapshotPaths(planPath);
|
|
7007
7082
|
for (const candidate of [paths.plan, paths.inflight, paths.rotating, paths.oversized]) {
|
|
7008
7083
|
if (await isLinkFreeUnder(workspaceDir, candidate)) continue;
|
|
7009
7084
|
log4.warn(
|
|
@@ -7029,7 +7104,18 @@ async function ingestFlushPlanNotes(options) {
|
|
|
7029
7104
|
);
|
|
7030
7105
|
return;
|
|
7031
7106
|
}
|
|
7032
|
-
await
|
|
7107
|
+
const pinned = await pinSnapshotDirectory(paths);
|
|
7108
|
+
if (pinned.kind === "unstable") {
|
|
7109
|
+
log4.warn(
|
|
7110
|
+
`[${options.serviceId}] flush-plan ingestion skipped: the snapshot directory changed identity while it was being opened`
|
|
7111
|
+
);
|
|
7112
|
+
return;
|
|
7113
|
+
}
|
|
7114
|
+
try {
|
|
7115
|
+
await ingestUnderLock(options, pinned.kind === "pinned" ? pinned.paths : paths, lock);
|
|
7116
|
+
} finally {
|
|
7117
|
+
if (pinned.kind === "pinned") await pinned.close();
|
|
7118
|
+
}
|
|
7033
7119
|
}
|
|
7034
7120
|
);
|
|
7035
7121
|
}
|
|
@@ -7189,9 +7275,9 @@ async function quarantineOversizedLine(paths, pending, serviceId) {
|
|
|
7189
7275
|
const breakAt = pending.indexOf("\n");
|
|
7190
7276
|
const line = breakAt === -1 ? pending : pending.slice(0, breakAt + 1);
|
|
7191
7277
|
const rest = breakAt === -1 ? "" : pending.slice(breakAt + 1);
|
|
7192
|
-
const handle = await
|
|
7278
|
+
const handle = await open2(
|
|
7193
7279
|
paths.oversized,
|
|
7194
|
-
|
|
7280
|
+
constants2.O_WRONLY | constants2.O_CREAT | constants2.O_APPEND | constants2.O_NOFOLLOW,
|
|
7195
7281
|
384
|
|
7196
7282
|
);
|
|
7197
7283
|
try {
|
|
@@ -7201,14 +7287,14 @@ async function quarantineOversizedLine(paths, pending, serviceId) {
|
|
|
7201
7287
|
await handle.close();
|
|
7202
7288
|
}
|
|
7203
7289
|
log4.warn(
|
|
7204
|
-
`[${serviceId}] a flush-plan note exceeds the daemon's body limit; moved it to ${paths.
|
|
7290
|
+
`[${serviceId}] a flush-plan note exceeds the daemon's body limit; moved it to ${paths.oversizedLabel} so the remaining notes can drain`
|
|
7205
7291
|
);
|
|
7206
7292
|
return rest;
|
|
7207
7293
|
}
|
|
7208
7294
|
async function readIfPresent(filePath) {
|
|
7209
7295
|
let handle;
|
|
7210
7296
|
try {
|
|
7211
|
-
handle = await
|
|
7297
|
+
handle = await open2(filePath, constants2.O_RDONLY | constants2.O_NOFOLLOW);
|
|
7212
7298
|
return await handle.readFile("utf8");
|
|
7213
7299
|
} catch (err) {
|
|
7214
7300
|
if (err?.code === "ENOENT") return void 0;
|
|
@@ -7249,18 +7335,18 @@ function chunkOnLineBoundaries(text, limit) {
|
|
|
7249
7335
|
return chunks;
|
|
7250
7336
|
}
|
|
7251
7337
|
async function isLinkFreeUnder(root, target) {
|
|
7252
|
-
const relative =
|
|
7253
|
-
if (relative.startsWith("..") ||
|
|
7338
|
+
const relative = path8.relative(root, target);
|
|
7339
|
+
if (relative.startsWith("..") || path8.isAbsolute(relative)) return false;
|
|
7254
7340
|
let current = root;
|
|
7255
7341
|
try {
|
|
7256
|
-
if ((await
|
|
7342
|
+
if ((await lstat4(current)).isSymbolicLink()) return false;
|
|
7257
7343
|
} catch {
|
|
7258
7344
|
return true;
|
|
7259
7345
|
}
|
|
7260
|
-
for (const segment of relative.split(
|
|
7261
|
-
current =
|
|
7346
|
+
for (const segment of relative.split(path8.sep)) {
|
|
7347
|
+
current = path8.join(current, segment);
|
|
7262
7348
|
try {
|
|
7263
|
-
if ((await
|
|
7349
|
+
if ((await lstat4(current)).isSymbolicLink()) return false;
|
|
7264
7350
|
} catch {
|
|
7265
7351
|
return true;
|
|
7266
7352
|
}
|
|
@@ -8521,7 +8607,7 @@ var queueDelegateNamespaceMigration = (bindingPath, sessionKey, operation) => {
|
|
|
8521
8607
|
return run;
|
|
8522
8608
|
};
|
|
8523
8609
|
function createDelegateNamespaceBindingStore(memoryDir, serviceId, isLegacyAdapterActive) {
|
|
8524
|
-
const bindingPath = (pluginId) =>
|
|
8610
|
+
const bindingPath = (pluginId) => path9.join(memoryDir, "state", "plugins", pluginId, "session-namespace-bindings.json");
|
|
8525
8611
|
const primaryPath = bindingPath(serviceId);
|
|
8526
8612
|
const primary = createFileSessionNamespaceBindingStore(primaryPath);
|
|
8527
8613
|
if (serviceId !== REMNIC_OPENCLAW_PLUGIN_ID) return primary;
|
|
@@ -8695,9 +8781,9 @@ function maybeRegisterDelegateRuntime(api, options, deps = { checkHealth: checkD
|
|
|
8695
8781
|
delegateBoundApis.add(api);
|
|
8696
8782
|
}
|
|
8697
8783
|
const toggleStore = options.sessionTogglesEnabled ? createFileToggleStore(
|
|
8698
|
-
|
|
8784
|
+
path9.join(options.memoryDir, "state", "plugins", options.serviceId, "session-toggles.json"),
|
|
8699
8785
|
{
|
|
8700
|
-
secondaryReadOnlyPath: options.respectBundledActiveMemoryToggle ?
|
|
8786
|
+
secondaryReadOnlyPath: options.respectBundledActiveMemoryToggle ? path9.join(options.memoryDir, "state", "plugins", "active-memory", "session-toggles.json") : void 0
|
|
8701
8787
|
}
|
|
8702
8788
|
) : null;
|
|
8703
8789
|
const target = daemonTargetFor(bridge);
|
|
@@ -8870,23 +8956,23 @@ __export(resolve_provider_secret_exports, {
|
|
|
8870
8956
|
findGatewayRuntimeModules: () => findGatewayRuntimeModules
|
|
8871
8957
|
});
|
|
8872
8958
|
__reExport(resolve_provider_secret_exports, resolve_provider_secret_star);
|
|
8873
|
-
import
|
|
8959
|
+
import path10 from "path";
|
|
8874
8960
|
import * as resolve_provider_secret_star from "@remnic/core/resolve-provider-secret";
|
|
8875
8961
|
async function findGatewayRuntimeModules(filePrefix) {
|
|
8876
8962
|
const { existsSync, readFileSync, readdirSync, realpathSync: realpathSync2 } = await import("fs");
|
|
8877
8963
|
const { createRequire: createRequire2 } = await import("module");
|
|
8878
8964
|
const candidates = [];
|
|
8879
8965
|
const isWithinRoot = (root, candidate) => {
|
|
8880
|
-
const relative =
|
|
8881
|
-
return relative.length === 0 || !relative.startsWith("..") && !
|
|
8966
|
+
const relative = path10.relative(root, candidate);
|
|
8967
|
+
return relative.length === 0 || !relative.startsWith("..") && !path10.isAbsolute(relative);
|
|
8882
8968
|
};
|
|
8883
8969
|
let packageRoot;
|
|
8884
8970
|
try {
|
|
8885
8971
|
const req = createRequire2(import.meta.url);
|
|
8886
8972
|
const openclawEntrypoint = realpathSync2(req.resolve("openclaw"));
|
|
8887
|
-
let currentDir =
|
|
8973
|
+
let currentDir = path10.dirname(openclawEntrypoint);
|
|
8888
8974
|
while (true) {
|
|
8889
|
-
const packageJsonPath =
|
|
8975
|
+
const packageJsonPath = path10.join(currentDir, "package.json");
|
|
8890
8976
|
if (existsSync(packageJsonPath)) {
|
|
8891
8977
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
8892
8978
|
if (packageJson.name !== "openclaw") {
|
|
@@ -8895,7 +8981,7 @@ async function findGatewayRuntimeModules(filePrefix) {
|
|
|
8895
8981
|
packageRoot = realpathSync2(currentDir);
|
|
8896
8982
|
break;
|
|
8897
8983
|
}
|
|
8898
|
-
const parent =
|
|
8984
|
+
const parent = path10.dirname(currentDir);
|
|
8899
8985
|
if (parent === currentDir) {
|
|
8900
8986
|
return [];
|
|
8901
8987
|
}
|
|
@@ -8905,14 +8991,14 @@ async function findGatewayRuntimeModules(filePrefix) {
|
|
|
8905
8991
|
return [];
|
|
8906
8992
|
}
|
|
8907
8993
|
try {
|
|
8908
|
-
const distDir = realpathSync2(
|
|
8994
|
+
const distDir = realpathSync2(path10.join(packageRoot, "dist"));
|
|
8909
8995
|
if (!isWithinRoot(packageRoot, distDir)) {
|
|
8910
8996
|
return [];
|
|
8911
8997
|
}
|
|
8912
8998
|
const files = readdirSync(distDir);
|
|
8913
8999
|
for (const f of files) {
|
|
8914
9000
|
if (f.startsWith(filePrefix) && f.endsWith(".js")) {
|
|
8915
|
-
const candidate = realpathSync2(
|
|
9001
|
+
const candidate = realpathSync2(path10.join(distDir, f));
|
|
8916
9002
|
if (isWithinRoot(packageRoot, candidate) && isWithinRoot(distDir, candidate)) {
|
|
8917
9003
|
candidates.push(candidate);
|
|
8918
9004
|
}
|
|
@@ -9255,7 +9341,7 @@ function resolveOpenClawConfigFilePath() {
|
|
|
9255
9341
|
if (explicitConfigPath && explicitConfigPath.length > 0) {
|
|
9256
9342
|
return expandTildePath4(explicitConfigPath);
|
|
9257
9343
|
}
|
|
9258
|
-
return
|
|
9344
|
+
return path11.join(resolveHomeDir3(), ".openclaw", "openclaw.json");
|
|
9259
9345
|
}
|
|
9260
9346
|
function coerceRawConfigBoolean(value) {
|
|
9261
9347
|
if (typeof value === "boolean") return value;
|
|
@@ -9302,7 +9388,7 @@ function readPluginHooksPolicy(apiConfig, pluginId) {
|
|
|
9302
9388
|
}
|
|
9303
9389
|
async function maybeRegisterLiveConnectorCron(orchestrator) {
|
|
9304
9390
|
if (!hasEnabledLiveConnectorConfig(orchestrator.config.connectors)) return;
|
|
9305
|
-
const jobsPath =
|
|
9391
|
+
const jobsPath = path11.join(resolveHomeDir3(), ".openclaw", "cron", "jobs.json");
|
|
9306
9392
|
try {
|
|
9307
9393
|
if (!fileExistsNow(jobsPath)) {
|
|
9308
9394
|
logger_exports.log.debug("live connectors cron: jobs.json not found, skipping auto-register");
|
|
@@ -9871,9 +9957,9 @@ var pluginDefinition = {
|
|
|
9871
9957
|
emitLegacyTools: cfg.emitLegacyTools
|
|
9872
9958
|
});
|
|
9873
9959
|
globalThis[keys.ACCESS_HTTP_SERVER] = accessHttpServer;
|
|
9874
|
-
const pluginStateDir =
|
|
9875
|
-
const togglePrimaryPath =
|
|
9876
|
-
const toggleSecondaryPath = cfg.respectBundledActiveMemoryToggle ?
|
|
9960
|
+
const pluginStateDir = path11.join(cfg.memoryDir, "state", "plugins", serviceId);
|
|
9961
|
+
const togglePrimaryPath = path11.join(pluginStateDir, "session-toggles.json");
|
|
9962
|
+
const toggleSecondaryPath = cfg.respectBundledActiveMemoryToggle ? path11.join(cfg.memoryDir, "state", "plugins", "active-memory", "session-toggles.json") : void 0;
|
|
9877
9963
|
const sessionToggleStore = createFileToggleStore2(togglePrimaryPath, {
|
|
9878
9964
|
secondaryReadOnlyPath: toggleSecondaryPath
|
|
9879
9965
|
});
|
|
@@ -9895,11 +9981,11 @@ var pluginDefinition = {
|
|
|
9895
9981
|
}
|
|
9896
9982
|
function resolveDreamJournalPath(runtimeWorkspaceDir) {
|
|
9897
9983
|
const workspaceRoot = resolveWorkspaceRoot(runtimeWorkspaceDir);
|
|
9898
|
-
return
|
|
9984
|
+
return path11.isAbsolute(cfg.dreaming.journalPath) ? cfg.dreaming.journalPath : path11.join(workspaceRoot, cfg.dreaming.journalPath);
|
|
9899
9985
|
}
|
|
9900
9986
|
function resolveHeartbeatJournalPath(runtimeWorkspaceDir) {
|
|
9901
9987
|
const workspaceRoot = resolveWorkspaceRoot(runtimeWorkspaceDir);
|
|
9902
|
-
return
|
|
9988
|
+
return path11.isAbsolute(cfg.heartbeat.journalPath) ? cfg.heartbeat.journalPath : path11.join(workspaceRoot, cfg.heartbeat.journalPath);
|
|
9903
9989
|
}
|
|
9904
9990
|
const existingFlushPlanProcessingChains = globalThis[keys.FLUSH_PLAN_PROCESSING_CHAINS];
|
|
9905
9991
|
const flushPlanProcessingChains = existingFlushPlanProcessingChains instanceof Map ? existingFlushPlanProcessingChains : /* @__PURE__ */ new Map();
|
|
@@ -10176,7 +10262,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
10176
10262
|
timeoutMs: cfg.activeRecallTimeoutMs,
|
|
10177
10263
|
cacheTtlMs: cfg.activeRecallCacheTtlMs,
|
|
10178
10264
|
persistTranscripts: cfg.activeRecallPersistTranscripts,
|
|
10179
|
-
transcriptDir:
|
|
10265
|
+
transcriptDir: path11.isAbsolute(cfg.activeRecallTranscriptDir) ? cfg.activeRecallTranscriptDir : path11.join(pluginStateDir, cfg.activeRecallTranscriptDir),
|
|
10180
10266
|
entityGraphDepth: cfg.activeRecallEntityGraphDepth,
|
|
10181
10267
|
includeCausalTrajectories: cfg.activeRecallIncludeCausalTrajectories,
|
|
10182
10268
|
includeDaySummary: cfg.activeRecallIncludeDaySummary,
|
|
@@ -11725,7 +11811,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11725
11811
|
`session reset via API for ${sessionKey}, new sessionId=${result.sessionId}`
|
|
11726
11812
|
);
|
|
11727
11813
|
const safeSessionKey = sanitizeSessionKeyForFilename(sessionKey);
|
|
11728
|
-
const signalPath =
|
|
11814
|
+
const signalPath = path11.join(
|
|
11729
11815
|
workspaceDir,
|
|
11730
11816
|
`.compaction-reset-signal-${safeSessionKey}`
|
|
11731
11817
|
);
|
|
@@ -11944,7 +12030,7 @@ Keep the reflection grounded in the evidence below.
|
|
|
11944
12030
|
}
|
|
11945
12031
|
async function ensureHourlySummaryCron(api2) {
|
|
11946
12032
|
const jobId = "engram-hourly-summary";
|
|
11947
|
-
const cronFilePath =
|
|
12033
|
+
const cronFilePath = path11.join(
|
|
11948
12034
|
os.homedir(),
|
|
11949
12035
|
".openclaw",
|
|
11950
12036
|
"cron",
|
|
@@ -12003,32 +12089,32 @@ Keep the reflection grounded in the evidence below.
|
|
|
12003
12089
|
};
|
|
12004
12090
|
const normalizeCorpusPath = (value) => value.trim().replace(/\\/g, "/").replace(/^\.\//, "");
|
|
12005
12091
|
const pathIsInside = (root, candidate) => {
|
|
12006
|
-
const relative =
|
|
12007
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
12092
|
+
const relative = path11.relative(root, candidate);
|
|
12093
|
+
return relative === "" || !relative.startsWith("..") && !path11.isAbsolute(relative);
|
|
12008
12094
|
};
|
|
12009
12095
|
const corpusPathCandidates = (rawPath, storageDir) => {
|
|
12010
12096
|
const candidates = /* @__PURE__ */ new Set();
|
|
12011
12097
|
const trimmed = rawPath.trim();
|
|
12012
12098
|
if (!trimmed) return [];
|
|
12013
12099
|
candidates.add(normalizeCorpusPath(trimmed));
|
|
12014
|
-
if (
|
|
12015
|
-
const absolutePath =
|
|
12016
|
-
const absoluteStorageDir =
|
|
12100
|
+
if (path11.isAbsolute(trimmed)) {
|
|
12101
|
+
const absolutePath = path11.resolve(trimmed);
|
|
12102
|
+
const absoluteStorageDir = path11.resolve(storageDir);
|
|
12017
12103
|
if (pathIsInside(absoluteStorageDir, absolutePath)) {
|
|
12018
|
-
candidates.add(normalizeCorpusPath(
|
|
12104
|
+
candidates.add(normalizeCorpusPath(path11.relative(absoluteStorageDir, absolutePath)));
|
|
12019
12105
|
}
|
|
12020
12106
|
}
|
|
12021
|
-
candidates.add(
|
|
12107
|
+
candidates.add(path11.basename(trimmed));
|
|
12022
12108
|
return [...candidates].filter((candidate) => candidate.length > 0);
|
|
12023
12109
|
};
|
|
12024
12110
|
const displayCorpusPath = (rawPath, storageDir) => {
|
|
12025
12111
|
const trimmed = rawPath.trim();
|
|
12026
12112
|
if (!trimmed) return "";
|
|
12027
|
-
if (
|
|
12028
|
-
const absolutePath =
|
|
12029
|
-
const absoluteStorageDir =
|
|
12113
|
+
if (path11.isAbsolute(trimmed)) {
|
|
12114
|
+
const absolutePath = path11.resolve(trimmed);
|
|
12115
|
+
const absoluteStorageDir = path11.resolve(storageDir);
|
|
12030
12116
|
if (pathIsInside(absoluteStorageDir, absolutePath)) {
|
|
12031
|
-
return normalizeCorpusPath(
|
|
12117
|
+
return normalizeCorpusPath(path11.relative(absoluteStorageDir, absolutePath));
|
|
12032
12118
|
}
|
|
12033
12119
|
}
|
|
12034
12120
|
return normalizeCorpusPath(trimmed);
|
|
@@ -12542,9 +12628,9 @@ function truncateMetadataValue(value, maxChars) {
|
|
|
12542
12628
|
return value.length <= maxChars ? value : value.slice(0, maxChars);
|
|
12543
12629
|
}
|
|
12544
12630
|
async function resolveFlushPlanProcessingChainKey(workspaceRoot) {
|
|
12545
|
-
const lexicalRoot =
|
|
12631
|
+
const lexicalRoot = path11.resolve(workspaceRoot);
|
|
12546
12632
|
try {
|
|
12547
|
-
return
|
|
12633
|
+
return path11.resolve(await realPathLater(lexicalRoot));
|
|
12548
12634
|
} catch {
|
|
12549
12635
|
return lexicalRoot;
|
|
12550
12636
|
}
|