@totalreclaw/totalreclaw 3.3.9-rc.1 → 3.3.9-rc.2
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/CHANGELOG.md +17 -0
- package/SKILL.md +1 -1
- package/dist/fs-helpers.js +82 -0
- package/dist/index.js +40 -1
- package/fs-helpers.ts +108 -0
- package/index.ts +43 -0
- package/package.json +1 -1
- package/skill.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to `@totalreclaw/totalreclaw` (the OpenClaw plugin) are docu
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [3.3.9-rc.2] — 2026-05-02
|
|
8
|
+
|
|
9
|
+
Patch release fixing the two OpenClaw 2026.5.x compatibility blockers discovered during 3.3.9-rc.1 auto-QA ([umbrella #224](https://github.com/p-diogo/totalreclaw-internal/issues/224)).
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Finding #1 — memory slot not auto-assigned on install ([#225](https://github.com/p-diogo/totalreclaw-internal/issues/225)):** OpenClaw 2026.5.x introduced memory-slot exclusivity — a `kind: memory` plugin must explicitly claim `plugins.slots.memory` in `openclaw.json` or it is silently disabled ("memory slot set to memory-core"). Previously required manual config edit with no user-visible error. The plugin's `register()` now calls `patchOpenClawConfig()` at startup, which idempotently writes `plugins.slots.memory = "totalreclaw"` if absent. If the file was patched, a warn is emitted asking for a gateway restart.
|
|
14
|
+
|
|
15
|
+
- **Finding #2 — conversation hooks blocked by missing `allowConversationAccess` ([#226](https://github.com/p-diogo/totalreclaw-internal/issues/226)):** OpenClaw 2026.5.x requires `plugins.entries.totalreclaw.hooks.allowConversationAccess = true` for non-bundled plugins to receive `agent_end` and `before_agent_start` hooks. Without it, auto-extraction and recall injection are silently disabled — the hooks simply never fire. The same `patchOpenClawConfig()` call now idempotently writes this key alongside the slot claim.
|
|
16
|
+
|
|
17
|
+
### Implementation notes
|
|
18
|
+
|
|
19
|
+
- `patchOpenClawConfig()` added to `fs-helpers.ts` — synchronous, best-effort, scanner-safe (pure `node:fs` / `node:path`, no network markers).
|
|
20
|
+
- Called early in `register()` (after install-staging cleanup, before LLM init). Idempotent — if both keys are already correct the file is not touched.
|
|
21
|
+
- Results: `'patched'` (file mutated — warn + restart instruction), `'unchanged'` (no-op), `'skipped'` (no `openclaw.json` found — non-OpenClaw host), `'error'` (parse/write failure — warn with manual instructions).
|
|
22
|
+
- **Restart required when patched:** OpenClaw reads `openclaw.json` at startup. When this runs on the FIRST boot after install, it patches the file and emits the restart warning. After the user restarts, the second boot picks up the keys and all hooks fire normally.
|
|
23
|
+
|
|
7
24
|
## [3.3.9-rc.1] — 2026-05-02
|
|
8
25
|
|
|
9
26
|
Pedro's QA on 3.3.8-rc.1 (Telegram → canonical OpenClaw 2026.5.2) revealed five issues that all stem from the same architectural problem — TotalReclaw's tools registered via `api.registerTool()` are blocked by OpenClaw 2026.5.2's tool-policy strip race (issue #223, filed upstream). Each release we ship adds a fix for one gate, hits another. 3.3.9-rc.1 pivots to hybrid-primary: the `tr` CLI is now the PRIMARY path. Native tools are kept for back-compat only.
|
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: totalreclaw
|
|
3
3
|
description: "Install + set up TotalReclaw encrypted memory for OpenClaw, then use tr CLI for remember / recall. Trigger on 'install TotalReclaw', 'set up TotalReclaw', 'restore my recovery phrase', or any remember / recall request."
|
|
4
|
-
version: 3.3.9-rc.
|
|
4
|
+
version: 3.3.9-rc.2
|
|
5
5
|
author: TotalReclaw Team
|
|
6
6
|
license: MIT
|
|
7
7
|
homepage: https://totalreclaw.xyz
|
package/dist/fs-helpers.js
CHANGED
|
@@ -929,3 +929,85 @@ export function resolveOnboardingState(credentialsPath, statePath) {
|
|
|
929
929
|
writeOnboardingState(statePath, next);
|
|
930
930
|
return next;
|
|
931
931
|
}
|
|
932
|
+
/**
|
|
933
|
+
* Auto-patch `~/.openclaw/openclaw.json` with the two entries required by
|
|
934
|
+
* OpenClaw 2026.5.x for `kind: memory` plugins (issues #225 + #226):
|
|
935
|
+
*
|
|
936
|
+
* 1. `plugins.slots.memory = "totalreclaw"`
|
|
937
|
+
* Claim the memory slot so the plugin loads instead of deferring to
|
|
938
|
+
* the built-in `memory-core` tenant.
|
|
939
|
+
*
|
|
940
|
+
* 2. `plugins.entries.totalreclaw.hooks.allowConversationAccess = true`
|
|
941
|
+
* Grant the plugin access to `agent_end` and `before_agent_start`
|
|
942
|
+
* hooks. Without this flag OpenClaw 2026.5.x silently blocks both
|
|
943
|
+
* hooks for non-bundled plugins, disabling auto-extraction and
|
|
944
|
+
* recall injection.
|
|
945
|
+
*
|
|
946
|
+
* Design constraints
|
|
947
|
+
* ------------------
|
|
948
|
+
* - SYNCHRONOUS — called during register() which must be sync.
|
|
949
|
+
* - IDEMPOTENT — reads existing values before deciding to write; no-ops
|
|
950
|
+
* when both keys are already correct.
|
|
951
|
+
* - BEST-EFFORT — all errors are swallowed; the plugin keeps loading even
|
|
952
|
+
* if the patch fails. The caller logs an actionable warning.
|
|
953
|
+
* - SCANNER-SAFE — pure `node:fs` / `node:path`; no outbound markers.
|
|
954
|
+
*
|
|
955
|
+
* Restart semantics
|
|
956
|
+
* -----------------
|
|
957
|
+
* OpenClaw reads `openclaw.json` at gateway startup, not dynamically.
|
|
958
|
+
* When `patchOpenClawConfig` writes new keys during the CURRENT gateway
|
|
959
|
+
* boot, the keys take effect ONLY after the gateway is restarted. The
|
|
960
|
+
* plugin must tell the user via `api.logger.warn` so they know to run
|
|
961
|
+
* `/totalreclaw-restart` or restart the gateway manually.
|
|
962
|
+
*
|
|
963
|
+
* @param configPath Absolute path to `openclaw.json`.
|
|
964
|
+
* Defaults to `<home>/.openclaw/openclaw.json`.
|
|
965
|
+
*/
|
|
966
|
+
export function patchOpenClawConfig(configPath) {
|
|
967
|
+
const home = process.env.HOME ?? '/home/node';
|
|
968
|
+
const target = configPath ?? path.join(home, '.openclaw', 'openclaw.json');
|
|
969
|
+
// `'skipped'` when the config file is absent — this host may not be
|
|
970
|
+
// running OpenClaw, or may use a non-standard config location.
|
|
971
|
+
if (!fs.existsSync(target))
|
|
972
|
+
return 'skipped';
|
|
973
|
+
try {
|
|
974
|
+
const raw = fs.readFileSync(target, 'utf-8');
|
|
975
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
976
|
+
const cfg = JSON.parse(raw);
|
|
977
|
+
// Ensure the `plugins` key exists.
|
|
978
|
+
if (typeof cfg.plugins !== 'object' || cfg.plugins === null) {
|
|
979
|
+
cfg.plugins = {};
|
|
980
|
+
}
|
|
981
|
+
let mutated = false;
|
|
982
|
+
// --- Fix #1: plugins.slots.memory = "totalreclaw" ---
|
|
983
|
+
if (typeof cfg.plugins.slots !== 'object' || cfg.plugins.slots === null) {
|
|
984
|
+
cfg.plugins.slots = {};
|
|
985
|
+
}
|
|
986
|
+
if (cfg.plugins.slots.memory !== 'totalreclaw') {
|
|
987
|
+
cfg.plugins.slots.memory = 'totalreclaw';
|
|
988
|
+
mutated = true;
|
|
989
|
+
}
|
|
990
|
+
// --- Fix #2: plugins.entries.totalreclaw.hooks.allowConversationAccess = true ---
|
|
991
|
+
if (typeof cfg.plugins.entries !== 'object' || cfg.plugins.entries === null) {
|
|
992
|
+
cfg.plugins.entries = {};
|
|
993
|
+
}
|
|
994
|
+
if (typeof cfg.plugins.entries.totalreclaw !== 'object' || cfg.plugins.entries.totalreclaw === null) {
|
|
995
|
+
cfg.plugins.entries.totalreclaw = {};
|
|
996
|
+
}
|
|
997
|
+
if (typeof cfg.plugins.entries.totalreclaw.hooks !== 'object' || cfg.plugins.entries.totalreclaw.hooks === null) {
|
|
998
|
+
cfg.plugins.entries.totalreclaw.hooks = {};
|
|
999
|
+
}
|
|
1000
|
+
if (cfg.plugins.entries.totalreclaw.hooks.allowConversationAccess !== true) {
|
|
1001
|
+
cfg.plugins.entries.totalreclaw.hooks.allowConversationAccess = true;
|
|
1002
|
+
mutated = true;
|
|
1003
|
+
}
|
|
1004
|
+
if (!mutated)
|
|
1005
|
+
return 'unchanged';
|
|
1006
|
+
// Write back with 2-space indent to match OpenClaw's own write style.
|
|
1007
|
+
fs.writeFileSync(target, JSON.stringify(cfg, null, 2) + '\n');
|
|
1008
|
+
return 'patched';
|
|
1009
|
+
}
|
|
1010
|
+
catch {
|
|
1011
|
+
return 'error';
|
|
1012
|
+
}
|
|
1013
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -66,7 +66,7 @@ import { PluginHotCache } from './hot-cache-wrapper.js';
|
|
|
66
66
|
import { CONFIG, setRecoveryPhraseOverride } from './config.js';
|
|
67
67
|
import { buildRelayHeaders } from './relay-headers.js';
|
|
68
68
|
import { readBillingCache, writeBillingCache, BILLING_CACHE_PATH, } from './billing-cache.js';
|
|
69
|
-
import { ensureMemoryHeaderFile, loadCredentialsJson, writeCredentialsJson, deleteCredentialsFile, isRunningInDocker, deleteFileIfExists, resolveOnboardingState, writeOnboardingState, readPluginVersion, cleanupInstallStagingDirs, clearPartialInstallMarker, writePluginManifest, writePluginError, readPluginLoadedManifest, } from './fs-helpers.js';
|
|
69
|
+
import { ensureMemoryHeaderFile, loadCredentialsJson, writeCredentialsJson, deleteCredentialsFile, isRunningInDocker, deleteFileIfExists, resolveOnboardingState, writeOnboardingState, readPluginVersion, cleanupInstallStagingDirs, clearPartialInstallMarker, patchOpenClawConfig, writePluginManifest, writePluginError, readPluginLoadedManifest, } from './fs-helpers.js';
|
|
70
70
|
import { isRcBuild } from './qa-bug-report.js';
|
|
71
71
|
import { decideToolGate, isGatedToolName } from './tool-gating.js';
|
|
72
72
|
import { resolveRestartAuth, rejectMessageFor, } from './restart-auth.js';
|
|
@@ -2531,6 +2531,45 @@ const plugin = {
|
|
|
2531
2531
|
catch {
|
|
2532
2532
|
// Best-effort. Helper logs internally and never throws.
|
|
2533
2533
|
}
|
|
2534
|
+
// 3.3.9-rc.2 (issues #225 + #226): auto-patch openclaw.json for
|
|
2535
|
+
// OpenClaw 2026.5.x. Two required config keys were not auto-applied
|
|
2536
|
+
// by `openclaw plugins install` in 2026.5.x:
|
|
2537
|
+
//
|
|
2538
|
+
// 1. plugins.slots.memory = "totalreclaw"
|
|
2539
|
+
// OpenClaw 2026.5.x introduced memory-slot exclusivity — a
|
|
2540
|
+
// memory-kind plugin MUST explicitly claim the slot or it is
|
|
2541
|
+
// silently disabled (no error shown; `openclaw plugins inspect`
|
|
2542
|
+
// shows "memory slot set to memory-core"). #225.
|
|
2543
|
+
//
|
|
2544
|
+
// 2. plugins.entries.totalreclaw.hooks.allowConversationAccess = true
|
|
2545
|
+
// Non-bundled plugins in 2026.5.x require this flag to receive
|
|
2546
|
+
// agent_end and before_agent_start hooks. Without it, auto-
|
|
2547
|
+
// extraction and recall injection are silently disabled. #226.
|
|
2548
|
+
//
|
|
2549
|
+
// The patch is idempotent — if both keys are already correct the
|
|
2550
|
+
// file is not touched. When the file IS mutated a restart is
|
|
2551
|
+
// required for the new keys to take effect (OpenClaw reads
|
|
2552
|
+
// openclaw.json at startup, not dynamically). We emit a warn so
|
|
2553
|
+
// the user and ops scripts know to trigger a restart.
|
|
2554
|
+
try {
|
|
2555
|
+
const patchResult = patchOpenClawConfig();
|
|
2556
|
+
if (patchResult === 'patched') {
|
|
2557
|
+
api.logger.warn('TotalReclaw: updated openclaw.json with required 2026.5.x keys ' +
|
|
2558
|
+
'(plugins.slots.memory + hooks.allowConversationAccess). ' +
|
|
2559
|
+
'Gateway restart required for the changes to take effect. ' +
|
|
2560
|
+
'Run `/totalreclaw-restart` or restart the gateway manually.');
|
|
2561
|
+
}
|
|
2562
|
+
else if (patchResult === 'error') {
|
|
2563
|
+
api.logger.warn('TotalReclaw: failed to auto-patch openclaw.json for OpenClaw 2026.5.x ' +
|
|
2564
|
+
'compatibility. If memory hooks are silently disabled, add these keys ' +
|
|
2565
|
+
'manually: plugins.slots.memory="totalreclaw" and ' +
|
|
2566
|
+
'plugins.entries.totalreclaw.hooks.allowConversationAccess=true.');
|
|
2567
|
+
}
|
|
2568
|
+
// 'unchanged' and 'skipped' are silent — no log needed.
|
|
2569
|
+
}
|
|
2570
|
+
catch {
|
|
2571
|
+
// Best-effort — never let config-patch failure block plugin load.
|
|
2572
|
+
}
|
|
2534
2573
|
}
|
|
2535
2574
|
catch {
|
|
2536
2575
|
rcMode = false;
|
package/fs-helpers.ts
CHANGED
|
@@ -1126,3 +1126,111 @@ export function resolveOnboardingState(
|
|
|
1126
1126
|
writeOnboardingState(statePath, next);
|
|
1127
1127
|
return next;
|
|
1128
1128
|
}
|
|
1129
|
+
|
|
1130
|
+
// ---------------------------------------------------------------------------
|
|
1131
|
+
// OpenClaw 2026.5.x config auto-patch (3.3.9-rc.2 — issues #225 + #226)
|
|
1132
|
+
// ---------------------------------------------------------------------------
|
|
1133
|
+
|
|
1134
|
+
/**
|
|
1135
|
+
* Outcome of `patchOpenClawConfig`.
|
|
1136
|
+
* - `'patched'` — one or more required keys were missing; file was updated.
|
|
1137
|
+
* Caller must log a message telling the user to restart.
|
|
1138
|
+
* - `'unchanged'` — all required keys already present; no write.
|
|
1139
|
+
* - `'skipped'` — config file not found (not an OpenClaw host, or pre-2026
|
|
1140
|
+
* version that uses a different config path). Caller is safe
|
|
1141
|
+
* to ignore.
|
|
1142
|
+
* - `'error'` — file exists but read/parse/write failed. Caller logs
|
|
1143
|
+
* warn and continues — the plugin still loads, the user
|
|
1144
|
+
* must apply the keys manually.
|
|
1145
|
+
*/
|
|
1146
|
+
export type OpenClawConfigPatchResult = 'patched' | 'unchanged' | 'skipped' | 'error';
|
|
1147
|
+
|
|
1148
|
+
/**
|
|
1149
|
+
* Auto-patch `~/.openclaw/openclaw.json` with the two entries required by
|
|
1150
|
+
* OpenClaw 2026.5.x for `kind: memory` plugins (issues #225 + #226):
|
|
1151
|
+
*
|
|
1152
|
+
* 1. `plugins.slots.memory = "totalreclaw"`
|
|
1153
|
+
* Claim the memory slot so the plugin loads instead of deferring to
|
|
1154
|
+
* the built-in `memory-core` tenant.
|
|
1155
|
+
*
|
|
1156
|
+
* 2. `plugins.entries.totalreclaw.hooks.allowConversationAccess = true`
|
|
1157
|
+
* Grant the plugin access to `agent_end` and `before_agent_start`
|
|
1158
|
+
* hooks. Without this flag OpenClaw 2026.5.x silently blocks both
|
|
1159
|
+
* hooks for non-bundled plugins, disabling auto-extraction and
|
|
1160
|
+
* recall injection.
|
|
1161
|
+
*
|
|
1162
|
+
* Design constraints
|
|
1163
|
+
* ------------------
|
|
1164
|
+
* - SYNCHRONOUS — called during register() which must be sync.
|
|
1165
|
+
* - IDEMPOTENT — reads existing values before deciding to write; no-ops
|
|
1166
|
+
* when both keys are already correct.
|
|
1167
|
+
* - BEST-EFFORT — all errors are swallowed; the plugin keeps loading even
|
|
1168
|
+
* if the patch fails. The caller logs an actionable warning.
|
|
1169
|
+
* - SCANNER-SAFE — pure `node:fs` / `node:path`; no outbound markers.
|
|
1170
|
+
*
|
|
1171
|
+
* Restart semantics
|
|
1172
|
+
* -----------------
|
|
1173
|
+
* OpenClaw reads `openclaw.json` at gateway startup, not dynamically.
|
|
1174
|
+
* When `patchOpenClawConfig` writes new keys during the CURRENT gateway
|
|
1175
|
+
* boot, the keys take effect ONLY after the gateway is restarted. The
|
|
1176
|
+
* plugin must tell the user via `api.logger.warn` so they know to run
|
|
1177
|
+
* `/totalreclaw-restart` or restart the gateway manually.
|
|
1178
|
+
*
|
|
1179
|
+
* @param configPath Absolute path to `openclaw.json`.
|
|
1180
|
+
* Defaults to `<home>/.openclaw/openclaw.json`.
|
|
1181
|
+
*/
|
|
1182
|
+
export function patchOpenClawConfig(
|
|
1183
|
+
configPath?: string,
|
|
1184
|
+
): OpenClawConfigPatchResult {
|
|
1185
|
+
const home = process.env.HOME ?? '/home/node';
|
|
1186
|
+
const target = configPath ?? path.join(home, '.openclaw', 'openclaw.json');
|
|
1187
|
+
|
|
1188
|
+
// `'skipped'` when the config file is absent — this host may not be
|
|
1189
|
+
// running OpenClaw, or may use a non-standard config location.
|
|
1190
|
+
if (!fs.existsSync(target)) return 'skipped';
|
|
1191
|
+
|
|
1192
|
+
try {
|
|
1193
|
+
const raw = fs.readFileSync(target, 'utf-8');
|
|
1194
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1195
|
+
const cfg = JSON.parse(raw) as Record<string, any>;
|
|
1196
|
+
|
|
1197
|
+
// Ensure the `plugins` key exists.
|
|
1198
|
+
if (typeof cfg.plugins !== 'object' || cfg.plugins === null) {
|
|
1199
|
+
cfg.plugins = {};
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
let mutated = false;
|
|
1203
|
+
|
|
1204
|
+
// --- Fix #1: plugins.slots.memory = "totalreclaw" ---
|
|
1205
|
+
if (typeof cfg.plugins.slots !== 'object' || cfg.plugins.slots === null) {
|
|
1206
|
+
cfg.plugins.slots = {};
|
|
1207
|
+
}
|
|
1208
|
+
if (cfg.plugins.slots.memory !== 'totalreclaw') {
|
|
1209
|
+
cfg.plugins.slots.memory = 'totalreclaw';
|
|
1210
|
+
mutated = true;
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1213
|
+
// --- Fix #2: plugins.entries.totalreclaw.hooks.allowConversationAccess = true ---
|
|
1214
|
+
if (typeof cfg.plugins.entries !== 'object' || cfg.plugins.entries === null) {
|
|
1215
|
+
cfg.plugins.entries = {};
|
|
1216
|
+
}
|
|
1217
|
+
if (typeof cfg.plugins.entries.totalreclaw !== 'object' || cfg.plugins.entries.totalreclaw === null) {
|
|
1218
|
+
cfg.plugins.entries.totalreclaw = {};
|
|
1219
|
+
}
|
|
1220
|
+
if (typeof cfg.plugins.entries.totalreclaw.hooks !== 'object' || cfg.plugins.entries.totalreclaw.hooks === null) {
|
|
1221
|
+
cfg.plugins.entries.totalreclaw.hooks = {};
|
|
1222
|
+
}
|
|
1223
|
+
if (cfg.plugins.entries.totalreclaw.hooks.allowConversationAccess !== true) {
|
|
1224
|
+
cfg.plugins.entries.totalreclaw.hooks.allowConversationAccess = true;
|
|
1225
|
+
mutated = true;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
if (!mutated) return 'unchanged';
|
|
1229
|
+
|
|
1230
|
+
// Write back with 2-space indent to match OpenClaw's own write style.
|
|
1231
|
+
fs.writeFileSync(target, JSON.stringify(cfg, null, 2) + '\n');
|
|
1232
|
+
return 'patched';
|
|
1233
|
+
} catch {
|
|
1234
|
+
return 'error';
|
|
1235
|
+
}
|
|
1236
|
+
}
|
package/index.ts
CHANGED
|
@@ -165,6 +165,7 @@ import {
|
|
|
165
165
|
cleanupInstallStagingDirs,
|
|
166
166
|
detectPartialInstall,
|
|
167
167
|
clearPartialInstallMarker,
|
|
168
|
+
patchOpenClawConfig,
|
|
168
169
|
writePluginManifest,
|
|
169
170
|
writePluginError,
|
|
170
171
|
readPluginLoadedManifest,
|
|
@@ -3108,6 +3109,48 @@ const plugin = {
|
|
|
3108
3109
|
} catch {
|
|
3109
3110
|
// Best-effort. Helper logs internally and never throws.
|
|
3110
3111
|
}
|
|
3112
|
+
|
|
3113
|
+
// 3.3.9-rc.2 (issues #225 + #226): auto-patch openclaw.json for
|
|
3114
|
+
// OpenClaw 2026.5.x. Two required config keys were not auto-applied
|
|
3115
|
+
// by `openclaw plugins install` in 2026.5.x:
|
|
3116
|
+
//
|
|
3117
|
+
// 1. plugins.slots.memory = "totalreclaw"
|
|
3118
|
+
// OpenClaw 2026.5.x introduced memory-slot exclusivity — a
|
|
3119
|
+
// memory-kind plugin MUST explicitly claim the slot or it is
|
|
3120
|
+
// silently disabled (no error shown; `openclaw plugins inspect`
|
|
3121
|
+
// shows "memory slot set to memory-core"). #225.
|
|
3122
|
+
//
|
|
3123
|
+
// 2. plugins.entries.totalreclaw.hooks.allowConversationAccess = true
|
|
3124
|
+
// Non-bundled plugins in 2026.5.x require this flag to receive
|
|
3125
|
+
// agent_end and before_agent_start hooks. Without it, auto-
|
|
3126
|
+
// extraction and recall injection are silently disabled. #226.
|
|
3127
|
+
//
|
|
3128
|
+
// The patch is idempotent — if both keys are already correct the
|
|
3129
|
+
// file is not touched. When the file IS mutated a restart is
|
|
3130
|
+
// required for the new keys to take effect (OpenClaw reads
|
|
3131
|
+
// openclaw.json at startup, not dynamically). We emit a warn so
|
|
3132
|
+
// the user and ops scripts know to trigger a restart.
|
|
3133
|
+
try {
|
|
3134
|
+
const patchResult = patchOpenClawConfig();
|
|
3135
|
+
if (patchResult === 'patched') {
|
|
3136
|
+
api.logger.warn(
|
|
3137
|
+
'TotalReclaw: updated openclaw.json with required 2026.5.x keys ' +
|
|
3138
|
+
'(plugins.slots.memory + hooks.allowConversationAccess). ' +
|
|
3139
|
+
'Gateway restart required for the changes to take effect. ' +
|
|
3140
|
+
'Run `/totalreclaw-restart` or restart the gateway manually.',
|
|
3141
|
+
);
|
|
3142
|
+
} else if (patchResult === 'error') {
|
|
3143
|
+
api.logger.warn(
|
|
3144
|
+
'TotalReclaw: failed to auto-patch openclaw.json for OpenClaw 2026.5.x ' +
|
|
3145
|
+
'compatibility. If memory hooks are silently disabled, add these keys ' +
|
|
3146
|
+
'manually: plugins.slots.memory="totalreclaw" and ' +
|
|
3147
|
+
'plugins.entries.totalreclaw.hooks.allowConversationAccess=true.',
|
|
3148
|
+
);
|
|
3149
|
+
}
|
|
3150
|
+
// 'unchanged' and 'skipped' are silent — no log needed.
|
|
3151
|
+
} catch {
|
|
3152
|
+
// Best-effort — never let config-patch failure block plugin load.
|
|
3153
|
+
}
|
|
3111
3154
|
} catch {
|
|
3112
3155
|
rcMode = false;
|
|
3113
3156
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totalreclaw/totalreclaw",
|
|
3
|
-
"version": "3.3.9-rc.
|
|
3
|
+
"version": "3.3.9-rc.2",
|
|
4
4
|
"description": "End-to-end encrypted, agent-portable memory for OpenClaw and any LLM-agent runtime. XChaCha20-Poly1305 with protobuf v4 + on-chain Memory Taxonomy v1 (claim / preference / directive / commitment / episode / summary).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
package/skill.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "totalreclaw",
|
|
3
|
-
"version": "3.3.9-rc.
|
|
3
|
+
"version": "3.3.9-rc.2",
|
|
4
4
|
"description": "End-to-end encrypted memory for AI agents — portable, yours forever. XChaCha20-Poly1305 E2EE: server never sees plaintext.",
|
|
5
5
|
"author": "TotalReclaw Team",
|
|
6
6
|
"license": "MIT",
|