@totalreclaw/totalreclaw 3.3.11-rc.5 → 3.3.12-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 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.11-rc.6] — 2026-05-07
8
+
9
+ UX fix: mandatory ack-before-first-tool-call on install. Pedro's rc.5 user QA found the agent went silent for ~60 s while running `openclaw plugins install` before emitting the first user-visible line. From the user's POV the prompt looked unanswered. This RC strengthens SKILL.md + the quickstart guide to require line 1 BEFORE the first shell tool call, with reassuring wait-time copy.
10
+
11
+ ### Changed
12
+
13
+ - **SKILL.md user-visible line 1 reworded** from `Installing TotalReclaw…` to `Setting up TotalReclaw — this takes about a minute…` — adds explicit wait-time signal so the user knows to wait rather than resend.
14
+ - **New "MANDATORY ACK BEFORE FIRST TOOL CALL" section** in SKILL.md top-level rules. Calls out forbidden vs required ordering: line 1 must precede any shell tool call (no `openclaw plugins install` → 60 s silent → emit line 1).
15
+ - **Silence rules updated**: skipping line 1 entirely is now explicitly forbidden (previously the rule only forbade extra narration between lines, not omission of line 1).
16
+ - **`docs/guides/openclaw-setup-quickstart.md` mirrors the change** with the same wait-time copy and an explicit "Line 1 fires BEFORE the first shell tool call — not after" sub-section.
17
+
18
+ ### Implementation notes
19
+
20
+ - 4 new assertions in `skill-md-hybrid-primary.test.ts`: MANDATORY ACK section present, line 1 wait-time wording, Forbidden vs Required order documented, "Skipping line 1 entirely" listed as forbidden. 41/41 green.
21
+ - All other test suites unchanged: 92/92 fs-helpers + 21/21 register-command-name + 21/21 tr-cli-json + 44/44 trajectory-poller + 10/10 manifest-shape. check-scanner: 129 files, 0 flags.
22
+ - Pure documentation + spec change. No runtime code modified. Same poller behavior as rc.5.
23
+
7
24
  ## [3.3.11-rc.5] — 2026-05-07
8
25
 
9
26
  Trajectory poller hardening: cap extractions per poll iteration + skip stale trajectory files. Pedro's 2026-05-07 zai 429 cascade was caused by ~5 old session files all crossing the extract threshold in the same poll → 5 back-to-back LLM calls in seconds → daily quota tripped. Today's chat memories were lost because every extraction call returned 0 facts (LLM rejected with rate-limit).
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.11-rc.5
4
+ version: 3.3.12-rc.1
5
5
  author: TotalReclaw Team
6
6
  license: MIT
7
7
  homepage: https://totalreclaw.xyz
@@ -61,6 +61,15 @@ The word "pair" is internal jargon — never use it in user-visible prose. The u
61
61
 
62
62
  **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 **4–5 short lines TOTAL**. 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.
63
63
 
64
+ ### ⚡ MANDATORY ACK BEFORE FIRST TOOL CALL
65
+
66
+ **User-visible line 1 MUST be your FIRST output — emitted BEFORE you run any shell tool, plugin install, or `tr` command.** Install + setup takes 1–2 minutes of silent tool-execution; without an immediate ack the user assumes the request didn't register and may resend or abandon. The ack tells them work is happening.
67
+
68
+ The ack is unconditional. It fires the moment you decide to install / set up TotalReclaw — even before you've resolved `TR_CLI`, even before you've checked whether the plugin is already installed, even before the first `openclaw plugins install` shell call. Send line 1, THEN start the work.
69
+
70
+ Forbidden order (silent-then-narrate): ❌ run `openclaw plugins install` → wait 60s → emit line 1.
71
+ Required order (ack-then-work): ✅ emit line 1 → run `openclaw plugins install` silently → emit line 2 when `tr status` returns.
72
+
64
73
  ## ⛔ FORBIDDEN ACTIONS (4 hard rules from 2026-05-05 QA)
65
74
 
66
75
  These specific actions break the pair flow. Everything else is governed by the "emit only the numbered user-visible lines" rule above.
