@openclaw/matrix 2026.7.2-beta.7 → 2026.8.1-beta.3

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.
Files changed (92) hide show
  1. package/dist/{account-selection-kqquRzCf.js → account-selection-CWuhuFn1.js} +7 -8
  2. package/dist/{accounts-DfngqebB.js → accounts-BCzyubQt.js} +3 -3
  3. package/dist/api.js +8 -11
  4. package/dist/{approval-handler.runtime-DSeaIsGa.js → approval-handler.runtime-CSvueU9P.js} +7 -6
  5. package/dist/{approval-ids-BdJGPAJT.js → approval-ids-CEcf-EiM.js} +1 -1
  6. package/dist/{approval-reaction-auth-BjOpELxu.js → approval-reaction-auth-CziKXatm.js} +2 -2
  7. package/dist/{approval-reactions-D-BxBK_L.js → approval-reactions-tXh9KYrW.js} +2 -8
  8. package/dist/auth-presence.js +2 -2
  9. package/dist/{channel-vj788dNZ.js → channel-CzQw5OZN.js} +376 -148
  10. package/dist/channel-plugin-api.js +1 -1
  11. package/dist/{channel.runtime-CLoF2S9T.js → channel.runtime-I9pBRQb3.js} +79 -55
  12. package/dist/{config-schema-Djxw3C6b.js → channel.setup-aNaa3Uyn.js} +51 -10
  13. package/dist/{cli-DMqfDE-q.js → cli-iR6QJ5U0.js} +16 -16
  14. package/dist/{cli-metadata-C7D53SND.js → cli-metadata-BmUYWjuM.js} +1 -1
  15. package/dist/cli-metadata.js +1 -1
  16. package/dist/client-BBQdBG7t.js +799 -0
  17. package/dist/{client-6eRENr7k.js → client-D8XghqmX.js} +4 -4
  18. package/dist/{client-bootstrap-XsIkHNt0.js → client-bootstrap-Co3RlItb.js} +25 -61
  19. package/dist/client-support-DLj4vDeu.js +93 -0
  20. package/dist/config-update-Bor_Pjsv.js +150 -0
  21. package/dist/contract-api.js +2 -2
  22. package/dist/{credentials-W2EmwRhu.js → credentials-BdAaWuiR.js} +2 -1
  23. package/dist/credentials-read-B37cQknZ.js +51 -0
  24. package/dist/credentials-state-B3cuUFwZ.js +27 -0
  25. package/dist/{credentials-write.runtime-Be9zNSUw.js → credentials-write.runtime-nAV2-5uR.js} +1 -1
  26. package/dist/{crypto-runtime-D9_6J5tZ.js → crypto-runtime-Bnz3zEcS.js} +55 -32
  27. package/dist/direct-room-RinHjtqX.js +71 -0
  28. package/dist/{directory-live-C8dVBiCc.js → directory-live-DLQzel12.js} +2 -3
  29. package/dist/{doctor-CM8ijNpW.js → doctor-EWf9CDso.js} +2 -2
  30. package/dist/{doctor-contract-BMSJkkAE.js → doctor-contract-DEt4O4Zt.js} +2 -3
  31. package/dist/doctor-contract-api.js +209 -91
  32. package/dist/{draft-stream-CtvOXq0Z.js → draft-stream-DQ7QNC-l.js} +20 -23
  33. package/dist/{encryption-guidance-CbEFe38F.js → encryption-guidance-DmLY8NiO.js} +1 -1
  34. package/dist/{env-auth-CQsYbz-p.js → env-auth-MVS-Vv41.js} +4 -3
  35. package/dist/{env-vars-B0NxQnPk.js → env-vars-dGqak9dN.js} +1 -1
  36. package/dist/{errors-C47hvAF8.js → errors-DKVS3_DO.js} +2 -5
  37. package/dist/{file-sync-store-DiiFsayX.js → file-sync-store-DjskBX2o.js} +24 -3
  38. package/dist/helper-api.js +2 -2
  39. package/dist/{idb-persistence-B6x7dMsF.js → idb-persistence-BM0P27Zg.js} +3 -2
  40. package/dist/{inbound-dedupe-CaBLblef.js → inbound-dedupe-RvSLqdsz.js} +2 -2
  41. package/dist/index.js +1 -1
  42. package/dist/{logger-D0GCSDQq.js → logger-B_71hN6W.js} +1 -1
  43. package/dist/{logging-DV-p52N0.js → logging-DRjvUOIh.js} +1 -1
  44. package/dist/{media-text-BTwzADS_.js → media-text-Dh-DpTc3.js} +4 -1
  45. package/dist/{messages-DxQJkhxs.js → messages-DEqg7HVy.js} +31 -11
  46. package/dist/{monitor-VyWlSLwo.js → monitor-FNrfkuWL.js} +413 -405
  47. package/dist/plugin-entry.handlers.runtime.js +3 -3
  48. package/dist/probe.runtime-NIJZYqc2.js +2 -0
  49. package/dist/profile-D-Wubo0A.js +108 -0
  50. package/dist/{profile-update-CffmyW_4.js → profile-update-BQlE5s2J.js} +3 -2
  51. package/dist/{reaction-events-B00WSi98.js → reaction-events-BKOLlnCo.js} +10 -7
  52. package/dist/{recovery-key-store-BNnHvXdk.js → recovery-key-store-CognuDys.js} +5 -4
  53. package/dist/{resolve-targets-nm2L48sh.js → resolve-targets-e7AI0P75.js} +2 -2
  54. package/dist/{resolver.runtime-DS6uPaEe.js → resolver.runtime-V8u0pHEb.js} +1 -1
  55. package/dist/{room-info-CAFZ3Z9J.js → room-info-BXQA7y10.js} +12 -3
  56. package/dist/runtime-api.js +7 -4
  57. package/dist/{sdk-bUytQHx7.js → sdk-NxK3vzMa.js} +242 -119
  58. package/dist/{secret-contract-M3hRmGO-.js → secret-contract-CufozuyJ.js} +1 -1
  59. package/dist/secret-contract-api.js +1 -1
  60. package/dist/{send-BldGYG8g.js → send-ClHgDZLT.js} +1477 -1210
  61. package/dist/session-binding-contract-api.js +2 -3
  62. package/dist/{setup-bootstrap-Deleiibz.js → setup-bootstrap-BGPjbA5N.js} +4 -4
  63. package/dist/{setup-core-BVfBv2ai.js → setup-core-DigrLebY.js} +17 -266
  64. package/dist/setup-plugin-api.js +1 -44
  65. package/dist/{setup-surface-BBq3WeqX.js → setup-surface-Dtn8sAWs.js} +15 -16
  66. package/dist/{startup-verification-wm3_i88s.js → startup-verification-Cs08ca8u.js} +3 -3
  67. package/dist/{storage-BvAkgzvT.js → storage-BsGuHngK.js} +3 -3
  68. package/dist/subagent-hooks-CMoZaARG.js +48 -0
  69. package/dist/subagent-hooks-api.js +1 -1
  70. package/dist/{target-ids-B-5aQxwn.js → target-ids-Nwx7cMVE.js} +11 -1
  71. package/dist/{thread-binding-api-DRbBZlhS.js → thread-binding-api-CzkeLZCU.js} +1 -1
  72. package/dist/thread-binding-api.js +1 -1
  73. package/dist/{thread-bindings-DGbl3vDW.js → thread-bindings-BYEGfw3h.js} +17 -10
  74. package/dist/thread-bindings-runtime.js +1 -1
  75. package/dist/{thread-bindings-shared-CKnY4LSd.js → thread-bindings-shared-oNPiyMWY.js} +1 -6
  76. package/dist/{tool-actions.runtime-uu9blSqO.js → tool-actions.runtime-ck6IJyP0.js} +36 -19
  77. package/dist/{verification-DYMQ1QpI.js → verification-CabtBTtB.js} +2 -2
  78. package/openclaw.plugin.json +61 -1
  79. package/package.json +4 -4
  80. package/dist/active-client-DXvz2gCo.js +0 -20
  81. package/dist/client-Dbso3-0V.js +0 -30
  82. package/dist/create-client-BmSU-q-D.js +0 -61
  83. package/dist/credentials-read-DVmFCm7X.js +0 -77
  84. package/dist/exec-approval-resolver-BCgqRtZS.js +0 -16
  85. package/dist/preflight-audio.runtime-BZxxQsxY.js +0 -11
  86. package/dist/probe.runtime-BuieqmS3.js +0 -3
  87. package/dist/record-shared-CWWx6fvI.js +0 -2
  88. package/dist/route-DY6at4qJ.js +0 -161
  89. package/dist/shared-CUMWxcMz.js +0 -673
  90. package/dist/subagent-hooks-dkPAF6Et.js +0 -143
  91. package/dist/sync-state-CWbp0QSY.js +0 -12
  92. package/dist/{runtime-api-D1xI_cvh.js → runtime-api-BGO16Fu8.js} +3 -3
