@totalreclaw/totalreclaw 3.3.4-rc.2 → 3.3.6-rc.1
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 +60 -0
- package/SKILL.md +49 -12
- package/dist/fs-helpers.js +28 -20
- package/dist/index.js +11 -7
- package/fs-helpers.ts +26 -18
- package/index.ts +11 -7
- package/package.json +1 -2
- package/skill.json +126 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,66 @@ 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.6-rc.1] — 2026-05-01
|
|
8
|
+
|
|
9
|
+
Patch wave from Pedro's second QA cycle on 3.3.5-rc.1.
|
|
10
|
+
|
|
11
|
+
### Fixed — `/new` fallback regression from PR #175
|
|
12
|
+
|
|
13
|
+
PR #175 told the agent to suggest `/new` when `/restart` returned "not authorized". Pedro QA observed that this backfires: `/new` wipes the chat context, the agent forgets it was mid-install, treats the user's next message as a fresh install request, retries from scratch, and re-trips the scanner block on the partial-install dir.
|
|
14
|
+
|
|
15
|
+
Removed `/new` as a fallback for `/restart` failures from `skill/plugin/SKILL.md` and `docs/guides/openclaw-setup.md`. The only correct response when `/restart` is unauthorized is to surface the verbatim user-facing fix (`jq` + `docker restart`) and wait for `done`.
|
|
16
|
+
|
|
17
|
+
### Removed — `preinstall` script (`.tr-partial-install` marker write)
|
|
18
|
+
|
|
19
|
+
`skill/plugin/package.json::scripts.preinstall` was a `node -e` shell-exec that wrote a `.tr-partial-install` marker file at npm-install time. Removed entirely.
|
|
20
|
+
|
|
21
|
+
Why this is safe:
|
|
22
|
+
- OpenClaw's `openclaw plugins install` invokes `npm install --ignore-scripts`, so the `preinstall` script literally never fired in the canonical install path. The marker write was already dead code in the OpenClaw flow.
|
|
23
|
+
- `preinstall` ran via `node -e "require('fs').writeFileSync(...)"` — a node-eval shell-exec pattern that, while not flagged by the OpenClaw scanner today (the scanner does not inspect `package.json`), was a latent risk if the scanner spec ever extends to lifecycle scripts.
|
|
24
|
+
- The runtime canonical signal for partial-install detection is `dist/index.js` missing (Rule 5 in `fs-helpers.ts::detectPartialInstall`). The marker file (Rule 4) was a redundant second-line check; its absence does not weaken detection.
|
|
25
|
+
- `clearPartialInstallMarker()` in `index.ts::register()` is idempotent and returns `false` when the marker is absent — no behavioral change for clean installs.
|
|
26
|
+
- Helpers `writePartialInstallMarker()` / `clearPartialInstallMarker()` remain exported for backward compat and for legacy installs that may have a stale marker on disk.
|
|
27
|
+
|
|
28
|
+
Tests preserved unchanged: `partial-install-detection.test.ts`, `install-reload-idempotency.test.ts`, `install-staging-cleanup.test.ts`, and `fs-helpers.test.ts` all still exercise the helper round-trip without depending on the npm script.
|
|
29
|
+
|
|
30
|
+
### Added — top-level `tools` array in `skill/plugin/skill.json`
|
|
31
|
+
|
|
32
|
+
Per PR #154 / #185, `totalreclaw_pair` is declared at the skill layer in `openclaw.tools` so it appears in the registry catalog independent of plugin runtime register(). Added a top-level `tools` array as a defensive companion (mirrors the `openclaw.tools` entries with a `handler: "./dist/index.js"` pointer to the runtime impl) for any tool resolver that reads top-level `tools` rather than `openclaw.tools`.
|
|
33
|
+
|
|
34
|
+
Caveat: based on inspection of OpenClaw 2026.3.x reference plugins (`extensions/llm-task`, `extensions/memory-core`), OpenClaw itself does not currently parse `skill.json` at install time — tool binding happens via runtime `api.registerTool()`. The skill-layer declaration mechanism may not solve the post-install tool-binding race on its own; upstream OpenClaw work is required for an auto-refresh of the agent toolset on plugin load. Tracked separately by Pedro's research agent.
|
|
35
|
+
|
|
36
|
+
## [3.3.5-rc.1] — 2026-04-30
|
|
37
|
+
|
|
38
|
+
UX bundle from Pedro's QA on 3.3.4-rc.2:
|
|
39
|
+
|
|
40
|
+
- **Drop the "yes/no" consent gate before pair setup.** The yes-gate was added
|
|
41
|
+
in PR #160's safety-tone rewrite to give safety-trained agents an explicit
|
|
42
|
+
green light before account creation. In practice the user already consents
|
|
43
|
+
by pasting "Install TotalReclaw" + the canonical URL, and the URL+PIN handed
|
|
44
|
+
back from `totalreclaw_pair` is the real consent moment (the user has to
|
|
45
|
+
open the page in their browser to proceed). The extra gate added friction
|
|
46
|
+
for zero security benefit. Removed from `skill/plugin/SKILL.md`,
|
|
47
|
+
`skill/SKILL.md`, and `docs/guides/openclaw-setup.md`. The Hermes guide
|
|
48
|
+
retains its own gate (handled separately).
|
|
49
|
+
- **Tighten silence rules to suppress chat-channel mid-edit churn.** OpenClaw's
|
|
50
|
+
Telegram channel edits the bot's messages live as the agent's tool calls
|
|
51
|
+
progress, so every "Let me check…" / "Plugin loaded. Let me verify…" /
|
|
52
|
+
"I'll now…" line shows up to the user as visible edit churn even if the
|
|
53
|
+
transport later "deletes" or rewrites it. Added a top-level rule at the
|
|
54
|
+
start of SKILL.md: "Emit ONLY the user-visible lines. Do not narrate tool
|
|
55
|
+
calls. Do not describe what you're doing or about to do." Strengthened the
|
|
56
|
+
forbidden-vocabulary deny-list with the exact patterns Pedro saw in his
|
|
57
|
+
QA today. Re-stated the canonical user-visible line set as 5–6 lines
|
|
58
|
+
TOTAL.
|
|
59
|
+
- **Strengthen `/restart` instructions.** Pedro's chat agent on rc.4-rc.2
|
|
60
|
+
again said "I need permission to restart" instead of issuing the slash
|
|
61
|
+
command — same anti-pattern that PR #163 / #173 / #174 tried to suppress.
|
|
62
|
+
Made the SKILL.md instruction more imperative and concrete: "Your IMMEDIATE
|
|
63
|
+
next message must be the literal slash command `/restart` — nothing else."
|
|
64
|
+
Added explicit "Do not propose alternatives" guidance for the unauthorized
|
|
65
|
+
fallback path. Mirrored in `docs/guides/openclaw-setup.md`.
|
|
66
|
+
|
|
7
67
|
## [3.3.3-rc.1] — 2026-04-30
|
|
8
68
|
|
|
9
69
|
Combined RC bundle:
|
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 totalreclaw_remember / totalreclaw_recall. Trigger on 'install TotalReclaw', 'set up TotalReclaw', 'restore my recovery phrase', or any remember / recall request."
|
|
4
|
-
version: 3.3.
|
|
4
|
+
version: 3.3.6-rc.1
|
|
5
5
|
author: TotalReclaw Team
|
|
6
6
|
license: MIT
|
|
7
7
|
homepage: https://totalreclaw.xyz
|
|
@@ -26,11 +26,35 @@ metadata:
|
|
|
26
26
|
|
|
27
27
|
> The canonical install flow lives at <https://github.com/p-diogo/totalreclaw/blob/main/docs/guides/openclaw-setup.md>. If a user pastes that URL in chat, fetch it and follow its agent-instructions section. This SKILL.md mirrors the same steps so you can act even if the URL is unreachable.
|
|
28
28
|
|
|
29
|
+
## Top-level rule (read this before anything else)
|
|
30
|
+
|
|
31
|
+
**Emit ONLY the user-visible lines listed below. Do not narrate tool calls. Do not describe what you're doing or about to do. Errors are the only allowed deviation, and only as a single tight line.** The expected user-facing transcript for a healthy install is **5–6 short lines TOTAL** (lines 1, 2, 5, 6 always; lines 3 and 4 only if the corresponding condition fires). Anything more is a SKILL violation. Telegram and similar transports edit the bot's messages live as your tool calls progress — every interim "Let me check…" / "Plugin loaded. Let me verify…" line shows up to the user as awkward edit churn, even if you "delete" it. The fix is to never emit it in the first place.
|
|
32
|
+
|
|
33
|
+
## User-visible line set (THIS IS ALL YOU SAY)
|
|
34
|
+
|
|
35
|
+
Speak only these lines, in order. Substitute the bracketed placeholders with the real values. No prefaces. No suffixes. No narration.
|
|
36
|
+
|
|
37
|
+
1. (start of install)
|
|
38
|
+
> Installing TotalReclaw…
|
|
39
|
+
2. (after install + auto-reload + `totalreclaw_pair` is bound)
|
|
40
|
+
> ✓ Installed (totalreclaw <version>)
|
|
41
|
+
3. (optional — only if auto-reload didn't fire and you need to issue `/restart`)
|
|
42
|
+
> Restarting OpenClaw to load the plugin…
|
|
43
|
+
4. (optional — only if you successfully disabled the built-in memory tool to prevent dual-write)
|
|
44
|
+
> Disabled built-in memory tool.
|
|
45
|
+
5. (account-setup URL + PIN, immediately after `totalreclaw_pair` returns)
|
|
46
|
+
> Open <url> in your browser. Enter PIN <pin>. Generate or paste a 12-word recovery phrase. Reply `done` once it's sealed.
|
|
47
|
+
6. (done + free-tier confirmation)
|
|
48
|
+
> ✓ You're set up on the TotalReclaw free tier — 500 memories/month, unlimited reads. https://totalreclaw.xyz/pricing. Ask me to remember anything.
|
|
49
|
+
|
|
50
|
+
If existing credentials are detected (step "Check for existing credentials" below), emit ONLY this line and stop:
|
|
51
|
+
> ✓ TotalReclaw is already set up.
|
|
52
|
+
|
|
29
53
|
## Setup flow
|
|
30
54
|
|
|
31
55
|
If `totalreclaw_*` tools are already bound to your toolset, SKIP install and jump to step 4. Otherwise run all steps in order.
|
|
32
56
|
|
|
33
|
-
1. **Install plugin first, skill second.** Run via your shell tool, in this exact order:
|
|
57
|
+
1. **Install plugin first, skill second (silent — emit user-visible line 1 once at the start, then no prose until line 2).** Run via your shell tool, in this exact order:
|
|
34
58
|
```
|
|
35
59
|
openclaw plugins install @totalreclaw/totalreclaw
|
|
36
60
|
openclaw skills install totalreclaw
|
|
@@ -39,26 +63,39 @@ If `totalreclaw_*` tools are already bound to your toolset, SKIP install and jum
|
|
|
39
63
|
|
|
40
64
|
If either shell call fails with `command not found` / ENOENT / "not authorized" (managed-service or shell-restricted environment), tell the user verbatim *"Your environment doesn't expose the OpenClaw CLI to me. Please install `totalreclaw` from your service's plugins / skills UI, then reply `done`."* Wait for `done` and skip to step 3.
|
|
41
65
|
|
|
42
|
-
2. **Wait for auto-reload — then issue `/restart` autonomously if needed.** OpenClaw's default config (`gateway.reload.mode = "hybrid"`) auto-restarts the gateway via a file-watcher within 1-3 seconds. Wait ~5s, then run `openclaw plugins list | grep totalreclaw` and confirm `totalreclaw_pair` is in your toolset.
|
|
66
|
+
2. **Wait for auto-reload — then issue `/restart` autonomously if needed (silent — emit user-visible line 2 on success, line 3 only if you had to restart).** OpenClaw's default config (`gateway.reload.mode = "hybrid"`) auto-restarts the gateway via a file-watcher within 1-3 seconds. Wait ~5s, then run `openclaw plugins list | grep totalreclaw` and confirm `totalreclaw_pair` is in your toolset. When bound, emit user-visible line 2 and proceed.
|
|
67
|
+
|
|
68
|
+
**If `totalreclaw_pair` is NOT visible after 10s — restart imperative (read carefully):**
|
|
69
|
+
|
|
70
|
+
> Your IMMEDIATE next message must be the literal slash command `/restart` — nothing else. Do not narrate. Do not ask permission. Do not describe what `/restart` does. Do not propose alternatives. Just send `/restart`. You may emit user-visible line 3 (`Restarting OpenClaw to load the plugin…`) ONCE in the same turn, then issue `/restart`. Nothing else.
|
|
71
|
+
|
|
72
|
+
`/restart` is in-process — it drains active runs cleanly; your shell is NOT shelling out to `docker restart` or `openclaw gateway restart` (those would suicide the host). After `/restart`, wait ~3s and re-run `openclaw plugins list`.
|
|
43
73
|
|
|
44
|
-
**If
|
|
74
|
+
**If `/restart` returns "You are not authorized to use this command":** surface this verbatim and stop. Do NOT loop `/restart` calls. Do NOT propose alternatives.
|
|
45
75
|
|
|
46
|
-
|
|
76
|
+
> Your Telegram channel needs `allowFrom` configured. Run on your host: `jq '.channels.<channel>.allowFrom = ["<your-id>"]' ~/.openclaw/openclaw.json | sponge ~/.openclaw/openclaw.json && docker restart <your-container-name>`. Substitute `<channel>` (e.g. `telegram`, `slack`), `<your-id>` (Telegram: `@username` or numeric `chat_id`; Slack: workspace member ID), and `<your-container-name>` (`docker ps` shows it). For non-Docker installs substitute `openclaw gateway restart` for the `docker restart` portion. On a managed service, ask the service's support to enable slash commands. Reply `done` after.
|
|
47
77
|
|
|
48
|
-
|
|
78
|
+
Then wait for `done`. Do NOT retry the install. Do NOT keep restarting. Do NOT issue `/new` — it wipes the chat context, the agent forgets it was mid-install, and the user's next message is treated as a fresh install request which retries from scratch and re-trips the scanner block (Pedro QA, 3.3.5-rc.1).
|
|
49
79
|
|
|
50
|
-
|
|
80
|
+
**Forbidden vocabulary** (these are anti-patterns — they show up to the user even if your transport edits them later, and they violate the silence rule):
|
|
81
|
+
- "Let me check that…"
|
|
82
|
+
- "Plugin loaded. Let me verify…"
|
|
83
|
+
- "I'll now…"
|
|
84
|
+
- "Quick fix…"
|
|
85
|
+
- "However, I don't see…"
|
|
86
|
+
- "I need to use…"
|
|
87
|
+
- "Should I /restart" / "Do you have a public URL" / "Want me to restart" / "Let me check if the tool is bound" / "I need permission to restart"
|
|
88
|
+
- "Now installing…" / "Got it" / "In parallel…" / "Step 1a/1b/1c"
|
|
51
89
|
|
|
52
|
-
|
|
90
|
+
Substitute all of these with silence — the next user-visible line in the set, or nothing.
|
|
53
91
|
|
|
54
92
|
3. **Verify `totalreclaw_pair` is bound.** If still missing after `/restart` (or after the user fixed allowFrom and said `done`), tell them the restart didn't take effect and ask them to retry. Do not loop the install.
|
|
55
93
|
|
|
56
|
-
4. **Check for existing credentials.** Run `test -s ~/.totalreclaw/credentials.json`. If it exists and is non-empty,
|
|
94
|
+
4. **Check for existing credentials (silent unless found).** Run `test -s ~/.totalreclaw/credentials.json`. If it exists and is non-empty, emit *"✓ TotalReclaw is already set up."* and stop.
|
|
57
95
|
|
|
58
|
-
5. **Set up the user's TotalReclaw account
|
|
59
|
-
> *Open <url> in your browser. Generate a new 12-word recovery phrase there or paste an existing one — the phrase stays in your browser, the relay only sees ciphertext. Confirm PIN <pin>. Reply `done` once the page says it's sealed.*
|
|
96
|
+
5. **Set up the user's TotalReclaw account (emit user-visible line 5 once, after `totalreclaw_pair` returns).** Call `totalreclaw_pair` silently (the account-setup tool — name kept for backward compatibility). It returns `{url, pin, qr_ascii, qr_png_b64, qr_unicode, expires_at_ms}` (see "Rendering the QR" below). Then emit user-visible line 5 with `<url>` and `<pin>` substituted. Do not pre-narrate ("I'll walk you through…", "Setting up your account now…") — line 5 itself is the only thing the user needs to see. The URL + PIN itself is the real consent moment: surfacing them verbatim is what gives the user the chance to opt out by simply not opening the page.
|
|
60
97
|
|
|
61
|
-
6. **Verify and confirm.** After user says `done`, re-run `test -s ~/.totalreclaw/credentials.json`. If missing, the PIN expired — call `totalreclaw_pair` again and resend. If present,
|
|
98
|
+
6. **Verify and confirm (silent until line 6).** After the user says `done`, re-run `test -s ~/.totalreclaw/credentials.json`. If missing, the PIN expired — call `totalreclaw_pair` again silently and resend line 5 once. If present, emit user-visible line 6 and stop.
|
|
62
99
|
|
|
63
100
|
## Rendering the QR on your transport (rc.5+)
|
|
64
101
|
|
package/dist/fs-helpers.js
CHANGED
|
@@ -344,19 +344,23 @@ export function cleanupInstallStagingDirs(pluginDir, _now = Date.now) {
|
|
|
344
344
|
// Partial-install detection (rc.22 finding #5)
|
|
345
345
|
// ---------------------------------------------------------------------------
|
|
346
346
|
/**
|
|
347
|
-
* Marker filename
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
*
|
|
347
|
+
* Marker filename indicating a prior install was interrupted before the
|
|
348
|
+
* plugin successfully loaded — a confirmed-broken half-state that the next
|
|
349
|
+
* `openclaw plugins install` retry can detect and clean.
|
|
350
|
+
*
|
|
351
|
+
* 3.3.6-rc.1 (2026-05-01): the `preinstall` npm script that wrote this
|
|
352
|
+
* marker was removed. OpenClaw's `openclaw plugins install` invokes
|
|
353
|
+
* `npm install --ignore-scripts`, so the script never fired in the
|
|
354
|
+
* canonical install path anyway, and `node -e` shell-exec patterns are a
|
|
355
|
+
* latent scanner-spec risk. The runtime canonical signal for partial
|
|
356
|
+
* detection is now `dist/index.js` missing (Rule 5 in `detectPartialInstall`)
|
|
357
|
+
* — the marker (Rule 4) is a redundant second-line check that still works
|
|
358
|
+
* for legacy installs that may have a stale marker on disk.
|
|
359
|
+
*
|
|
360
|
+
* Helpers (`writePartialInstallMarker` / `clearPartialInstallMarker`) and
|
|
361
|
+
* the constant remain exported for backward compat and for any future
|
|
362
|
+
* mechanism that wants to reinstate marker writes (e.g. a runtime
|
|
363
|
+
* register-time write that is `--ignore-scripts`-safe).
|
|
360
364
|
*/
|
|
361
365
|
export const PARTIAL_INSTALL_MARKER = '.tr-partial-install';
|
|
362
366
|
/** Package name we own — used to confirm a directory is OUR plugin, not a stray. */
|
|
@@ -570,9 +574,12 @@ export function writePluginError(pluginDir, error) {
|
|
|
570
574
|
/**
|
|
571
575
|
* Drop the `.tr-partial-install` marker into `pluginRootDir`. Idempotent
|
|
572
576
|
* (overwrites any existing marker) and best-effort — returns `true` on
|
|
573
|
-
* success, `false` if the dir doesn't exist or write fails.
|
|
574
|
-
*
|
|
575
|
-
* preinstall
|
|
577
|
+
* success, `false` if the dir doesn't exist or write fails.
|
|
578
|
+
*
|
|
579
|
+
* 3.3.6-rc.1 (2026-05-01): the `preinstall` npm script that previously
|
|
580
|
+
* called this (via `node -e`) was removed (see `PARTIAL_INSTALL_MARKER`
|
|
581
|
+
* doc-comment). The helper remains exported for backward compat and for
|
|
582
|
+
* any future runtime register-time marker mechanism.
|
|
576
583
|
*/
|
|
577
584
|
export function writePartialInstallMarker(pluginRootDir) {
|
|
578
585
|
try {
|
|
@@ -586,10 +593,11 @@ export function writePartialInstallMarker(pluginRootDir) {
|
|
|
586
593
|
}
|
|
587
594
|
}
|
|
588
595
|
/**
|
|
589
|
-
* Remove the partial-install marker. Called
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
596
|
+
* Remove the partial-install marker. Called at register-time once we've
|
|
597
|
+
* confirmed the load succeeded — clears any stale marker left by a legacy
|
|
598
|
+
* install, since 3.3.6-rc.1 removed the `preinstall` script that used to
|
|
599
|
+
* write fresh markers. Returns `true` if a marker was removed, `false` if
|
|
600
|
+
* there was nothing to remove.
|
|
593
601
|
*/
|
|
594
602
|
export function clearPartialInstallMarker(pluginRootDir) {
|
|
595
603
|
try {
|
package/dist/index.js
CHANGED
|
@@ -2476,13 +2476,17 @@ const plugin = {
|
|
|
2476
2476
|
});
|
|
2477
2477
|
}
|
|
2478
2478
|
// 3.3.1-rc.22 (rc.21 finding #5): self-heal partial-install marker.
|
|
2479
|
-
//
|
|
2480
|
-
//
|
|
2481
|
-
//
|
|
2482
|
-
//
|
|
2483
|
-
//
|
|
2484
|
-
//
|
|
2485
|
-
//
|
|
2479
|
+
// Clearing the marker has been the runtime's job since 3.3.3-rc.1
|
|
2480
|
+
// dropped postinstall.mjs (OpenClaw scanner blocked the install on
|
|
2481
|
+
// the subprocess-spawn import — see 3.3.3-rc.1 PR). 3.3.6-rc.1
|
|
2482
|
+
// additionally dropped the `preinstall` npm script that wrote the
|
|
2483
|
+
// marker (npm install --ignore-scripts meant it never fired in the
|
|
2484
|
+
// canonical install path anyway, and `node -e` shell-exec is a
|
|
2485
|
+
// latent scanner-spec risk). The clear call here remains valid for
|
|
2486
|
+
// legacy installs that may have a stale marker on disk. If we have
|
|
2487
|
+
// gotten this far the loader did register us — meaning the install
|
|
2488
|
+
// succeeded enough to be useful — so any lingering marker is stale.
|
|
2489
|
+
// Clear it so the next retry's detector does not see a false positive.
|
|
2486
2490
|
//
|
|
2487
2491
|
// 3.3.1-rc.22 (rc.21 finding #6) — gateway/reload upstream caveat:
|
|
2488
2492
|
// OpenClaw's config-watcher fires `gateway/reload` when
|
package/fs-helpers.ts
CHANGED
|
@@ -393,19 +393,23 @@ export function cleanupInstallStagingDirs(
|
|
|
393
393
|
// ---------------------------------------------------------------------------
|
|
394
394
|
|
|
395
395
|
/**
|
|
396
|
-
* Marker filename
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
* install` retry can detect and clean.
|
|
396
|
+
* Marker filename indicating a prior install was interrupted before the
|
|
397
|
+
* plugin successfully loaded — a confirmed-broken half-state that the next
|
|
398
|
+
* `openclaw plugins install` retry can detect and clean.
|
|
400
399
|
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
400
|
+
* 3.3.6-rc.1 (2026-05-01): the `preinstall` npm script that wrote this
|
|
401
|
+
* marker was removed. OpenClaw's `openclaw plugins install` invokes
|
|
402
|
+
* `npm install --ignore-scripts`, so the script never fired in the
|
|
403
|
+
* canonical install path anyway, and `node -e` shell-exec patterns are a
|
|
404
|
+
* latent scanner-spec risk. The runtime canonical signal for partial
|
|
405
|
+
* detection is now `dist/index.js` missing (Rule 5 in `detectPartialInstall`)
|
|
406
|
+
* — the marker (Rule 4) is a redundant second-line check that still works
|
|
407
|
+
* for legacy installs that may have a stale marker on disk.
|
|
406
408
|
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
+
* Helpers (`writePartialInstallMarker` / `clearPartialInstallMarker`) and
|
|
410
|
+
* the constant remain exported for backward compat and for any future
|
|
411
|
+
* mechanism that wants to reinstate marker writes (e.g. a runtime
|
|
412
|
+
* register-time write that is `--ignore-scripts`-safe).
|
|
409
413
|
*/
|
|
410
414
|
export const PARTIAL_INSTALL_MARKER = '.tr-partial-install';
|
|
411
415
|
|
|
@@ -666,9 +670,12 @@ export function writePluginError(
|
|
|
666
670
|
/**
|
|
667
671
|
* Drop the `.tr-partial-install` marker into `pluginRootDir`. Idempotent
|
|
668
672
|
* (overwrites any existing marker) and best-effort — returns `true` on
|
|
669
|
-
* success, `false` if the dir doesn't exist or write fails.
|
|
670
|
-
*
|
|
671
|
-
* preinstall
|
|
673
|
+
* success, `false` if the dir doesn't exist or write fails.
|
|
674
|
+
*
|
|
675
|
+
* 3.3.6-rc.1 (2026-05-01): the `preinstall` npm script that previously
|
|
676
|
+
* called this (via `node -e`) was removed (see `PARTIAL_INSTALL_MARKER`
|
|
677
|
+
* doc-comment). The helper remains exported for backward compat and for
|
|
678
|
+
* any future runtime register-time marker mechanism.
|
|
672
679
|
*/
|
|
673
680
|
export function writePartialInstallMarker(pluginRootDir: string): boolean {
|
|
674
681
|
try {
|
|
@@ -681,10 +688,11 @@ export function writePartialInstallMarker(pluginRootDir: string): boolean {
|
|
|
681
688
|
}
|
|
682
689
|
|
|
683
690
|
/**
|
|
684
|
-
* Remove the partial-install marker. Called
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
691
|
+
* Remove the partial-install marker. Called at register-time once we've
|
|
692
|
+
* confirmed the load succeeded — clears any stale marker left by a legacy
|
|
693
|
+
* install, since 3.3.6-rc.1 removed the `preinstall` script that used to
|
|
694
|
+
* write fresh markers. Returns `true` if a marker was removed, `false` if
|
|
695
|
+
* there was nothing to remove.
|
|
688
696
|
*/
|
|
689
697
|
export function clearPartialInstallMarker(pluginRootDir: string): boolean {
|
|
690
698
|
try {
|
package/index.ts
CHANGED
|
@@ -3043,13 +3043,17 @@ const plugin = {
|
|
|
3043
3043
|
}
|
|
3044
3044
|
|
|
3045
3045
|
// 3.3.1-rc.22 (rc.21 finding #5): self-heal partial-install marker.
|
|
3046
|
-
//
|
|
3047
|
-
//
|
|
3048
|
-
//
|
|
3049
|
-
//
|
|
3050
|
-
//
|
|
3051
|
-
//
|
|
3052
|
-
//
|
|
3046
|
+
// Clearing the marker has been the runtime's job since 3.3.3-rc.1
|
|
3047
|
+
// dropped postinstall.mjs (OpenClaw scanner blocked the install on
|
|
3048
|
+
// the subprocess-spawn import — see 3.3.3-rc.1 PR). 3.3.6-rc.1
|
|
3049
|
+
// additionally dropped the `preinstall` npm script that wrote the
|
|
3050
|
+
// marker (npm install --ignore-scripts meant it never fired in the
|
|
3051
|
+
// canonical install path anyway, and `node -e` shell-exec is a
|
|
3052
|
+
// latent scanner-spec risk). The clear call here remains valid for
|
|
3053
|
+
// legacy installs that may have a stale marker on disk. If we have
|
|
3054
|
+
// gotten this far the loader did register us — meaning the install
|
|
3055
|
+
// succeeded enough to be useful — so any lingering marker is stale.
|
|
3056
|
+
// Clear it so the next retry's detector does not see a false positive.
|
|
3053
3057
|
//
|
|
3054
3058
|
// 3.3.1-rc.22 (rc.21 finding #6) — gateway/reload upstream caveat:
|
|
3055
3059
|
// OpenClaw's config-watcher fires `gateway/reload` when
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totalreclaw/totalreclaw",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.6-rc.1",
|
|
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": [
|
|
@@ -70,7 +70,6 @@
|
|
|
70
70
|
"check-version-drift": "node ../scripts/check-version-drift.mjs",
|
|
71
71
|
"check-url-binding": "node ../scripts/check-url-binding.mjs",
|
|
72
72
|
"sync-version": "node ../scripts/sync-version.mjs",
|
|
73
|
-
"preinstall": "node -e \"try{require('fs').writeFileSync('.tr-partial-install','');}catch{}\"",
|
|
74
73
|
"prepack": "npm run build",
|
|
75
74
|
"prepublishOnly": "node ../scripts/check-scanner.mjs && node ../scripts/check-version-drift.mjs && node ../scripts/check-url-binding.mjs --release-type=${TOTALRECLAW_RELEASE_TYPE:-rc}"
|
|
76
75
|
},
|
package/skill.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "totalreclaw",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.6-rc.1",
|
|
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",
|
|
@@ -15,6 +15,131 @@
|
|
|
15
15
|
"agent-memory",
|
|
16
16
|
"persistent-context"
|
|
17
17
|
],
|
|
18
|
+
"tools": [
|
|
19
|
+
{
|
|
20
|
+
"name": "totalreclaw_pair",
|
|
21
|
+
"description": "Set up the user's TotalReclaw account (encrypted, browser-side recovery-phrase generation or import). Returns an account-setup URL, a 6-digit PIN, and an ASCII QR code that the agent relays to the user. The recovery phrase is generated/entered in the BROWSER and uploaded end-to-end encrypted to this gateway — it NEVER touches the LLM provider or the chat transcript. This is the canonical agent-facilitated account-setup surface. Tool name kept for backward compatibility — function-wise this is the account-setup tool.",
|
|
22
|
+
"handler": "./dist/index.js",
|
|
23
|
+
"parameters": {
|
|
24
|
+
"mode": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"required": false,
|
|
27
|
+
"enum": ["generate", "import"],
|
|
28
|
+
"default": "generate",
|
|
29
|
+
"description": "\"generate\" = browser will create a NEW recovery phrase. \"import\" = browser will accept an EXISTING phrase pasted by the user in their browser (never through chat)."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "totalreclaw_remember",
|
|
35
|
+
"description": "Store a new fact or preference in long-term memory",
|
|
36
|
+
"handler": "./dist/index.js",
|
|
37
|
+
"parameters": {
|
|
38
|
+
"text": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"required": true,
|
|
41
|
+
"description": "The fact or information to remember"
|
|
42
|
+
},
|
|
43
|
+
"type": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"required": false,
|
|
46
|
+
"enum": ["fact", "preference", "decision", "episodic", "goal"],
|
|
47
|
+
"default": "fact",
|
|
48
|
+
"description": "Type of memory"
|
|
49
|
+
},
|
|
50
|
+
"importance": {
|
|
51
|
+
"type": "integer",
|
|
52
|
+
"required": false,
|
|
53
|
+
"min": 1,
|
|
54
|
+
"max": 10,
|
|
55
|
+
"description": "Importance score 1-10. Default: auto-detected by LLM"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "totalreclaw_recall",
|
|
61
|
+
"description": "Search and retrieve relevant memories from long-term storage",
|
|
62
|
+
"handler": "./dist/index.js",
|
|
63
|
+
"parameters": {
|
|
64
|
+
"query": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"required": true,
|
|
67
|
+
"description": "Natural language query to search memories"
|
|
68
|
+
},
|
|
69
|
+
"k": {
|
|
70
|
+
"type": "integer",
|
|
71
|
+
"required": false,
|
|
72
|
+
"default": 8,
|
|
73
|
+
"max": 20,
|
|
74
|
+
"description": "Number of results to return"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "totalreclaw_forget",
|
|
80
|
+
"description": "Delete a specific fact from memory",
|
|
81
|
+
"handler": "./dist/index.js",
|
|
82
|
+
"parameters": {
|
|
83
|
+
"factId": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"required": true,
|
|
86
|
+
"description": "UUID of the fact to delete"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "totalreclaw_export",
|
|
92
|
+
"description": "Export all stored memories in plaintext format",
|
|
93
|
+
"handler": "./dist/index.js",
|
|
94
|
+
"parameters": {
|
|
95
|
+
"format": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"required": false,
|
|
98
|
+
"enum": ["json", "markdown"],
|
|
99
|
+
"default": "json",
|
|
100
|
+
"description": "Export format"
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "totalreclaw_status",
|
|
106
|
+
"description": "Check billing and subscription status, including quota usage and upgrade options",
|
|
107
|
+
"handler": "./dist/index.js",
|
|
108
|
+
"parameters": {}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"name": "totalreclaw_upgrade",
|
|
112
|
+
"description": "Get a checkout URL to upgrade to TotalReclaw Pro (unlimited memories on Gnosis mainnet)",
|
|
113
|
+
"handler": "./dist/index.js",
|
|
114
|
+
"parameters": {}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "totalreclaw_import_from",
|
|
118
|
+
"description": "Import memories from other AI memory tools (Mem0, MCP Memory Server) into TotalReclaw",
|
|
119
|
+
"handler": "./dist/index.js",
|
|
120
|
+
"parameters": {
|
|
121
|
+
"source": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"required": true,
|
|
124
|
+
"enum": ["mem0", "mcp-memory"],
|
|
125
|
+
"description": "Source system to import from"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "totalreclaw_consolidate",
|
|
131
|
+
"description": "Scan all stored memories and merge near-duplicates, keeping the most important/recent version",
|
|
132
|
+
"handler": "./dist/index.js",
|
|
133
|
+
"parameters": {
|
|
134
|
+
"dry_run": {
|
|
135
|
+
"type": "boolean",
|
|
136
|
+
"required": false,
|
|
137
|
+
"default": false,
|
|
138
|
+
"description": "Preview consolidation without deleting"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
],
|
|
18
143
|
"openclaw": {
|
|
19
144
|
"minVersion": "0.1.0",
|
|
20
145
|
"maxVersion": "1.0.0",
|