@@ -93,8 +102,8 @@ Then invoke as `node "$TR_CLI" <cmd> [--json]`.
93
102
 
94
103
  Speak only these lines, in order. Substitute the bracketed placeholders with the real values. No prefaces. No suffixes. No narration.
95
104
 
96
- 1. (start of install)
97
- > Installing TotalReclaw…
105
+ 1. (FIRST output, emitted BEFORE any shell tool call — see "MANDATORY ACK" rule above)
106
+ > Setting up TotalReclaw — this takes about a minute
98
107
  2. (after install + CLI verify — `tr status` works)
99
108
  > ✓ Installed (totalreclaw &lt;version&gt;, hybrid mode)
100
109
  3. (account-setup URL + PIN, IMMEDIATELY after `tr pair --json` returns — no consent gate)
@@ -114,8 +123,9 @@ Do NOT emit transitional / narrative lines between any of the four user-visible
114
123
  - ❌ "Need to pair. Let me kick that off:" → silent. Just run the `setsid -f` block. Emit line 3 when URL+PIN returns. ALSO never use the word "pair" in user-facing text — see vocabulary table above.
115
124
  - ❌ "Standing by." → silent. Acknowledgements between lines are noise.
116
125
  - ❌ Any "Let me X" / "Now I'll Y" / "Just give me a second" prelude.
126
+ - ❌ **Skipping line 1 entirely and going straight to shell tool calls.** Line 1 ack must precede the first tool call. Silent install = user thinks the prompt didn't register.
117
127
 
118
- The transcript Pedro should see is exactly four messages — the four numbered lines, nothing in between.
128
+ The transcript Pedro should see is exactly four messages — the four numbered lines, nothing in between. Line 1 fires immediately. Lines 2–4 fire as work completes. No prose between.
119
129
 
120
130
  ## How does TotalReclaw work? (canonical answer for user questions)
121
131
 
@@ -216,7 +226,7 @@ After you emit user-visible line 3, the user opens the URL on their phone or des
216
226
 