@@ -1,19 +1,25 @@
1
- import { n as formatMatrixErrorReason, r as isMatrixNotFoundError, t as formatMatrixErrorMessage } from "./errors-C47hvAF8.js";
2
- import { t as SqliteBackedMatrixSyncStore } from "./file-sync-store-DiiFsayX.js";
3
- import { n as LogService, r as noop, t as ConsoleLogger } from "./logger-D0GCSDQq.js";
1
+ import "./reaction-common-DkrQdBSZ.js";
2
+ import { t as SqliteBackedMatrixSyncStore } from "./file-sync-store-DjskBX2o.js";
3
+ import { n as LogService, r as noop, t as ConsoleLogger } from "./logger-B_71hN6W.js";
4
4
  import { t as MATRIX_IDB_PERSIST_INTERVAL_MS } from "./idb-persistence-lock-DAJ49nZX.js";
5
- import { c as createMatrixStartupAbortError, u as throwIfMatrixStartupAborted } from "./shared-CUMWxcMz.js";
5
+ import { n as isMatrixNotFoundError, t as formatMatrixErrorReason } from "./errors-DKVS3_DO.js";
6
+ import { a as throwIfMatrixStartupAborted, r as createMatrixStartupAbortError } from "./client-BBQdBG7t.js";
6
7
  import { a as matrixEventToRaw, n as createMatrixGuardedFetch, o as parseMxc, t as MatrixAuthedHttpClient } from "./http-client-CycYxU9-.js";
7
8
  import { n as resolveMatrixRoomKeyBackupReadinessError } from "./backup-health-Dm_YMVFT.js";
