@totalreclaw/totalreclaw 3.3.1 → 3.3.2-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 +25 -0
- package/SKILL.md +8 -8
- package/dist/index.js +17 -12
- package/index.ts +17 -12
- package/package.json +4 -3
- package/preinstall.mjs +65 -0
- package/skill.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,31 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
### 3.3.2-rc.1 — preinstall orphan-stage cleanup (umbrella #182 F6 / issue #190)
|
|
10
|
+
|
|
11
|
+
The rc.21 fix (#126) added `cleanupInstallStagingDirs` called at plugin
|
|
12
|
+
register time. That helper is too late for the re-install scenario: with
|
|
13
|
+
an orphan `.openclaw-install-stage-*` sibling already present in
|
|
14
|
+
`~/.openclaw/extensions/`, OpenClaw's config validator fires
|
|
15
|
+
`duplicate plugin id detected; global plugin will be overridden by global
|
|
16
|
+
plugin` BEFORE plugin register runs, so registration is blocked entirely
|
|
17
|
+
and the helper never gets a chance to clean up. The user observes the
|
|
18
|
+
warning and a plugin that silently fails to load.
|
|
19
|
+
|
|
20
|
+
Fix: a new `preinstall.mjs` script runs at npm preinstall time (before
|
|
21
|
+
the new install is renamed into place). It removes orphan
|
|
22
|
+
`.openclaw-install-stage-*` siblings from `~/.openclaw/extensions/`
|
|
23
|
+
(and `$OPENCLAW_STATE_DIR/extensions/` when set), skipping the script's
|
|
24
|
+
own cwd basename so older OpenClaw versions that stage inside extensions/
|
|
25
|
+
don't delete their own in-flight install. Also keeps the existing
|
|
26
|
+
`.tr-partial-install` marker drop. Best-effort throughout — never throws
|
|
27
|
+
or exits non-zero.
|
|
28
|
+
|
|
29
|
+
Regression: `test_issue_190_preinstall_orphan_cleanup.test.ts`
|
|
30
|
+
(19 assertions) covers newer-OpenClaw flow (cwd in /tmp), older-OpenClaw
|
|
31
|
+
flow (cwd inside extensions/), `OPENCLAW_STATE_DIR` env override,
|
|
32
|
+
no-extensions-dir fallback, and unrelated-sibling preservation.
|
|
33
|
+
|
|
9
34
|
### Install / runtime hygiene (issues #126, #128)
|
|
10
35
|
|
|
11
36
|
Two narrow fixes from the rc.20 user-QA findings — both around install /
|
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.2-rc.1
|
|
5
5
|
author: TotalReclaw Team
|
|
6
6
|
license: MIT
|
|
7
7
|
homepage: https://totalreclaw.xyz
|
|
@@ -43,10 +43,10 @@ If `totalreclaw_*` tools are already bound to your toolset, SKIP install and jum
|
|
|
43
43
|
|
|
44
44
|
4. **Check for existing credentials.** Run `test -s ~/.totalreclaw/credentials.json`. If it exists and is non-empty, confirm *"TotalReclaw is already set up."* and stop.
|
|
45
45
|
|
|
46
|
-
5. **
|
|
46
|
+
5. **Set up the user's TotalReclaw account.** Tell the user: *"I'll walk you through setting up your TotalReclaw account."* Then call `totalreclaw_pair` (the account-setup tool — name kept for backward compatibility). Returns `{url, pin, qr_ascii, qr_png_b64, qr_unicode, expires_at_ms}` (see "Rendering the QR" below). Relay verbatim:
|
|
47
47
|
> *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.*
|
|
48
48
|
|
|
49
|
-
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, confirm *"TotalReclaw is set up. Ask me to remember or recall anything."*
|
|
49
|
+
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, confirm *"Your TotalReclaw account is set up. Ask me to remember or recall anything."*
|
|
50
50
|
|
|
51
51
|
## Rendering the QR on your transport (rc.5+)
|
|
52
52
|
|
|
@@ -54,13 +54,13 @@ When you receive the `totalreclaw_pair` payload, render the QR based on your cha
|
|
|
54
54
|
|
|
55
55
|
- **Transport supports image attachments** (Telegram, Slack, web chat, any transport with file/image upload): decode `qr_png_b64` from base64 to bytes, save to a tempfile with a `.png` suffix, and attach the tempfile as an image. Also show the URL + PIN as text so users who prefer clicking can still do so.
|
|
56
56
|
- **Terminal-only transport** (OpenClaw native CLI chat, bare SSH shell): emit `qr_unicode` inline in your reply. It renders as block characters in most terminal fonts; the user scans from their phone.
|
|
57
|
-
- **Web chat with inline-image support**: embed as `<img src="data:image/png;base64,<qr_png_b64>" alt="
|
|
57
|
+
- **Web chat with inline-image support**: embed as `<img src="data:image/png;base64,<qr_png_b64>" alt="TotalReclaw account-setup QR">` if the chat client renders HTML; otherwise fall back to attachment.
|
|
58
58
|
|
|
59
|
-
The QR encodes ONLY the
|
|
59
|
+
The QR encodes ONLY the account-setup URL. The 6-digit PIN is a separate out-of-band confirmation — deliberately NOT baked into the QR (dual-channel design: scan + type). Never log, print, or re-emit the PIN outside the user-facing reply. The PIN must NOT end up in any other tool call, log file, or memory store.
|
|
60
60
|
|
|
61
61
|
## Phrase safety (HARD — never break)
|
|
62
62
|
|
|
63
|
-
NEVER echo / generate / ask the user to paste a recovery phrase in chat. NEVER invoke `openclaw totalreclaw onboard` (bare interactive form), `totalreclaw setup`, or any phrase-touching CLI via your shell tool (stdout enters LLM context). The ONLY agent-facilitated setup paths are (in order of preference): (1) `totalreclaw_pair` tool; (2) if the tool is missing from your tool list — a known gap for some container-based agents, issue #87 — shell out to EITHER `openclaw totalreclaw pair generate --url-pin-only` (single-line JSON `{v,url,pin,expires_at_ms}`) OR `openclaw totalreclaw onboard --pair-only` (single-line JSON `{v,pair_url,pin,expires_at_ms}`, issue #95 — same
|
|
63
|
+
NEVER echo / generate / ask the user to paste a recovery phrase in chat. NEVER invoke `openclaw totalreclaw onboard` (bare interactive form), `totalreclaw setup`, or any phrase-touching CLI via your shell tool (stdout enters LLM context). The ONLY agent-facilitated account-setup paths are (in order of preference): (1) the `totalreclaw_pair` account-setup tool; (2) if the tool is missing from your tool list — a known gap for some container-based agents, issue #87 — shell out to EITHER `openclaw totalreclaw pair generate --url-pin-only` (single-line JSON `{v,url,pin,expires_at_ms}`) OR `openclaw totalreclaw onboard --pair-only` (single-line JSON `{v,pair_url,pin,expires_at_ms}`, issue #95 — same account-setup flow, `pair_url` key naming). Both have zero phrase material on stdout (account-setup crypto is x25519-only, not BIP-39). If the user pastes a phrase anyway: tell them it is compromised, call `totalreclaw_pair` with `mode=generate` for a fresh wallet.
|
|
64
64
|
|
|
65
65
|
## Usage (post-setup)
|
|
66
66
|
|
|
@@ -74,10 +74,10 @@ NEVER echo / generate / ask the user to paste a recovery phrase in chat. NEVER i
|
|
|
74
74
|
|
|
75
75
|
- `totalreclaw_*` tools not visible → plugin not installed or auto-reload didn't fire. Verify via `openclaw plugins list | grep totalreclaw` (or, on a managed service that doesn't expose the CLI, ask the user to confirm via their service's plugins UI). If `totalreclaw` is listed but tools are still absent, the gateway probably hasn't completed its auto-restart yet (give it 5-10s) OR `gateway.reload.mode = off` is set — instruct manual restart as fallback: `openclaw gateway restart` (native), `docker restart <your-container-name>` (Docker self-host), or the managed service's restart control. If the plugin is listed and the gateway has been restarted but tools are still missing (container-agent gap, issue #87), shell out to `openclaw totalreclaw pair generate --url-pin-only` on the gateway host and hand the user the `url` + `pin` from the JSON payload — OR `openclaw totalreclaw onboard --pair-only` (same flow, returns `pair_url` instead of `url`, issue #95). If your shell doesn't reach the gateway host (managed service), tell the user to install/enable the plugin via their service's plugins UI and restart the gateway via the service's restart control. Do NOT suggest the bare `openclaw totalreclaw onboard` (leaks phrase on stdout — deprecated in rc.18, removed next RC).
|
|
76
76
|
- User says done but `credentials.json` missing → PIN expired or entered wrong phrase; call `totalreclaw_pair` again.
|
|
77
|
-
- `onboarding required` → credentials missing; redo from the
|
|
77
|
+
- `onboarding required` → credentials missing; redo from the account-setup step.
|
|
78
78
|
- `quota exceeded` → `totalreclaw_status`, then offer `totalreclaw_upgrade`.
|
|
79
79
|
- `No LLM available for auto-extraction` at startup → provider key unreachable; check `~/.openclaw/agents/<agent>/agent/auth-profiles.json` or plugin config `extraction.llm`.
|
|
80
80
|
|
|
81
81
|
## Tool surface
|
|
82
82
|
|
|
83
|
-
`totalreclaw_pair` (ONLY setup path) · `_remember` · `_recall` · `_forget` · `_pin` · `_unpin` · `_retype` · `_set_scope` · `_export` · `_status` · `_upgrade` · `_migrate` · `_import_from` · `_import_batch` · `_consolidate` · `_onboarding_start` (pointer to local-terminal wizard, for users explicitly rejecting the browser flow) · `_report_qa_bug` (RC only).
|
|
83
|
+
`totalreclaw_pair` (ONLY account-setup path) · `_remember` · `_recall` · `_forget` · `_pin` · `_unpin` · `_retype` · `_set_scope` · `_export` · `_status` · `_upgrade` · `_migrate` · `_import_from` · `_import_batch` · `_consolidate` · `_onboarding_start` (pointer to local-terminal wizard, for users explicitly rejecting the browser flow) · `_report_qa_bug` (RC only).
|
package/dist/index.js
CHANGED
|
@@ -4377,18 +4377,23 @@ const plugin = {
|
|
|
4377
4377
|
// ---------------------------------------------------------------
|
|
4378
4378
|
api.registerTool({
|
|
4379
4379
|
name: 'totalreclaw_pair',
|
|
4380
|
-
label: '
|
|
4381
|
-
description: '
|
|
4382
|
-
'
|
|
4383
|
-
'
|
|
4384
|
-
'
|
|
4385
|
-
'to
|
|
4386
|
-
'
|
|
4387
|
-
'
|
|
4388
|
-
'
|
|
4389
|
-
'
|
|
4390
|
-
'
|
|
4391
|
-
'
|
|
4380
|
+
label: 'Set up the user\'s TotalReclaw account (encrypted, browser-side)',
|
|
4381
|
+
description: 'Set up the user\'s TotalReclaw account (encrypted, browser-side recovery-phrase ' +
|
|
4382
|
+
'generation or import). Starts a brief remote session so the user can create or ' +
|
|
4383
|
+
'import a TotalReclaw recovery phrase from their phone or another browser. ' +
|
|
4384
|
+
'Returns an account-setup URL, a 6-digit PIN, and an ASCII QR code that the agent ' +
|
|
4385
|
+
'relays to the user. The recovery phrase itself is generated/entered in the ' +
|
|
4386
|
+
'BROWSER and uploaded end-to-end encrypted to this gateway — it NEVER touches ' +
|
|
4387
|
+
'the LLM provider or the chat transcript.\n\n' +
|
|
4388
|
+
'This is the CANONICAL agent-facilitated account-setup surface — use it whenever ' +
|
|
4389
|
+
'the user asks you to set up TotalReclaw, regardless of whether they have ' +
|
|
4390
|
+
'terminal access. Narrate it to the user as "setting up your TotalReclaw ' +
|
|
4391
|
+
'account". Browser-side crypto keeps the recovery phrase out of the LLM context ' +
|
|
4392
|
+
'entirely. If a user explicitly prefers local-terminal account setup with no ' +
|
|
4393
|
+
'browser, point them at `totalreclaw_onboarding_start` (a pointer to the CLI ' +
|
|
4394
|
+
'wizard they run on their own terminal, NOT through your shell tool).\n\n' +
|
|
4395
|
+
'Tool name `totalreclaw_pair` is kept for backward compatibility — function-wise ' +
|
|
4396
|
+
'this is the account-setup tool.',
|
|
4392
4397
|
parameters: {
|
|
4393
4398
|
type: 'object',
|
|
4394
4399
|
properties: {
|
package/index.ts
CHANGED
|
@@ -5162,19 +5162,24 @@ const plugin = {
|
|
|
5162
5162
|
api.registerTool(
|
|
5163
5163
|
{
|
|
5164
5164
|
name: 'totalreclaw_pair',
|
|
5165
|
-
label: '
|
|
5165
|
+
label: 'Set up the user\'s TotalReclaw account (encrypted, browser-side)',
|
|
5166
5166
|
description:
|
|
5167
|
-
'
|
|
5168
|
-
'
|
|
5169
|
-
'
|
|
5170
|
-
'
|
|
5171
|
-
'to
|
|
5172
|
-
'
|
|
5173
|
-
'
|
|
5174
|
-
'
|
|
5175
|
-
'
|
|
5176
|
-
'
|
|
5177
|
-
'
|
|
5167
|
+
'Set up the user\'s TotalReclaw account (encrypted, browser-side recovery-phrase ' +
|
|
5168
|
+
'generation or import). Starts a brief remote session so the user can create or ' +
|
|
5169
|
+
'import a TotalReclaw recovery phrase from their phone or another browser. ' +
|
|
5170
|
+
'Returns an account-setup URL, a 6-digit PIN, and an ASCII QR code that the agent ' +
|
|
5171
|
+
'relays to the user. The recovery phrase itself is generated/entered in the ' +
|
|
5172
|
+
'BROWSER and uploaded end-to-end encrypted to this gateway — it NEVER touches ' +
|
|
5173
|
+
'the LLM provider or the chat transcript.\n\n' +
|
|
5174
|
+
'This is the CANONICAL agent-facilitated account-setup surface — use it whenever ' +
|
|
5175
|
+
'the user asks you to set up TotalReclaw, regardless of whether they have ' +
|
|
5176
|
+
'terminal access. Narrate it to the user as "setting up your TotalReclaw ' +
|
|
5177
|
+
'account". Browser-side crypto keeps the recovery phrase out of the LLM context ' +
|
|
5178
|
+
'entirely. If a user explicitly prefers local-terminal account setup with no ' +
|
|
5179
|
+
'browser, point them at `totalreclaw_onboarding_start` (a pointer to the CLI ' +
|
|
5180
|
+
'wizard they run on their own terminal, NOT through your shell tool).\n\n' +
|
|
5181
|
+
'Tool name `totalreclaw_pair` is kept for backward compatibility — function-wise ' +
|
|
5182
|
+
'this is the account-setup tool.',
|
|
5178
5183
|
parameters: {
|
|
5179
5184
|
type: 'object',
|
|
5180
5185
|
properties: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totalreclaw/totalreclaw",
|
|
3
|
-
"version": "3.3.1",
|
|
3
|
+
"version": "3.3.2-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": [
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"!**/*.test.ts",
|
|
55
55
|
"!pocv2-e2e-test.ts",
|
|
56
56
|
"openclaw.plugin.json",
|
|
57
|
+
"preinstall.mjs",
|
|
57
58
|
"SKILL.md",
|
|
58
59
|
"README.md",
|
|
59
60
|
"CHANGELOG.md",
|
|
@@ -63,12 +64,12 @@
|
|
|
63
64
|
"scripts": {
|
|
64
65
|
"build": "rm -rf dist && tsc -p tsconfig.json --noCheck",
|
|
65
66
|
"verify-tarball": "node ../scripts/verify-tarball.mjs",
|
|
66
|
-
"test": "npx tsx manifest-shape.test.ts && npx tsx config-schema.test.ts && npx tsx config.test.ts && npx tsx relay-headers.test.ts && npx tsx scope-address-visible.test.ts && npx tsx llm-profile-reader.test.ts && npx tsx llm-client.test.ts && npx tsx llm-client-retry.test.ts && npx tsx gateway-url.test.ts && npx tsx retype-setscope.test.ts && npx tsx tool-gating.test.ts && npx tsx onboarding-noninteractive.test.ts && npx tsx pair-cli-json.test.ts && npx tsx pair-qr.test.ts && npx tsx pair-remote-client.test.ts && npx tsx qa-bug-report.test.ts && npx tsx nonce-serialization.test.ts && npx tsx phrase-safety-registry.test.ts && npx tsx test_issue_92_onnx_download_ux.test.ts && npx tsx onboard-pair-only.test.ts && npx tsx import-time-smoke.test.ts && npx tsx install-staging-cleanup.test.ts && npx tsx partial-install-detection.test.ts && npx tsx install-reload-idempotency.test.ts && npx tsx json-stdout-cleanliness.test.ts",
|
|
67
|
+
"test": "npx tsx manifest-shape.test.ts && npx tsx config-schema.test.ts && npx tsx config.test.ts && npx tsx relay-headers.test.ts && npx tsx scope-address-visible.test.ts && npx tsx llm-profile-reader.test.ts && npx tsx llm-client.test.ts && npx tsx llm-client-retry.test.ts && npx tsx gateway-url.test.ts && npx tsx retype-setscope.test.ts && npx tsx tool-gating.test.ts && npx tsx onboarding-noninteractive.test.ts && npx tsx pair-cli-json.test.ts && npx tsx pair-qr.test.ts && npx tsx pair-remote-client.test.ts && npx tsx qa-bug-report.test.ts && npx tsx nonce-serialization.test.ts && npx tsx phrase-safety-registry.test.ts && npx tsx test_issue_92_onnx_download_ux.test.ts && npx tsx onboard-pair-only.test.ts && npx tsx import-time-smoke.test.ts && npx tsx install-staging-cleanup.test.ts && npx tsx partial-install-detection.test.ts && npx tsx install-reload-idempotency.test.ts && npx tsx json-stdout-cleanliness.test.ts && npx tsx test_issue_190_preinstall_orphan_cleanup.test.ts",
|
|
67
68
|
"smoke:dist": "npx tsx dist-esm-smoke.test.ts",
|
|
68
69
|
"check-scanner": "node ../scripts/check-scanner.mjs",
|
|
69
70
|
"check-version-drift": "node ../scripts/check-version-drift.mjs",
|
|
70
71
|
"sync-version": "node ../scripts/sync-version.mjs",
|
|
71
|
-
"preinstall": "node
|
|
72
|
+
"preinstall": "node ./preinstall.mjs",
|
|
72
73
|
"postinstall": "node -e \"try{require('fs').unlinkSync('.tr-partial-install');}catch{}\"",
|
|
73
74
|
"prepack": "npm run build",
|
|
74
75
|
"prepublishOnly": "node ../scripts/check-scanner.mjs && node ../scripts/check-version-drift.mjs"
|
package/preinstall.mjs
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Runs at npm preinstall during `openclaw plugins install @totalreclaw/totalreclaw`.
|
|
3
|
+
//
|
|
4
|
+
// Two responsibilities:
|
|
5
|
+
// 1. Drop the `.tr-partial-install` marker. detectPartialInstall (rc.22)
|
|
6
|
+
// uses it to identify installs that didn't reach postinstall.
|
|
7
|
+
// 2. Remove orphan `.openclaw-install-stage-*` siblings from
|
|
8
|
+
// `~/.openclaw/extensions/` (and `$OPENCLAW_STATE_DIR/extensions/` when set).
|
|
9
|
+
// An interrupted prior install leaves a stage dir behind; on next gateway
|
|
10
|
+
// start, OpenClaw's config validator finds two manifests with the same
|
|
11
|
+
// plugin id, fires `duplicate plugin id detected; global plugin will be
|
|
12
|
+
// overridden by global plugin`, and refuses to register either copy.
|
|
13
|
+
// The register-time `cleanupInstallStagingDirs` helper from rc.21 (#126)
|
|
14
|
+
// cannot recover this: registration is blocked before our code runs.
|
|
15
|
+
//
|
|
16
|
+
// Best-effort throughout. Never throws or exits non-zero.
|
|
17
|
+
//
|
|
18
|
+
// Background: issue #190 (umbrella #182 finding F6).
|
|
19
|
+
|
|
20
|
+
import fs from 'node:fs';
|
|
21
|
+
import os from 'node:os';
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
|
|
24
|
+
const STAGE_PREFIX = '.openclaw-install-stage-';
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
fs.writeFileSync('.tr-partial-install', '');
|
|
28
|
+
} catch { /* swallow */ }
|
|
29
|
+
|
|
30
|
+
function cleanExtensionsDir(extensionsDir, selfName) {
|
|
31
|
+
const removed = [];
|
|
32
|
+
let entries;
|
|
33
|
+
try {
|
|
34
|
+
entries = fs.readdirSync(extensionsDir);
|
|
35
|
+
} catch { return removed; }
|
|
36
|
+
for (const name of entries) {
|
|
37
|
+
if (!name.startsWith(STAGE_PREFIX)) continue;
|
|
38
|
+
if (name === selfName) continue;
|
|
39
|
+
const target = path.join(extensionsDir, name);
|
|
40
|
+
try {
|
|
41
|
+
if (!fs.lstatSync(target).isDirectory()) continue;
|
|
42
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
43
|
+
removed.push(target);
|
|
44
|
+
} catch { /* skip racy / unreadable */ }
|
|
45
|
+
}
|
|
46
|
+
return removed;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const cwd = process.cwd();
|
|
50
|
+
const cwdName = path.basename(cwd);
|
|
51
|
+
|
|
52
|
+
const candidates = new Set();
|
|
53
|
+
if (cwdName.startsWith(STAGE_PREFIX)) {
|
|
54
|
+
candidates.add(path.dirname(cwd));
|
|
55
|
+
}
|
|
56
|
+
candidates.add(path.join(os.homedir(), '.openclaw', 'extensions'));
|
|
57
|
+
if (process.env.OPENCLAW_STATE_DIR) {
|
|
58
|
+
candidates.add(path.join(process.env.OPENCLAW_STATE_DIR, 'extensions'));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (const dir of candidates) {
|
|
62
|
+
for (const removedPath of cleanExtensionsDir(dir, cwdName)) {
|
|
63
|
+
process.stdout.write(`[totalreclaw preinstall] removed orphan install-stage dir: ${removedPath}\n`);
|
|
64
|
+
}
|
|
65
|
+
}
|
package/skill.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "totalreclaw",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.2-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",
|