217
227
  Common user-side issues during pair (recover gracefully — emit ONE tight line, don't pre-narrate):
218
228
 
219
- - **"The page won't load"** → check the URL is the staging URL (`api-staging.totalreclaw.xyz` for RC builds, `api.totalreclaw.xyz` for stable). If they used the wrong stub host, generate a fresh URL.
229
+ - **"The page won't load"** → confirm the URL host is `api.totalreclaw.xyz` (the default for both stable and RC post-3.3.12-rc.1). If a `TOTALRECLAW_SERVER_URL` env override was set, the host might be `api-staging.totalreclaw.xyz` (staging, opt-in) or a self-hosted relay. Wrong stub host generate a fresh URL.
220
230
  - **"PIN says expired"** or countdown ran out → re-run the pair block (Step 4 above) and emit line 3 again with the fresh URL+PIN. The previous session is dead.
221
231
  - **"It says invalid phrase"** during Log in → the user pasted a phrase that isn't BIP-39 valid (typo or wrong source). Tell them to double-check and re-paste; or switch to **Set up** tab to generate a fresh one (loses existing memories).
222
232
  - **"I clicked Set up TotalReclaw but nothing happened"** / **502** → the gateway WS dropped before respond. The pair subprocess is alive (you used `setsid -f`). Wait 30s; if the user still sees the 502, re-run Step 4 (the deferred reload should have completed by then).
package/config.ts CHANGED
@@ -138,15 +138,14 @@ export const CONFIG = {
138
138
  get sessionId(): string | null {
139
139
  return getSessionId();
140
140
  },
141
- // 3.3.3-rc.1: source default is `api-staging.totalreclaw.xyz` per the
142
- // codified RC=staging / stable=production rule (PR #165). The workflow
143
- // step "Bind stable to production URLs" in `npm-publish.yml` /
144
- // `publish-clawhub.yml` sed-replaces `api-staging.totalreclaw.xyz` ->
145
- // `api.totalreclaw.xyz` across the built `dist/` tree (and skill.json /
146
- // SKILL.md / CHANGELOG / CLAWHUB.md / package.json) when
147
- // `release-type=stable`. RC publishes leave the staging URL untouched.
141
+ // 3.3.12-rc.1 (F flip): source default is `api.totalreclaw.xyz` (production)
142
+ // for BOTH stable and RC builds. Previously RC defaulted to staging, which
143
+ // stranded users who picked `@rc` with their memories on staging. Staging
144
+ // access is now opt-in via `TOTALRECLAW_SERVER_URL=https://api-staging.totalreclaw.xyz`.
145
+ // No more publish-time URL rewrites both release-types ship the same
146
+ // production default, and the workflow guard rails simply assert that.
148
147
  // User overrides via `TOTALRECLAW_SERVER_URL=...` always win.
149
- serverUrl: (process.env.TOTALRECLAW_SERVER_URL || 'https://api-staging.totalreclaw.xyz').replace(/\/+$/, ''),
148
+ serverUrl: (process.env.TOTALRECLAW_SERVER_URL || 'https://api.totalreclaw.xyz').replace(/\/+$/, ''),
150
149
  selfHosted: process.env.TOTALRECLAW_SELF_HOSTED === 'true',
151
150
  credentialsPath: process.env.TOTALRECLAW_CREDENTIALS_PATH || path.join(home, '.totalreclaw', 'credentials.json'),
152
151
  // 3.2.0 onboarding state file — separate from credentials.json so it
@@ -172,7 +171,7 @@ export const CONFIG = {
172
171
  // 3.3.1-rc.11 — relay base URL for the WebSocket-brokered pair flow.
173
172
  // `wss://` preferred; `https://` is rewritten in the remote-client.
174
173
  pairRelayUrl: (process.env.TOTALRECLAW_PAIR_RELAY_URL
175
- || 'wss://api-staging.totalreclaw.xyz').replace(/\/+$/, ''),
174
+ || 'wss://api.totalreclaw.xyz').replace(/\/+$/, ''),
176
175
 
177
176
  // Chain — chainId is no longer user-configurable. It is auto-detected from
178
177
  // the relay billing response (free = Base Sepolia / 84532, Pro = Gnosis /
package/dist/config.js CHANGED
@@ -123,15 +123,14 @@ export const CONFIG = {
123
123
  get sessionId() {
124
124
  return getSessionId();
125
125
  },
126
- // 3.3.3-rc.1: source default is `api-staging.totalreclaw.xyz` per the
127
- // codified RC=staging / stable=production rule (PR #165). The workflow
128
- // step "Bind stable to production URLs" in `npm-publish.yml` /
129
- // `publish-clawhub.yml` sed-replaces `api-staging.totalreclaw.xyz` ->
130
- // `api.totalreclaw.xyz` across the built `dist/` tree (and skill.json /
131
- // SKILL.md / CHANGELOG / CLAWHUB.md / package.json) when
132
- // `release-type=stable`. RC publishes leave the staging URL untouched.
126
+ // 3.3.12-rc.1 (F flip): source default is `api.totalreclaw.xyz` (production)
127
+ // for BOTH stable and RC builds. Previously RC defaulted to staging, which
128
+ // stranded users who picked `@rc` with their memories on staging. Staging
129
+ // access is now opt-in via `TOTALRECLAW_SERVER_URL=https://api-staging.totalreclaw.xyz`.
130
+ // No more publish-time URL rewrites both release-types ship the same
131
+ // production default, and the workflow guard rails simply assert that.
133
132
  // User overrides via `TOTALRECLAW_SERVER_URL=...` always win.
134
- serverUrl: (process.env.TOTALRECLAW_SERVER_URL || 'https://api-staging.totalreclaw.xyz').replace(/\/+$/, ''),
133
+ serverUrl: (process.env.TOTALRECLAW_SERVER_URL || 'https://api.totalreclaw.xyz').replace(/\/+$/, ''),
135
134
  selfHosted: process.env.TOTALRECLAW_SELF_HOSTED === 'true',
136
135
  credentialsPath: process.env.TOTALRECLAW_CREDENTIALS_PATH || path.join(home, '.totalreclaw', 'credentials.json'),
137
136
  // 3.2.0 onboarding state file — separate from credentials.json so it
@@ -156,7 +155,7 @@ export const CONFIG = {
156
155
  // 3.3.1-rc.11 — relay base URL for the WebSocket-brokered pair flow.
157
156
  // `wss://` preferred; `https://` is rewritten in the remote-client.
158
157
  pairRelayUrl: (process.env.TOTALRECLAW_PAIR_RELAY_URL
159
- || 'wss://api-staging.totalreclaw.xyz').replace(/\/+$/, ''),
158
+ || 'wss://api.totalreclaw.xyz').replace(/\/+$/, ''),
160
159
  // Chain — chainId is no longer user-configurable. It is auto-detected from
161
160
  // the relay billing response (free = Base Sepolia / 84532, Pro = Gnosis /
162
161
  // 100). The default here is used only before the first billing lookup
package/dist/index.js CHANGED
@@ -547,9 +547,9 @@ let stagingBannerLogged = false;
547
547
  * directs the caller to `openclaw totalreclaw onboard`.
548
548
  */
549
549
  async function initialize(logger) {
550
- // 3.3.3-rc.1: staging is the source default per #165. Stable build-time
551
- // sed-replace flips `api-staging` -> `api` in dist/.
552
- const serverUrl = CONFIG.serverUrl || 'https://api-staging.totalreclaw.xyz';
550
+ // 3.3.12-rc.1 (F flip): production is the source default for all builds.
551
+ // Staging is opt-in via TOTALRECLAW_SERVER_URL=https://api-staging.totalreclaw.xyz.
552
+ const serverUrl = CONFIG.serverUrl || 'https://api.totalreclaw.xyz';
553
553
  let masterPassword = CONFIG.recoveryPhrase;
554
554
  // 3.2.0: if the env var is unset, probe credentials.json for a
555
555
  // pre-existing mnemonic (written either by the CLI wizard on this machine
@@ -5374,25 +5374,29 @@ const plugin = {
5374
5374
  let stagingBannerSuppressed = false;
5375
5375
  if (!stagingBannerShown) {
5376
5376
  try {
5377
- const usingStagingDefault = CONFIG.serverUrl.includes('api-staging.totalreclaw.xyz');
5378
- const userOverrode = CONFIG.serverUrlEnvOverridden;
5379
- if (usingStagingDefault && !userOverrode) {
5377
+ // 3.3.12-rc.1 (F flip): banner now fires when serverUrl resolves
5378
+ // to api-staging.totalreclaw.xyz, which under the new contract
5379
+ // can ONLY happen if (a) user opted in via env override, or
5380
+ // (b) the artifact is broken / accidentally bound to staging.
5381
+ // Either way the user benefits from seeing the warning.
5382
+ const usingStaging = CONFIG.serverUrl.includes('api-staging.totalreclaw.xyz');
5383
+ if (usingStaging) {
5380
5384
  stagingBannerBlock =
5381
- '## ⚠️ TotalReclaw is running in RC / staging mode\n\n' +
5382
- 'This build is bound to `api-staging.totalreclaw.xyz`. Staging has **no SLA** ' +
5385
+ '## ⚠️ TotalReclaw is running in staging mode\n\n' +
5386
+ 'This session is bound to `api-staging.totalreclaw.xyz`. Staging has **no SLA** ' +
5383
5387
  'and may be wiped between QA cycles. Do **NOT** use this build for real data.\n\n' +
5384
- 'For production, install the stable release: `openclaw plugins install ' +
5385
- '@totalreclaw/totalreclaw` (no `@rc` suffix). To pin a custom server, set ' +
5386
- '`TOTALRECLAW_SERVER_URL=https://api.totalreclaw.xyz` in your env.\n\n';
5387
- // Do NOT set stagingBannerShown=true here — see comment above.
5388
- // Logger emits once per gateway process; this is fine to
5389
- // gate on the same flag because the logger is operator-
5390
- // facing, not user-facing.
5388
+ 'The default relay is `api.totalreclaw.xyz` (production). To return to production, ' +
5389
+ 'unset `TOTALRECLAW_SERVER_URL`. To stay on staging, leave it set to ' +
5390
+ '`https://api-staging.totalreclaw.xyz`.\n\n';
5391
+ // Do NOT set stagingBannerShown=true here — see comment in
5392
+ // staging-banner-gate.test.ts. Banner-shown flips only via
5393
+ // consumeBannerForPrepend() once a return path actually
5394
+ // delivers the block.
5391
5395
  stagingBannerSuppressed = true;
5392
5396
  }
5393
5397
  else {
5394
- // Non-RC artifact OR user override — never fire the banner this
5395
- // gateway-process lifetime.
5398
+ // Production default OR custom URL — never fire the banner
5399
+ // this gateway-process lifetime.
5396
5400
  stagingBannerShown = true;
5397
5401
  }
5398
5402
  }
@@ -5401,13 +5405,12 @@ const plugin = {
5401
5405
  stagingBannerShown = true;
5402
5406
  }
5403
5407
  }
5404
- // Operator-facing log: once per process, when we DETECT the
5405
- // staging build (banner-shown semantics are about user
5406
- // delivery; this log is independent).
5408
+ // Operator-facing log: once per process, when we DETECT staging.
5407
5409
  if (stagingBannerSuppressed && !stagingBannerLogged) {
5408
5410
  stagingBannerLogged = true;
5409
- api.logger.warn('TotalReclaw: RC/staging build active (api-staging.totalreclaw.xyz). ' +
5410
- 'See docs/guides/release-process.md for the RC=staging / stable=production rule.');
5411
+ api.logger.warn('TotalReclaw: staging mode active (api-staging.totalreclaw.xyz). ' +
5412
+ 'Default is production (api.totalreclaw.xyz); staging is opt-in via ' +
5413
+ 'TOTALRECLAW_SERVER_URL.');
5411
5414
  }
5412
5415
  /**
5413
5416
  * Helper — invoked inline at any `prependContext` site that
@@ -48,7 +48,7 @@ import { decryptPairingPayload, generateGatewayKeypair, } from './pair-crypto.js
48
48
  // Constants
49
49
  // ---------------------------------------------------------------------------
50
50
  /** Default relay endpoint. Caller passes `TOTALRECLAW_PAIR_RELAY_URL` via config. */
51
- export const DEFAULT_RELAY_URL = 'wss://api-staging.totalreclaw.xyz';
51
+ export const DEFAULT_RELAY_URL = 'wss://api.totalreclaw.xyz';
52
52
  /** WebSocket connect + handshake timeout (ms). */
53
53
  const OPEN_TIMEOUT_MS = 10_000;
54
54
  /** Default blocking-await-for-forward timeout (5 minutes — matches relay TTL). */
@@ -675,7 +675,7 @@ export function isSubgraphMode() {
675
675
  *
676
676
  * After the v1 env var cleanup, clients only need:
677
677
  * - TOTALRECLAW_RECOVERY_PHRASE -- BIP-39 mnemonic
678
- * - TOTALRECLAW_SERVER_URL -- relay server URL (source default: https://api-staging.totalreclaw.xyz; stable build: https://api.totalreclaw.xyz — swapped in at publish time per PR #165)
678
+ * - TOTALRECLAW_SERVER_URL -- relay server URL (default: https://api.totalreclaw.xyz; staging via override: https://api-staging.totalreclaw.xyz)
679
679
  * - TOTALRECLAW_SELF_HOSTED -- set "true" to use self-hosted server (default: managed service)
680
680
  *
681
681
  * Chain ID is no longer configurable via env — it is auto-detected from the
@@ -683,8 +683,8 @@ export function isSubgraphMode() {
683
683
  */
684
684
  export function getSubgraphConfig() {
685
685
  return {
686
- // 3.3.3-rc.1: staging by default in source; stable workflow seds.
687
- relayUrl: CONFIG.serverUrl || 'https://api-staging.totalreclaw.xyz',
686
+ // 3.3.12-rc.1 (F flip): production default for both release-types.
687
+ relayUrl: CONFIG.serverUrl || 'https://api.totalreclaw.xyz',
688
688
  mnemonic: CONFIG.recoveryPhrase,
689
689
  cachePath: CONFIG.cachePath,
690
690
  chainId: CONFIG.chainId,
package/dist/tr-cli.js CHANGED
@@ -41,7 +41,7 @@ const STATE_PATH = CONFIG.onboardingStatePath;
41
41
  // Auto-synced by skill/scripts/sync-version.mjs from skill/plugin/package.json::version.
42
42
  // Do not edit by hand — running tests will catch drift but the publish workflow
43
43
  // rewrites this constant at the start of every npm/ClawHub publish.
44
- const PLUGIN_VERSION = '3.3.11-rc.5';
44
+ const PLUGIN_VERSION = '3.3.12-rc.1';
45
45
  function die(msg, code = 1) {
46
46
  process.stderr.write(`tr: ${msg}\n`);
47
47
  process.exit(code);
@@ -367,7 +367,7 @@ async function main() {
367
367
  ' remember: {"ok":true,"id":"...","claim_count":N}\n' +
368
368
  ' recall: {"results":[{"text":"...","score":0.8}]}\n\n' +
369
369
  'Environment:\n' +
370
- ' TOTALRECLAW_SERVER_URL — relay URL (default: api-staging.totalreclaw.xyz)\n' +
370
+ ' TOTALRECLAW_SERVER_URL — relay URL (default: api.totalreclaw.xyz; staging: api-staging.totalreclaw.xyz)\n' +
371
371
  ' TOTALRECLAW_CREDENTIALS_PATH — override credentials.json path\n');
372
372
  break;
373
373
  default:
package/index.ts CHANGED
@@ -807,9 +807,9 @@ let stagingBannerLogged = false;
807
807
  * directs the caller to `openclaw totalreclaw onboard`.
808
808
  */
809
809
  async function initialize(logger: OpenClawPluginApi['logger']): Promise<void> {
810
- // 3.3.3-rc.1: staging is the source default per #165. Stable build-time
811
- // sed-replace flips `api-staging` -> `api` in dist/.
812
- const serverUrl = CONFIG.serverUrl || 'https://api-staging.totalreclaw.xyz';
810
+ // 3.3.12-rc.1 (F flip): production is the source default for all builds.
811
+ // Staging is opt-in via TOTALRECLAW_SERVER_URL=https://api-staging.totalreclaw.xyz.
812
+ const serverUrl = CONFIG.serverUrl || 'https://api.totalreclaw.xyz';
813
813
  let masterPassword = CONFIG.recoveryPhrase;
814
814
 
815
815
  // 3.2.0: if the env var is unset, probe credentials.json for a
@@ -6262,24 +6262,28 @@ const plugin = {
6262
6262
  let stagingBannerSuppressed = false;
6263
6263
  if (!stagingBannerShown) {
6264
6264
  try {
6265
- const usingStagingDefault = CONFIG.serverUrl.includes('api-staging.totalreclaw.xyz');
6266
- const userOverrode = CONFIG.serverUrlEnvOverridden;
6267
- if (usingStagingDefault && !userOverrode) {
6265
+ // 3.3.12-rc.1 (F flip): banner now fires when serverUrl resolves
6266
+ // to api-staging.totalreclaw.xyz, which under the new contract
6267
+ // can ONLY happen if (a) user opted in via env override, or
6268
+ // (b) the artifact is broken / accidentally bound to staging.
6269
+ // Either way the user benefits from seeing the warning.
6270
+ const usingStaging = CONFIG.serverUrl.includes('api-staging.totalreclaw.xyz');
6271
+ if (usingStaging) {
6268
6272
  stagingBannerBlock =
6269
- '## ⚠️ TotalReclaw is running in RC / staging mode\n\n' +
6270
- 'This build is bound to `api-staging.totalreclaw.xyz`. Staging has **no SLA** ' +
6273
+ '## ⚠️ TotalReclaw is running in staging mode\n\n' +
6274
+ 'This session is bound to `api-staging.totalreclaw.xyz`. Staging has **no SLA** ' +
6271
6275
  'and may be wiped between QA cycles. Do **NOT** use this build for real data.\n\n' +
6272
- 'For production, install the stable release: `openclaw plugins install ' +
6273
- '@totalreclaw/totalreclaw` (no `@rc` suffix). To pin a custom server, set ' +
6274
- '`TOTALRECLAW_SERVER_URL=https://api.totalreclaw.xyz` in your env.\n\n';
6275
- // Do NOT set stagingBannerShown=true here — see comment above.
6276
- // Logger emits once per gateway process; this is fine to
6277
- // gate on the same flag because the logger is operator-
6278
- // facing, not user-facing.
6276
+ 'The default relay is `api.totalreclaw.xyz` (production). To return to production, ' +
6277
+ 'unset `TOTALRECLAW_SERVER_URL`. To stay on staging, leave it set to ' +
6278
+ '`https://api-staging.totalreclaw.xyz`.\n\n';
6279
+ // Do NOT set stagingBannerShown=true here — see comment in
6280
+ // staging-banner-gate.test.ts. Banner-shown flips only via
6281
+ // consumeBannerForPrepend() once a return path actually
6282
+ // delivers the block.
6279
6283
  stagingBannerSuppressed = true;
6280
6284
  } else {
6281
- // Non-RC artifact OR user override — never fire the banner this
6282
- // gateway-process lifetime.
6285
+ // Production default OR custom URL — never fire the banner
6286
+ // this gateway-process lifetime.
6283
6287
  stagingBannerShown = true;
6284
6288
  }
6285
6289
  } catch {
@@ -6287,14 +6291,13 @@ const plugin = {
6287
6291
  stagingBannerShown = true;
6288
6292
  }
6289
6293
  }
6290
- // Operator-facing log: once per process, when we DETECT the
6291
- // staging build (banner-shown semantics are about user
6292
- // delivery; this log is independent).
6294
+ // Operator-facing log: once per process, when we DETECT staging.
6293
6295
  if (stagingBannerSuppressed && !stagingBannerLogged) {
6294
6296
  stagingBannerLogged = true;
6295
6297
  api.logger.warn(
6296
- 'TotalReclaw: RC/staging build active (api-staging.totalreclaw.xyz). ' +
6297
- 'See docs/guides/release-process.md for the RC=staging / stable=production rule.',
6298
+ 'TotalReclaw: staging mode active (api-staging.totalreclaw.xyz). ' +
6299
+ 'Default is production (api.totalreclaw.xyz); staging is opt-in via ' +
6300
+ 'TOTALRECLAW_SERVER_URL.',
6298
6301
  );
6299
6302
  }
6300
6303
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totalreclaw/totalreclaw",
3
- "version": "3.3.11-rc.5",
3
+ "version": "3.3.12-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": [
@@ -81,7 +81,7 @@
81
81
  "./dist/index.js"
82
82
  ],
83
83
  "compat": {
84
- "pluginApi": ">=2026.3.22"
84
+ "pluginApi": ">=2026.5.5"
85
85
  },
86
86
  "build": {
87
87
  "openclawVersion": "2026.4.24"
@@ -57,7 +57,7 @@ import {
57
57
  // ---------------------------------------------------------------------------
58
58
 
59
59
  /** Default relay endpoint. Caller passes `TOTALRECLAW_PAIR_RELAY_URL` via config. */
60
- export const DEFAULT_RELAY_URL = 'wss://api-staging.totalreclaw.xyz';
60
+ export const DEFAULT_RELAY_URL = 'wss://api.totalreclaw.xyz';
61
61
 
62
62
  /** WebSocket connect + handshake timeout (ms). */
63
63
  const OPEN_TIMEOUT_MS = 10_000;
package/skill.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "totalreclaw",
3
- "version": "3.3.11-rc.5",
3
+ "version": "3.3.12-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",
@@ -141,8 +141,9 @@
141
141
  }
142
142
  ],
143
143
  "openclaw": {
144
- "minVersion": "0.1.0",
145
- "maxVersion": "1.0.0",
144
+ "compat": {
145
+ "pluginApi": ">=2026.5.5"
146
+ },
146
147
  "requires": {
147
148
  "env": [],
148
149
  "bins": []
@@ -318,8 +319,8 @@
318
319
  "config": {
319
320
  "serverUrl": {
320
321
  "type": "string",
321
- "default": "https://api-staging.totalreclaw.xyz",
322
- "description": "TotalReclaw server URL (only change for self-hosted mode). Source default points at staging; stable releases swap to https://api.totalreclaw.xyz at publish time per PR #165."
322
+ "default": "https://api.totalreclaw.xyz",
323
+ "description": "TotalReclaw server URL. Both stable and RC builds default to production (api.totalreclaw.xyz). Set TOTALRECLAW_SERVER_URL=https://api-staging.totalreclaw.xyz to test against staging."
323
324
  },
324
325
  "autoExtractEveryTurns": {
325
326
  "type": "number",
package/subgraph-store.ts CHANGED
@@ -805,7 +805,7 @@ export function isSubgraphMode(): boolean {
805
805
  *
806
806
  * After the v1 env var cleanup, clients only need:
807
807
  * - TOTALRECLAW_RECOVERY_PHRASE -- BIP-39 mnemonic
808
- * - TOTALRECLAW_SERVER_URL -- relay server URL (source default: https://api-staging.totalreclaw.xyz; stable build: https://api.totalreclaw.xyz — swapped in at publish time per PR #165)
808
+ * - TOTALRECLAW_SERVER_URL -- relay server URL (default: https://api.totalreclaw.xyz; staging via override: https://api-staging.totalreclaw.xyz)
809
809
  * - TOTALRECLAW_SELF_HOSTED -- set "true" to use self-hosted server (default: managed service)
810
810
  *
811
811
  * Chain ID is no longer configurable via env — it is auto-detected from the
@@ -813,8 +813,8 @@ export function isSubgraphMode(): boolean {
813
813
  */
814
814
  export function getSubgraphConfig(): SubgraphStoreConfig {
815
815
  return {
816
- // 3.3.3-rc.1: staging by default in source; stable workflow seds.
817
- relayUrl: CONFIG.serverUrl || 'https://api-staging.totalreclaw.xyz',
816
+ // 3.3.12-rc.1 (F flip): production default for both release-types.
817
+ relayUrl: CONFIG.serverUrl || 'https://api.totalreclaw.xyz',
818
818
  mnemonic: CONFIG.recoveryPhrase,
819
819
  cachePath: CONFIG.cachePath,
820
820
  chainId: CONFIG.chainId,
package/tr-cli.ts CHANGED
@@ -52,7 +52,7 @@ const STATE_PATH = CONFIG.onboardingStatePath;
52
52
  // Auto-synced by skill/scripts/sync-version.mjs from skill/plugin/package.json::version.
53
53
  // Do not edit by hand — running tests will catch drift but the publish workflow
54
54
  // rewrites this constant at the start of every npm/ClawHub publish.
55
- const PLUGIN_VERSION = '3.3.11-rc.5';
55
+ const PLUGIN_VERSION = '3.3.12-rc.1';
56
56
 
57
57
  function die(msg: string, code = 1): never {
58
58
  process.stderr.write(`tr: ${msg}\n`);
@@ -431,7 +431,7 @@ async function main(): Promise<void> {
431
431
  ' remember: {"ok":true,"id":"...","claim_count":N}\n' +
432
432
  ' recall: {"results":[{"text":"...","score":0.8}]}\n\n' +
433
433
  'Environment:\n' +
434
- ' TOTALRECLAW_SERVER_URL — relay URL (default: api-staging.totalreclaw.xyz)\n' +
434
+ ' TOTALRECLAW_SERVER_URL — relay URL (default: api.totalreclaw.xyz; staging: api-staging.totalreclaw.xyz)\n' +
435
435
  ' TOTALRECLAW_CREDENTIALS_PATH — override credentials.json path\n',
436
436
  );
437
437
  break;