8
- import { t as createMatrixJsSdkClientLogger } from "./logging-DV-p52N0.js";
9
- import { n as isMatrixReadySyncState, r as isMatrixTerminalSyncState } from "./sync-state-CWbp0QSY.js";
10
- import { n as isRepairableSecretStorageAccessError, t as MatrixRecoveryKeyStore } from "./recovery-key-store-BNnHvXdk.js";
9
+ import { t as createMatrixJsSdkClientLogger } from "./logging-DRjvUOIh.js";
10
+ import { a as isMatrixAccessTokenInvalidatedError, c as resolveMatrixLocalTimeoutMs, f as isMatrixReadySyncState, i as createMatrixExplicitBootstrapOptions, l as unresolvedMatrixDeviceVerificationStatus, n as MATRIX_INITIAL_CRYPTO_BOOTSTRAP_OPTIONS, o as resolveMatrixDiagnostic, p as isMatrixTerminalSyncState, r as MATRIX_STATUS_DIAGNOSTIC_TIMEOUT_MS, s as resolveMatrixDiagnosticResult, t as MATRIX_AUTOMATIC_REPAIR_BOOTSTRAP_OPTIONS, u as unresolvedMatrixRoomKeyBackupStatus } from "./client-support-DLj4vDeu.js";
11
+ import { n as isRepairableSecretStorageAccessError, t as MatrixRecoveryKeyStore } from "./recovery-key-store-CognuDys.js";
12
+ import { createRequire } from "node:module";
11
13
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
12
14
  import { normalizeNullableString, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
15
+ import { createHash } from "node:crypto";
16
+ import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
13
17
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
14
- import { ClientEvent, Filter, MatrixEventEvent, Preset, createClient } from "matrix-js-sdk/lib/matrix.js";
18
+ import { ClientEvent, EventType, Filter, MatrixError, MatrixEventEvent, MsgType, Preset, createClient } from "matrix-js-sdk/lib/matrix.js";
15
19
  import { EventEmitter } from "node:events";
16
20
  import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
21
+ import { SyncApi, SyncState } from "matrix-js-sdk/lib/sync.js";
22
+ import { EventStatus } from "matrix-js-sdk/lib/models/event-status.js";
17
23
  //#region extensions/matrix/src/matrix/sdk/client-device-info.ts
18
24
  async function resolveMatrixCrossSigningPublicationStatus(params) {
19
25
  if (!params.userId) return {
@@ -78,8 +84,8 @@ function registerMatrixClientBridge(params) {
78
84
  });
79
85
  params.client.on(ClientEvent.Room, params.emitMembershipForRoom);
80
86
  params.client.on(ClientEvent.Sync, (state, prevState, data) => {
81
- params.setCurrentSyncState(state);
82
87
  const error = data && typeof data === "object" && "error" in data ? data.error : void 0;
88
+ params.setCurrentSyncState(state, error);
83
89
  params.emitter.emit("sync.state", state, prevState, error);
84
90
  });
85
91
  params.client.on(ClientEvent.SyncUnexpectedError, (error) => {
@@ -115,89 +121,93 @@ function refreshMatrixDmRoomIds(direct, dmRoomIds) {
115
121
  return true;
116
122
  }
117
123
  //#endregion
118
- //#region extensions/matrix/src/matrix/sdk/client-support.ts
119
- const MATRIX_STATUS_DIAGNOSTIC_TIMEOUT_MS = 1e4;
120
- const DEFAULT_MATRIX_LOCAL_TIMEOUT_MS = 6e4;
121
- function resolveMatrixLocalTimeoutMs(raw) {
122
- if (typeof raw !== "number" || !Number.isFinite(raw)) return DEFAULT_MATRIX_LOCAL_TIMEOUT_MS;
123
- return Math.max(1, Math.floor(raw));
124
+ //#region extensions/matrix/src/matrix/sdk/client-sync-quiesce.ts
125
+ const MATRIX_SYNC_QUIESCE_TIMEOUT_MS = 5e3;
126
+ const MATRIX_JS_SDK_SYNC_VERSION = "41.9.0";
127
+ const matrixJsSdkPackage = createRequire(import.meta.url)("matrix-js-sdk/package.json");
128
+ function requireMatrixClassicSyncInternals(syncApi) {
129
+ return syncApi;
124
130
  }
125
- function unresolvedMatrixRoomKeyBackupStatus() {
126
- return {
127
- serverVersion: null,
128
- activeVersion: null,
129
- trusted: null,
130
- matchesDecryptionKey: null,
131
- decryptionKeyCached: null,
132
- keyLoadAttempted: false,
133
- keyLoadError: null
134
- };
135
- }
136
- function unresolvedMatrixDeviceVerificationStatus(params) {
137
- return {
138
- encryptionEnabled: true,
139
- userId: params.userId,
140
- deviceId: params.deviceId,
141
- verified: false,
142
- localVerified: false,
143
- crossSigningVerified: false,
144
- signedByOwner: false
145
- };
146
- }
147
- async function resolveMatrixDiagnostic(promise, timeoutMs) {
148
- return (await resolveMatrixDiagnosticResult(promise, timeoutMs)).value;
131
+ function assertMatrixJsSdkSyncVersion() {
132
+ const version = matrixJsSdkPackage.version;
133
+ if (version !== MATRIX_JS_SDK_SYNC_VERSION) throw new Error(`Matrix sync quiesce requires matrix-js-sdk ${MATRIX_JS_SDK_SYNC_VERSION}; found ${String(version)}`);
149
134
  }
150
- async function resolveMatrixDiagnosticResult(promise, timeoutMs) {
151
- let timeoutId;
135
+ async function quiesceMatrixClientSync(params) {
136
+ await params.syncStore?.freezeSyncCursorPersistence();
152
137
  try {
153
- const guarded = promise.then((value) => ({
154
- error: null,
155
- timedOut: false,
156
- value
157
- })).catch((error) => ({
158
- error,
159
- timedOut: false,
160
- value: null
161
- }));
162
- const timeout = new Promise((resolve) => {
163
- timeoutId = setTimeout(() => resolve({
164
- error: null,
165
- timedOut: true,
166
- value: null
167
- }), timeoutMs);
168
- timeoutId.unref?.();
169
- });
170
- return await Promise.race([guarded, timeout]);
171
- } finally {
172
- if (timeoutId) clearTimeout(timeoutId);
138
+ assertMatrixJsSdkSyncVersion();
139
+ } catch (error) {
140
+ params.syncStore?.discardPendingSyncCursorPersistence();
141
+ throw error;
142
+ }
143
+ const syncApi = params.client.syncApi;
144
+ if (syncApi === void 0 && !params.started) return;
145
+ if (!(syncApi instanceof SyncApi)) {
146
+ params.syncStore?.discardPendingSyncCursorPersistence();
147
+ throw new Error(syncApi === void 0 ? "Matrix sync quiesce requires the classic matrix-js-sdk SyncApi, but none is active" : "Matrix sync quiesce rejected a sliding or unknown matrix-js-sdk sync implementation");
148
+ }
149
+ const syncState = syncApi.getSyncState();
150
+ if (syncState === SyncState.Stopped) {
151
+ params.markStopped();
152
+ return;
173
153
  }
154
+ const disconnectedBeforeStop = syncState === SyncState.Error || syncState === SyncState.Reconnecting;
155
+ const syncInternals = requireMatrixClassicSyncInternals(syncApi);
156
+ const keepaliveResolvers = disconnectedBeforeStop ? syncInternals.connectionReturnedResolvers : void 0;
157
+ await new Promise((resolve, reject) => {
158
+ let settled = false;
159
+ const settle = (error) => {
160
+ if (settled) return;
161
+ settled = true;
162
+ clearTimeout(timeout);
163
+ params.emitter.off("sync.state", onSyncState);
164
+ if (error) reject(error);
165
+ else {
166
+ params.markStopped();
167
+ resolve();
168
+ }
169
+ };
170
+ const onSyncState = (state) => {
171
+ if (state === "STOPPED") settle();
172
+ };
173
+ const timeout = setTimeout(() => {
174
+ params.syncStore?.discardPendingSyncCursorPersistence();
175
+ settle(/* @__PURE__ */ new Error(`Matrix classic sync did not reach STOPPED within 5000ms`));
176
+ }, MATRIX_SYNC_QUIESCE_TIMEOUT_MS);
177
+ timeout.unref?.();
178
+ params.emitter.on("sync.state", onSyncState);
179
+ try {
180
+ syncApi.stop();
181
+ if (keepaliveResolvers && syncInternals.connectionReturnedResolvers === keepaliveResolvers) {
182
+ syncInternals.connectionReturnedResolvers = void 0;
183
+ keepaliveResolvers.reject("SyncApi.stop() was called");
184
+ settle();
185
+ }
186
+ } catch (error) {
187
+ params.syncStore?.discardPendingSyncCursorPersistence();
188
+ settle(error instanceof Error ? error : new Error(String(error)));
189
+ }
190
+ });
174
191
  }
175
- function isMatrixAccessTokenInvalidatedError(error) {
176
- if (!error || typeof error !== "object") return false;
177
- const err = error;
178
- const errcode = err.body?.errcode ?? err.data?.errcode;
179
- if (err.statusCode === 401 && errcode === "M_UNKNOWN_TOKEN") return true;
180
- const reason = formatMatrixErrorReason(error);
181
- return reason.includes("m_unknown_token") || reason.includes("unknown token") || reason.includes("access token") && (reason.includes("invalid") || reason.includes("unrecognized") || reason.includes("unknown"));
182
- }
183
- const MATRIX_INITIAL_CRYPTO_BOOTSTRAP_OPTIONS = { allowAutomaticCrossSigningReset: false };
184
- const MATRIX_AUTOMATIC_REPAIR_BOOTSTRAP_OPTIONS = {
185
- forceResetCrossSigning: true,
186
- allowSecretStorageRecreateWithoutRecoveryKey: true,
187
- strict: true
188
- };
189
- function createMatrixExplicitBootstrapOptions(params) {
192
+ //#endregion
193
+ //#region extensions/matrix/src/matrix/sdk/client-base.ts
194
+ function resolveMessageWireDispatch(resource, init) {
195
+ if ((init?.method ?? (resource instanceof Request ? resource.method : "GET")).toUpperCase() !== "PUT") return null;
196
+ const rawUrl = typeof resource === "string" ? resource : resource instanceof URL ? resource.href : resource.url;
197
+ const segments = new URL(rawUrl).pathname.split("/").filter(Boolean);
198
+ const roomsIndex = segments.lastIndexOf("rooms");
199
+ if (roomsIndex < 0 || segments[roomsIndex + 2] !== "send" || segments.length !== roomsIndex + 5) return null;
200
+ const eventType = decodeURIComponent(segments[roomsIndex + 3] ?? "");
201
+ if (eventType !== "m.room.message" && eventType !== "m.room.encrypted") return null;
190
202
  return {
191
- forceResetCrossSigning: params?.forceResetCrossSigning === true,
192
- allowAutomaticCrossSigningReset: params?.allowAutomaticCrossSigningReset !== false,
193
- allowSecretStorageRecreateWithoutRecoveryKey: true,
194
- strict: params?.strict !== false
203
+ roomId: decodeURIComponent(segments[roomsIndex + 1] ?? ""),
204
+ eventType,
205
+ transactionId: decodeURIComponent(segments[roomsIndex + 4] ?? ""),
206
+ requestPath: new URL(rawUrl).pathname
195
207
  };
196
208
  }
197
- //#endregion
198
- //#region extensions/matrix/src/matrix/sdk/client-base.ts
199
209
  let loadedMatrixCryptoRuntime = null;
200
- const loadMatrixCryptoRuntime = createLazyRuntimeModule(() => import("./crypto-runtime-D9_6J5tZ.js").then((runtime) => {
210
+ const loadMatrixCryptoRuntime = createLazyRuntimeModule(() => import("./crypto-runtime-Bnz3zEcS.js").then((runtime) => {
201
211
  loadedMatrixCryptoRuntime = runtime;
202
212
  return runtime;
203
213
  }));
@@ -210,9 +220,15 @@ var MatrixClientBase = class {
210
220
  this.dmRoomIds = /* @__PURE__ */ new Set();
211
221
  this.cryptoInitialized = false;
212
222
  this.sendQueue = new KeyedAsyncQueue();
223
+ this.syncQuiescePromise = null;
213
224
  this.stopPersistPromise = null;
214
225
  this.verificationSummaryListenerBound = false;
215
226
  this.currentSyncState = null;
227
+ this.currentSyncError = void 0;
228
+ this.transactionScopeId = null;
229
+ this.transactionScopePromise = null;
230
+ this.messageWireDispatchGuards = /* @__PURE__ */ new Map();
231
+ this.sdkStopped = false;
216
232
  this.dms = {
217
233
  update: async () => {
218
234
  return await this.refreshDmCache();
@@ -220,6 +236,9 @@ var MatrixClientBase = class {
220
236
  isDm: (roomId) => this.dmRoomIds.has(roomId)
221
237
  };
222
238
  this.idbPersistTimer = null;
239
+ this.transactionScopeHomeserver = homeserver;
240
+ this.transactionScopeAccessTokenHash = createHash("sha256").update(accessToken).digest("hex");
241
+ this.transactionScopeDeviceId = opts.deviceId?.trim() || null;
223
242
  this.httpClient = new MatrixAuthedHttpClient({
224
243
  homeserver,
225
244
  accessToken,
@@ -239,6 +258,10 @@ var MatrixClientBase = class {
239
258
  this.autoBootstrapCrypto = opts.autoBootstrapCrypto !== false;
240
259
  this.recoveryKeyStore = new MatrixRecoveryKeyStore(opts.recoveryKeyPath);
241
260
  const cryptoCallbacks = this.encryptionEnabled ? this.recoveryKeyStore.buildCryptoCallbacks() : void 0;
261
+ const guardedFetch = createMatrixGuardedFetch({
262
+ ssrfPolicy: opts.ssrfPolicy,
263
+ dispatcherPolicy: opts.dispatcherPolicy
264
+ });
242
265
  this.client = createClient({
243
266
  baseUrl: homeserver,
244
267
  accessToken,
@@ -246,9 +269,10 @@ var MatrixClientBase = class {
246
269
  deviceId: opts.deviceId,
247
270
  logger: createMatrixJsSdkClientLogger("MatrixClient"),
248
271
  localTimeoutMs: this.localTimeoutMs,
249
- fetchFn: createMatrixGuardedFetch({
250
- ssrfPolicy: opts.ssrfPolicy,
251
- dispatcherPolicy: opts.dispatcherPolicy
272
+ fetchFn: (async (resource, init) => {
273
+ const dispatch = resolveMessageWireDispatch(resource, init);
274
+ if (dispatch) await this.messageWireDispatchGuards.get(dispatch.transactionId)?.(dispatch);
275
+ return await guardedFetch(resource, init);
252
276
  }),
253
277
  store: this.syncStore,
254
278
  cryptoCallbacks,
@@ -260,6 +284,16 @@ var MatrixClientBase = class {
260
284
  ]
261
285
  });
262
286
  }
287
+ async withMessageWireDispatchGuard(params) {
288
+ if (!params.transactionId || !params.guard) return await params.run();
289
+ if (this.messageWireDispatchGuards.has(params.transactionId)) throw new Error(`Matrix transaction ${params.transactionId} already has a dispatch guard`);
290
+ this.messageWireDispatchGuards.set(params.transactionId, params.guard);
291
+ try {
292
+ return await params.run();
293
+ } finally {
294
+ this.messageWireDispatchGuards.delete(params.transactionId);
295
+ }
296
+ }
263
297
  on(eventName, listener) {
264
298
  this.emitter.on(eventName, listener);
265
299
  return this;
@@ -314,7 +348,7 @@ var MatrixClientBase = class {
314
348
  client: this.client,
315
349
  verificationManager: this.verificationManager,
316
350
  recoveryKeyStore: this.recoveryKeyStore,
317
- getRoomStateEvent: (roomId, eventType, stateKey = "") => this.getRoomStateEvent(roomId, eventType, stateKey),
351
+ isRoomEncrypted: async (roomId) => await this.getMessageWireEventType(roomId) === "m.room.encrypted",
318
352
  downloadContent: (mxcUrl, opts) => this.downloadContent(mxcUrl, opts)
319
353
  });
320
354
  if (!this.verificationSummaryListenerBound) {
@@ -334,6 +368,7 @@ var MatrixClientBase = class {
334
368
  async waitForInitialSyncReady(params = {}) {
335
369
  const timeoutMs = params.timeoutMs ?? 3e4;
336
370
  if (isMatrixReadySyncState(this.currentSyncState)) return;
371
+ if (isMatrixAccessTokenInvalidatedError(this.currentSyncError)) throw this.currentSyncError instanceof Error ? this.currentSyncError : new Error("Matrix access token invalidated", { cause: this.currentSyncError });
337
372
  if (isMatrixTerminalSyncState(this.currentSyncState)) throw new Error(`Matrix sync entered ${this.currentSyncState} during startup`);
338
373
  await new Promise((resolve, reject) => {
339
374
  let settled = false;
@@ -365,6 +400,10 @@ var MatrixClientBase = class {
365
400
  settleResolve();
366
401
  return;
367
402
  }
403
+ if (isMatrixAccessTokenInvalidatedError(error)) {
404
+ settleReject(error instanceof Error ? error : /* @__PURE__ */ new Error("Matrix access token invalidated"));
405
+ return;
406
+ }
368
407
  if (isMatrixTerminalSyncState(state)) settleReject(new Error(error instanceof Error && error.message ? error.message : `Matrix sync entered ${state} during startup`));
369
408
  };
370
409
  const onUnexpectedError = (error) => {
@@ -388,6 +427,7 @@ var MatrixClientBase = class {
388
427
  }
389
428
  async startSyncSession(opts) {
390
429
  if (this.started) return;
430
+ if (this.sdkStopped) throw new Error("Matrix client has been fully stopped and cannot be restarted; acquire a new shared client generation");
391
431
  throwIfMatrixStartupAborted(opts.abortSignal);
392
432
  await this.ensureCryptoSupportInitialized();
393
433
  throwIfMatrixStartupAborted(opts.abortSignal);
@@ -425,43 +465,58 @@ var MatrixClientBase = class {
425
465
  if (this.started) return;
426
466
  await this.startSyncSession({ bootstrapCrypto: false });
427
467
  }
428
- stopSyncWithoutPersist() {
468
+ stopSdkClient() {
469
+ if (this.sdkStopped) return;
429
470
  if (this.idbPersistTimer) {
430
471
  clearInterval(this.idbPersistTimer);
431
472
  this.idbPersistTimer = null;
432
473
  }
433
474
  this.currentSyncState = null;
475
+ this.currentSyncError = void 0;
434
476
  this.client.stopClient();
477
+ this.sdkStopped = true;
435
478
  this.started = false;
436
479
  }
480
+ async quiesceSync() {
481
+ this.syncQuiescePromise ??= quiesceMatrixClientSync({
482
+ client: this.client,
483
+ emitter: this.emitter,
484
+ markStopped: () => {
485
+ this.started = false;
486
+ },
487
+ started: this.started,
488
+ syncStore: this.syncStore
489
+ });
490
+ await this.syncQuiescePromise;
491
+ }
437
492
  async drainPendingDecryptions(reason = "matrix client shutdown") {
438
493
  await this.decryptBridge?.drainPendingDecryptions(reason);
439
494
  }
440
495
  stop() {
441
- this.stopSyncWithoutPersist();
442
- this.decryptBridge?.stop();
443
- this.syncStore?.markCleanShutdown();
444
- if (loadedMatrixCryptoRuntime) {
445
- const { persistIdbToDisk } = loadedMatrixCryptoRuntime;
446
- this.stopPersistPromise = Promise.all([persistIdbToDisk({
447
- snapshotPath: this.idbSnapshotPath,
448
- databasePrefix: this.cryptoDatabasePrefix
449
- }).catch(noop), this.syncStore?.flush().catch(noop)]).then(() => void 0);
496
+ this.stopAndPersist().catch(() => this.stopWithoutPersist()).catch(noop);
497
+ }
498
+ async stopAndPersist() {
499
+ if (this.stopPersistPromise) {
500
+ await this.stopPersistPromise;
450
501
  return;
451
502
  }
452
- this.stopPersistPromise = loadMatrixCryptoRuntime().then(async ({ persistIdbToDisk }) => {
453
- await Promise.all([persistIdbToDisk({
503
+ this.stopPersistPromise = (async () => {
504
+ await this.quiesceSync();
505
+ this.stopSdkClient();
506
+ this.decryptBridge?.stop();
507
+ await (loadedMatrixCryptoRuntime ?? await loadMatrixCryptoRuntime()).persistIdbToDisk({
454
508
  snapshotPath: this.idbSnapshotPath,
455
- databasePrefix: this.cryptoDatabasePrefix
456
- }).catch(noop), this.syncStore?.flush().catch(noop)]);
457
- }).catch(noop).then(() => void 0);
458
- }
459
- async stopAndPersist() {
460
- this.stop();
509
+ databasePrefix: this.cryptoDatabasePrefix,
510
+ strict: true
511
+ });
512
+ this.syncStore?.markCleanShutdown();
513
+ await this.syncStore?.flush();
514
+ })();
461
515
  await this.stopPersistPromise;
462
516
  }
463
517
  stopWithoutPersist() {
464
- this.stopSyncWithoutPersist();
518
+ this.syncStore?.discardPendingSyncCursorPersistence();
519
+ this.stopSdkClient();
465
520
  this.decryptBridge?.stop();
466
521
  this.stopPersistPromise = Promise.resolve();
467
522
  }
@@ -537,6 +592,30 @@ var MatrixClientCore = class extends MatrixClientBase {
537
592
  const joined = await this.doRequest("GET", "/_matrix/client/v3/joined_rooms");
538
593
  return Array.isArray(joined.joined_rooms) ? joined.joined_rooms : [];
539
594
  }
595
+ async getTransactionScopeId() {
596
+ if (this.transactionScopeId) return this.transactionScopeId;
597
+ const active = this.transactionScopePromise ?? (async () => {
598
+ const configuredUserId = this.client.getUserId()?.trim() || this.selfUserId;
599
+ const configuredDeviceId = this.transactionScopeDeviceId || this.client.getDeviceId()?.trim() || null;
600
+ const whoami = await this.doRequest("GET", "/_matrix/client/v3/account/whoami");
601
+ const userId = whoami.user_id?.trim() || null;
602
+ const deviceId = whoami.device_id?.trim() || null;
603
+ if (!userId) throw new Error("Matrix whoami did not return user_id");
604
+ if (configuredUserId && configuredUserId !== userId) throw new Error("Matrix access token user does not match the configured userId");
605
+ if (configuredDeviceId && deviceId && configuredDeviceId !== deviceId) throw new Error("Matrix access token device does not match the configured deviceId");
606
+ this.selfUserId = userId;
607
+ this.transactionScopeDeviceId = deviceId;
608
+ return createHash("sha256").update(this.transactionScopeHomeserver).update("\0").update(userId).update("\0").update(deviceId ?? "").update("\0").update(this.transactionScopeAccessTokenHash).digest("hex");
609
+ })();
610
+ this.transactionScopePromise = active;
611
+ try {
612
+ const resolved = await active;
613
+ this.transactionScopeId = resolved;
614
+ return resolved;
615
+ } finally {
616
+ if (this.transactionScopePromise === active) this.transactionScopePromise = null;
617
+ }
618
+ }
540
619
  async getJoinedRoomMembers(roomId) {
541
620
  const joined = (await this.client.getJoinedRoomMembers(roomId))?.joined;
542
621
  if (!joined || typeof joined !== "object") return [];
@@ -577,13 +656,56 @@ var MatrixClientCore = class extends MatrixClientBase {
577
656
  initial_state: initialState
578
657
  })).room_id;
579
658
  }
580
- async sendMessage(roomId, content) {
659
+ async sendMessage(roomId, content, transactionId, beforeWireDispatch) {
581
660
  return await this.runSerializedRoomSend(roomId, async () => {
582
- return (await this.client.sendMessage(roomId, content)).event_id;
661
+ return await this.withMessageWireDispatchGuard({
662
+ transactionId,
663
+ guard: beforeWireDispatch,
664
+ run: async () => {
665
+ if (transactionId) {
666
+ const room = this.client.getRoom(roomId);
667
+ const existing = room?.getEventForTxnId?.(transactionId);
668
+ if (existing) {
669
+ const existingId = existing.getId();
670
+ if (existing.status === EventStatus.SENT && existingId && !existingId.startsWith("~")) return existingId;
671
+ if (existing.status === EventStatus.NOT_SENT && room) {
672
+ await this.prepareRoomForMessageSend(roomId, existing.getContent());
673
+ return (await this.client.resendEvent(existing, room)).event_id;
674
+ }
675
+ throw new Error(`Matrix transaction ${transactionId} is already active with status ${existing.status ?? "unknown"}`);
676
+ }
677
+ }
678
+ await this.prepareRoomForMessageSend(roomId, content);
679
+ return (await this.client.sendMessage(roomId, content, transactionId)).event_id;
680
+ }
681
+ });
583
682
  });
584
683
  }
684
+ async getMessageWireEventType(roomId) {
685
+ if (this.client.getRoom(roomId)?.hasEncryptionStateEvent() === true) return "m.room.encrypted";
686
+ const crypto = this.client.getCrypto();
687
+ if (crypto && await crypto.isEncryptionEnabledInRoom(roomId)) return "m.room.encrypted";
688
+ try {
689
+ await this.getRoomStateEvent(roomId, "m.room.encryption", "");
690
+ return "m.room.encrypted";
691
+ } catch (error) {
692
+ if (error instanceof MatrixError && error.httpStatus === 404 && error.errcode === "M_NOT_FOUND") return "m.room.message";
693
+ throw error;
694
+ }
695
+ }
696
+ async prepareRoomForMessageSend(roomId, content) {
697
+ if (await this.getMessageWireEventType(roomId) === "m.room.message") return "m.room.message";
698
+ const crypto = this.client.getCrypto();
699
+ if (!crypto) throw new Error("Encrypted Matrix room: enable encryption before sending messages");
700
+ const room = this.client.getRoom(roomId);
701
+ if (!room || !room.hasEncryptionStateEvent() && !await crypto.isEncryptionEnabledInRoom(roomId)) throw new Error("Encrypted Matrix room is not ready: wait for room sync before sending");
702
+ if (content && ((content.msgtype === MsgType.Image || content.msgtype === MsgType.Audio || content.msgtype === MsgType.Video || content.msgtype === MsgType.File) && typeof content.url === "string" || content.info && "thumbnail_url" in content.info && typeof content.info.thumbnail_url === "string")) throw new Error("Encrypted Matrix room contains unencrypted media; retry the send");
703
+ return "m.room.encrypted";
704
+ }
585
705
  async sendEvent(roomId, eventType, content) {
586
706
  return await this.runSerializedRoomSend(roomId, async () => {
707
+ if (eventType === EventType.RoomMessageEncrypted.toString() || eventType === EventType.RoomRedaction.toString()) throw new Error(eventType === EventType.RoomRedaction.toString() ? "Matrix redaction wire events must use redactEvent" : "Matrix encrypted wire events must be generated by the SDK");
708
+ if (eventType !== "m.reaction") await this.prepareRoomForMessageSend(roomId, content);
587
709
  return (await this.client.sendEvent(roomId, eventType, content)).event_id;
588
710
  });
589
711
  }
@@ -698,7 +820,7 @@ var MatrixClientCore = class extends MatrixClientBase {
698
820
  };
699
821
  //#endregion
700
822
  //#region extensions/matrix/src/matrix/sdk/client-verification.ts
701
- const normalizeOptionalString$1 = normalizeNullableString;
823
+ const normalizeNullableVerificationString = normalizeNullableString;
702
824
  var MatrixClientVerification = class extends MatrixClientCore {
703
825
  async getRoomKeyBackupStatus() {
704
826
  if (!this.encryptionEnabled) return {
@@ -733,7 +855,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
733
855
  try {
734
856
  await crypto.loadSessionBackupPrivateKeyFromSecretStorage();
735
857
  } catch (err) {
736
- keyLoadError = formatMatrixErrorMessage(err);
858
+ keyLoadError = formatErrorMessage(err);
737
859
  }
738
860
  } else keyLoadError = "Matrix crypto backend does not support loading backup keys from secret storage";
739
861
  if (!keyLoadError) await this.enableTrustedRoomKeyBackupIfPossible(crypto);
@@ -830,7 +952,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
830
952
  async resolveActiveRoomKeyBackupVersion(crypto) {
831
953
  if (typeof crypto.getActiveSessionBackupVersion !== "function") return null;
832
954
  const version = await crypto.getActiveSessionBackupVersion().catch(() => null);
833
- return normalizeOptionalString$1(version);
955
+ return normalizeNullableVerificationString(version);
834
956
  }
835
957
  async resolveCachedRoomKeyBackupDecryptionKey(crypto) {
836
958
  const read = Reflect.get(crypto, "getSessionBackupPrivateKey");
@@ -862,7 +984,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
862
984
  let matchesDecryptionKey = null;
863
985
  if (typeof crypto.getKeyBackupInfo === "function") {
864
986
  const info = await crypto.getKeyBackupInfo().catch(() => null);
865
- serverVersion = normalizeOptionalString$1(info?.version) ?? serverVersion;
987
+ serverVersion = normalizeNullableVerificationString(info?.version) ?? serverVersion;
866
988
  if (info && typeof crypto.isKeyBackupTrusted === "function") {
867
989
  const trustInfo = await crypto.isKeyBackupTrusted(info).catch(() => null);
868
990
  trusted = typeof trustInfo?.trusted === "boolean" ? trustInfo.trusted : null;
@@ -883,7 +1005,7 @@ var MatrixClientVerification = class extends MatrixClientCore {
883
1005
  async resolveRoomKeyBackupVersion() {
884
1006
  try {
885
1007
  const response = await this.doRequest("GET", "/_matrix/client/v3/room_keys/version");
886
- return normalizeOptionalString$1(response.version);
1008
+ return normalizeNullableVerificationString(response.version);
887
1009
  } catch {
888
1010
  return null;
889
1011
  }
@@ -932,7 +1054,7 @@ var MatrixClient = class extends MatrixClientVerification {
932
1054
  keyId: stagedKeyId
933
1055
  });
934
1056
  } catch (err) {
935
- return await fail(formatMatrixErrorMessage(err));
1057
+ return await fail(formatErrorMessage(err));
936
1058
  }
937
1059
  const storedRecoveryKeyMatches = this.recoveryKeyStore.getRecoveryKeySummary()?.encodedPrivateKey?.trim() === trimmedRecoveryKey;
938
1060
  if (backupUsableBeforeStagedRecovery && storedRecoveryKeyMatches) {
@@ -1033,7 +1155,7 @@ var MatrixClient = class extends MatrixClientVerification {
1033
1155
  };
1034
1156
  } catch (err) {
1035
1157
  this.recoveryKeyStore.discardStagedRecoveryKey();
1036
- return await fail(formatMatrixErrorMessage(err));
1158
+ return await fail(formatErrorMessage(err));
1037
1159
  }
1038
1160
  }
1039
1161
  async restoreRoomKeyBackup(params = {}) {
@@ -1088,7 +1210,7 @@ var MatrixClient = class extends MatrixClientVerification {
1088
1210
  };
1089
1211
  } catch (err) {
1090
1212
  this.recoveryKeyStore.discardStagedRecoveryKey();
1091
- return await fail(formatMatrixErrorMessage(err));
1213
+ return await fail(formatErrorMessage(err));
1092
1214
  }
1093
1215
  }
1094
1216
  async resetRoomKeyBackup(options = {}) {
@@ -1143,7 +1265,7 @@ var MatrixClient = class extends MatrixClientVerification {
1143
1265
  backup
1144
1266
  };
1145
1267
  } catch (err) {
1146
- return await fail(formatMatrixErrorMessage(err));
1268
+ return await fail(formatErrorMessage(err));
1147
1269
  }
1148
1270
  }
1149
1271
  async getOwnCrossSigningPublicationStatus() {
@@ -1185,7 +1307,7 @@ var MatrixClient = class extends MatrixClientVerification {
1185
1307
  await this.ensureRoomKeyBackupEnabled(crypto);
1186
1308
  } catch (err) {
1187
1309
  this.recoveryKeyStore.discardStagedRecoveryKey();
1188
- bootstrapError = formatMatrixErrorMessage(err);
1310
+ bootstrapError = formatErrorMessage(err);
1189
1311
  }
1190
1312
  const verification = await this.getOwnDeviceVerificationStatus();
1191
1313
  const crossSigning = await this.getOwnCrossSigningPublicationStatus();
@@ -1249,8 +1371,9 @@ var MatrixClient = class extends MatrixClientVerification {
1249
1371
  emitter: this.emitter,
1250
1372
  emitMembershipForRoom: (room) => this.emitMembershipForRoom(room),
1251
1373
  getSelfUserId: () => this.client.getUserId() ?? this.selfUserId ?? "",
1252
- setCurrentSyncState: (state) => {
1374
+ setCurrentSyncState: (state, error) => {
1253
1375
  this.currentSyncState = state;
1376
+ this.currentSyncError = error;
1254
1377
  }
1255
1378
  });
1256
1379
  }
@@ -1,4 +1,4 @@
1
- import { t as getMatrixScopedEnvVarNames } from "./env-vars-B0NxQnPk.js";
1
+ import { t as getMatrixScopedEnvVarNames } from "./env-vars-dGqak9dN.js";
2
2
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
3
  import { collectSecretInputAssignment, createChannelSecretTargetRegistryEntries, getChannelSurface, hasConfiguredSecretInputValue, hasOwnProperty, normalizeSecretStringValue } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
4
4
  //#region extensions/matrix/src/secret-contract.ts
@@ -1,2 +1,2 @@
1
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-M3hRmGO-.js";
1
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-CufozuyJ.js";
2
2
  export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };