@openclaw/matrix 2026.6.5-beta.2 → 2026.6.5-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 (65) hide show
  1. package/dist/{account-selection-DEMtY2cn.js → account-selection-Bv_ZuOu4.js} +2 -3
  2. package/dist/api.js +5 -5
  3. package/dist/{approval-handler.runtime-DBUlR5vu.js → approval-handler.runtime-D88ERXxc.js} +4 -4
  4. package/dist/{approval-ids-BWuh0wZT.js → approval-ids-B2J320aL.js} +1 -1
  5. package/dist/{approval-reaction-auth-NgDjrK6V.js → approval-reaction-auth-ryklScll.js} +2 -2
  6. package/dist/{channel-6UUus7Ba.js → channel-DtT1oc4C.js} +13 -13
  7. package/dist/channel-plugin-api.js +1 -1
  8. package/dist/{channel.runtime-CPXd3XKs.js → channel.runtime-CoCkSJV6.js} +6 -6
  9. package/dist/{cli-CM0h-B_j.js → cli-BX7_GgmS.js} +10 -10
  10. package/dist/{cli-metadata-CW6xSM2K.js → cli-metadata-C9_um_Yj.js} +1 -1
  11. package/dist/cli-metadata.js +1 -1
  12. package/dist/{client-CdP9vWOu.js → client-CPfb6TMG.js} +2 -2
  13. package/dist/{client-bootstrap-D5vrHEms.js → client-bootstrap-Dj2242_Y.js} +1 -1
  14. package/dist/{client-DRRL7Zv5.js → client-dLfa0qNk.js} +2 -2
  15. package/dist/{config-schema-CVJYP50t.js → config-schema-NrB2XGxM.js} +1 -1
  16. package/dist/contract-api.js +4 -4
  17. package/dist/{create-client-B90Sb7LG.js → create-client-MnSzqELZ.js} +4 -4
  18. package/dist/{credentials-Bi0pTJDK.js → credentials-G8lNmiME.js} +1 -1
  19. package/dist/{credentials-read-DpxFOhx0.js → credentials-read-TzTOQPOM.js} +1 -1
  20. package/dist/{credentials-write.runtime-BB5QuM4Z.js → credentials-write.runtime-cZhhyGAZ.js} +1 -1
  21. package/dist/{crypto-runtime-DWVNNqa3.js → crypto-runtime-B4WWNpMk.js} +4 -174
  22. package/dist/crypto-state-store-DK2tcEyP.js +352 -0
  23. package/dist/{directory-live-5uWtLQ41.js → directory-live-C7aYHtRU.js} +2 -2
  24. package/dist/{doctor-BKjr6uua.js → doctor-BwpkOBwr.js} +5 -5
  25. package/dist/{doctor-contract-D9oKDvsJ.js → doctor-contract-Dq8OZWHF.js} +1 -1
  26. package/dist/doctor-contract-api.js +265 -2
  27. package/dist/{draft-stream-DZ2X1RHP.js → draft-stream-PqFfvyV9.js} +1 -1
  28. package/dist/{encryption-guidance-aEUzD940.js → encryption-guidance-D_KhjprO.js} +1 -1
  29. package/dist/file-sync-store-Ni-pkFde.js +402 -0
  30. package/dist/helper-api.js +1 -1
  31. package/dist/idb-persistence-BGY1CJ7J.js +229 -0
  32. package/dist/idb-persistence-lock-DAJ49nZX.js +32 -0
  33. package/dist/index.js +1 -1
  34. package/dist/{legacy-crypto-restore-CbVSppMd.js → legacy-crypto-restore-Bm6HmeN5.js} +36 -28
  35. package/dist/logger-D0GCSDQq.js +78 -0
  36. package/dist/{logging-Cm8vxO3E.js → logging-QH-48Gr6.js} +1 -1
  37. package/dist/{matrix-migration.runtime-RzIEp7RP.js → matrix-migration.runtime-dvxE3e5l.js} +24 -25
  38. package/dist/{media-text-DVhXN81h.js → media-text-D0uvrHo1.js} +1 -1
  39. package/dist/{messages-sk1eTx7H.js → messages-C00n-MG_.js} +3 -3
  40. package/dist/{monitor-DXW0sFfU.js → monitor-BWHn9jy2.js} +21 -19
  41. package/dist/plugin-entry.handlers.runtime.js +1 -1
  42. package/dist/probe.runtime-DcSBLSet.js +3 -0
  43. package/dist/{profile-update-rzynJvpi.js → profile-update-CWvjc5i_.js} +2 -2
  44. package/dist/{reaction-events-DRKzlo8q.js → reaction-events-CdkYjlyo.js} +1 -1
  45. package/dist/{recovery-key-store-D6RbiZMM.js → recovery-key-store-TSlOpcEG.js} +22 -53
  46. package/dist/{resolve-targets-CAwsoBQK.js → resolve-targets-0dT0vJZJ.js} +1 -1
  47. package/dist/{resolver.runtime-phS2hwm9.js → resolver.runtime-BD2ZRhKw.js} +1 -1
  48. package/dist/runtime-api.js +1 -1
  49. package/dist/runtime-heavy-api.js +1 -1
  50. package/dist/{sdk-BdCZ5WwA.js → sdk-CdMhAFz3.js} +9 -202
  51. package/dist/{send-DEgWxp1p.js → send-Bus9xhUh.js} +1 -1
  52. package/dist/{setup-bootstrap-B4xc58Ww.js → setup-bootstrap-C9tUX9Ty.js} +2 -2
  53. package/dist/{setup-core-DJosJdWt.js → setup-core-CUyFBi5x.js} +3 -3
  54. package/dist/setup-plugin-api.js +3 -3
  55. package/dist/{setup-surface-CqxGV1WL.js → setup-surface-BRlTR6to.js} +5 -5
  56. package/dist/{shared-BbT5LdPp.js → shared-Bk7pOHMb.js} +8 -84
  57. package/dist/{startup-verification-D1p_LRmg.js → startup-verification-BoDITB_u.js} +2 -2
  58. package/dist/{storage-DSVcH_zM.js → storage-C10h2piS.js} +122 -26
  59. package/dist/{thread-bindings-gLQYbsB9.js → thread-bindings-CnviJ9Ff.js} +4 -23
  60. package/dist/{tool-actions.runtime-o06m9bgN.js → tool-actions.runtime-dStqVKMT.js} +6 -6
  61. package/dist/{verification-BiA5IWPK.js → verification-jZ1KWtb5.js} +2 -2
  62. package/npm-shrinkwrap.json +3 -3
  63. package/package.json +4 -4
  64. package/dist/probe.runtime-BO0mNIe8.js +0 -3
  65. package/dist/record-shared-CvzjvHRn.js +0 -2
@@ -0,0 +1,352 @@
1
+ import { o as isRecord } from "./account-selection-Bv_ZuOu4.js";
2
+ import { t as getMatrixRuntime } from "./runtime-6S3DNFNv.js";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { createHash, randomUUID } from "node:crypto";
7
+ //#region extensions/matrix/src/matrix/sqlite-state.ts
8
+ function resolveStateDirOverride(options) {
9
+ if (!options) return;
10
+ if (options.stateDir) return options.stateDir;
11
+ if (options.stateRootDir) return options.stateRootDir;
12
+ return getMatrixRuntime().state.resolveStateDir(options.env ?? process.env, os.homedir);
13
+ }
14
+ function resolveMatrixSqliteStateKey(options) {
15
+ return resolveStateDirOverride(options) ?? "";
16
+ }
17
+ function resolveMatrixSqliteStateEnv(options) {
18
+ const stateDir = resolveStateDirOverride(options);
19
+ if (!stateDir) return options?.env;
20
+ return {
21
+ ...options?.env ?? process.env,
22
+ OPENCLAW_STATE_DIR: stateDir
23
+ };
24
+ }
25
+ //#endregion
26
+ //#region extensions/matrix/src/matrix/crypto-state-store.ts
27
+ const STATE_KEY = "current";
28
+ const RECOVERY_KEY_NAMESPACE = "recovery-key";
29
+ const LEGACY_CRYPTO_MIGRATION_NAMESPACE = "legacy-crypto-migration";
30
+ const IDB_SNAPSHOT_NAMESPACE = "idb-snapshot";
31
+ const SMALL_STATE_MAX_ENTRIES = 10;
32
+ const IDB_SNAPSHOT_MAX_ENTRIES = 2e4;
33
+ const IDB_SNAPSHOT_MAX_CHUNKS = Math.floor((IDB_SNAPSHOT_MAX_ENTRIES - 1) / 2);
34
+ const IDB_SNAPSHOT_CHUNK_BYTES = 24e3;
35
+ const MATRIX_RECOVERY_KEY_FILENAME = "recovery-key.json";
36
+ const MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME = "legacy-crypto-migration.json";
37
+ const MATRIX_IDB_SNAPSHOT_FILENAME = "crypto-idb-snapshot.json";
38
+ function openMatrixRecoveryKeyStoreOptions(storageRootDir) {
39
+ return {
40
+ namespace: RECOVERY_KEY_NAMESPACE,
41
+ maxEntries: SMALL_STATE_MAX_ENTRIES,
42
+ env: resolveMatrixSqliteStateEnv({ stateDir: storageRootDir })
43
+ };
44
+ }
45
+ function openMatrixLegacyCryptoMigrationStoreOptions(storageRootDir) {
46
+ return {
47
+ namespace: LEGACY_CRYPTO_MIGRATION_NAMESPACE,
48
+ maxEntries: SMALL_STATE_MAX_ENTRIES,
49
+ env: resolveMatrixSqliteStateEnv({ stateDir: storageRootDir })
50
+ };
51
+ }
52
+ function openMatrixIdbSnapshotStoreOptions(storageRootDir) {
53
+ return {
54
+ namespace: IDB_SNAPSHOT_NAMESPACE,
55
+ maxEntries: IDB_SNAPSHOT_MAX_ENTRIES,
56
+ env: resolveMatrixSqliteStateEnv({ stateDir: storageRootDir })
57
+ };
58
+ }
59
+ function readMatrixRecoveryKeyState(storageRootDir) {
60
+ return readMatrixRecoveryKeyStateWithKey({
61
+ storageRootDir,
62
+ stateKey: STATE_KEY
63
+ });
64
+ }
65
+ function readMatrixRecoveryKeyStateForPath(recoveryKeyPath) {
66
+ return readMatrixRecoveryKeyStateWithKey({
67
+ storageRootDir: path.dirname(recoveryKeyPath),
68
+ stateKey: resolveRecoveryKeyStateKeyForPath(recoveryKeyPath)
69
+ });
70
+ }
71
+ function readMatrixRecoveryKeyStateWithKey(params) {
72
+ return normalizeMatrixStoredRecoveryKey(openSyncStore(openMatrixRecoveryKeyStoreOptions(params.storageRootDir)).lookup(params.stateKey));
73
+ }
74
+ function writeMatrixRecoveryKeyState(params) {
75
+ writeMatrixRecoveryKeyStateWithKey({
76
+ storageRootDir: params.storageRootDir,
77
+ stateKey: STATE_KEY,
78
+ payload: params.payload
79
+ });
80
+ }
81
+ function writeMatrixRecoveryKeyStateForPath(params) {
82
+ writeMatrixRecoveryKeyStateWithKey({
83
+ storageRootDir: path.dirname(params.recoveryKeyPath),
84
+ stateKey: resolveRecoveryKeyStateKeyForPath(params.recoveryKeyPath),
85
+ payload: params.payload
86
+ });
87
+ }
88
+ function writeMatrixRecoveryKeyStateWithKey(params) {
89
+ const payload = normalizeMatrixStoredRecoveryKey(params.payload);
90
+ if (!payload) throw new Error("Invalid Matrix recovery key state");
91
+ openSyncStore(openMatrixRecoveryKeyStoreOptions(params.storageRootDir)).register(params.stateKey, payload);
92
+ }
93
+ async function hasMatrixRecoveryKeyStateInStore(params) {
94
+ return normalizeMatrixStoredRecoveryKey(await params.store.lookup(STATE_KEY)) !== null;
95
+ }
96
+ async function writeMatrixRecoveryKeyStateToStore(params) {
97
+ const payload = normalizeMatrixStoredRecoveryKey(params.payload);
98
+ if (!payload) throw new Error("Invalid Matrix recovery key state");
99
+ await params.store.register(STATE_KEY, payload);
100
+ }
101
+ function readMatrixLegacyCryptoMigrationState(storageRootDir) {
102
+ return normalizeMatrixLegacyCryptoMigrationState(openSyncStore(openMatrixLegacyCryptoMigrationStoreOptions(storageRootDir)).lookup(STATE_KEY));
103
+ }
104
+ function writeMatrixLegacyCryptoMigrationState(params) {
105
+ const state = normalizeMatrixLegacyCryptoMigrationState(params.state);
106
+ if (!state) throw new Error("Invalid Matrix legacy crypto migration state");
107
+ openSyncStore(openMatrixLegacyCryptoMigrationStoreOptions(params.storageRootDir)).register(STATE_KEY, state);
108
+ }
109
+ async function hasMatrixLegacyCryptoMigrationStateInStore(params) {
110
+ return normalizeMatrixLegacyCryptoMigrationState(await params.store.lookup(STATE_KEY)) !== null;
111
+ }
112
+ async function writeMatrixLegacyCryptoMigrationStateToStore(params) {
113
+ const state = normalizeMatrixLegacyCryptoMigrationState(params.state);
114
+ if (!state) throw new Error("Invalid Matrix legacy crypto migration state");
115
+ await params.store.register(STATE_KEY, state);
116
+ }
117
+ function readMatrixIdbSnapshotJson(storageRootDir) {
118
+ return readIdbSnapshotJsonFromStore(openSyncStore(openMatrixIdbSnapshotStoreOptions(storageRootDir)));
119
+ }
120
+ function hasMatrixIdbSnapshotState(storageRootDir) {
121
+ return isIdbSnapshotMeta(openSyncStore(openMatrixIdbSnapshotStoreOptions(storageRootDir)).lookup(idbMetaKey()));
122
+ }
123
+ function writeMatrixIdbSnapshotJson(params) {
124
+ writeIdbSnapshotJsonToStore({
125
+ snapshotJson: params.snapshotJson,
126
+ databaseCount: params.databaseCount,
127
+ store: openSyncStore(openMatrixIdbSnapshotStoreOptions(params.storageRootDir))
128
+ });
129
+ }
130
+ async function hasMatrixIdbSnapshotStateInStore(params) {
131
+ return await readIdbSnapshotJsonFromAsyncStore(params.store) !== null;
132
+ }
133
+ async function writeMatrixIdbSnapshotJsonToStore(params) {
134
+ const rows = buildIdbSnapshotRows(params.snapshotJson, params.databaseCount);
135
+ for (const row of rows.chunks) await params.store.register(row.key, row.value);
136
+ await params.store.register(rows.meta.key, rows.meta.value);
137
+ for (const row of await params.store.entries()) if (row.key.startsWith(idbChunkKeyPrefix()) && !rows.nextChunkKeys.has(row.key)) await params.store.delete(row.key);
138
+ }
139
+ function migrateLegacyMatrixRecoveryKeyFileToStore(storageRootDir) {
140
+ return migrateLegacyMatrixRecoveryKeyFilePathToStore(path.join(storageRootDir, MATRIX_RECOVERY_KEY_FILENAME));
141
+ }
142
+ function migrateLegacyMatrixRecoveryKeyFilePathToStore(recoveryKeyPath) {
143
+ const existing = readMatrixRecoveryKeyStateForPath(recoveryKeyPath);
144
+ const legacy = readLegacyMatrixRecoveryKeyFile(recoveryKeyPath);
145
+ if (!existing && legacy) writeMatrixRecoveryKeyStateForPath({
146
+ recoveryKeyPath,
147
+ payload: legacy
148
+ });
149
+ return archiveLegacyStateFileIfPossible(recoveryKeyPath);
150
+ }
151
+ function migrateLegacyMatrixLegacyCryptoMigrationFileToStore(storageRootDir) {
152
+ const existing = readMatrixLegacyCryptoMigrationState(storageRootDir);
153
+ const legacy = readLegacyMatrixLegacyCryptoMigrationState(storageRootDir);
154
+ if (!existing && legacy) writeMatrixLegacyCryptoMigrationState({
155
+ storageRootDir,
156
+ state: legacy
157
+ });
158
+ return archiveLegacyStateFileIfPossible(path.join(storageRootDir, MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME));
159
+ }
160
+ function readLegacyMatrixRecoveryKeyState(storageRootDir) {
161
+ return readLegacyMatrixRecoveryKeyFile(path.join(storageRootDir, MATRIX_RECOVERY_KEY_FILENAME));
162
+ }
163
+ function readLegacyMatrixRecoveryKeyFile(filePath) {
164
+ return readJsonFileSync(filePath, normalizeMatrixStoredRecoveryKey);
165
+ }
166
+ function readLegacyMatrixLegacyCryptoMigrationState(storageRootDir) {
167
+ return readJsonFileSync(path.join(storageRootDir, MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME), normalizeMatrixLegacyCryptoMigrationState);
168
+ }
169
+ function scoreMatrixCryptoStateInStore(storageRootDir) {
170
+ if (!matrixCryptoStateDatabaseExists(storageRootDir)) return 0;
171
+ let score = 0;
172
+ try {
173
+ if (readMatrixLegacyCryptoMigrationState(storageRootDir)) score += 3;
174
+ } catch {}
175
+ try {
176
+ if (readMatrixRecoveryKeyState(storageRootDir)) score += 2;
177
+ } catch {}
178
+ try {
179
+ if (hasMatrixIdbSnapshotState(storageRootDir)) score += 2;
180
+ } catch {}
181
+ return score;
182
+ }
183
+ function matrixCryptoStateDatabaseExists(storageRootDir) {
184
+ return fs.existsSync(path.join(storageRootDir, "state", "openclaw.sqlite"));
185
+ }
186
+ function resolveRecoveryKeyStateKeyForPath(recoveryKeyPath) {
187
+ const basename = path.basename(recoveryKeyPath);
188
+ if (basename === "recovery-key.json") return STATE_KEY;
189
+ return `file:${createHash("sha256").update(basename, "utf8").digest("hex").slice(0, 32)}`;
190
+ }
191
+ function normalizeMatrixStoredRecoveryKey(value) {
192
+ if (!isRecord(value) || value.version !== 1 || typeof value.createdAt !== "string" || typeof value.privateKeyBase64 !== "string" || !value.privateKeyBase64.trim()) return null;
193
+ return {
194
+ version: 1,
195
+ createdAt: value.createdAt,
196
+ keyId: typeof value.keyId === "string" ? value.keyId : null,
197
+ ...typeof value.encodedPrivateKey === "string" ? { encodedPrivateKey: value.encodedPrivateKey } : {},
198
+ privateKeyBase64: value.privateKeyBase64,
199
+ ...isRecord(value.keyInfo) ? { keyInfo: {
200
+ ...value.keyInfo.passphrase !== void 0 ? { passphrase: value.keyInfo.passphrase } : {},
201
+ ...typeof value.keyInfo.name === "string" ? { name: value.keyInfo.name } : {}
202
+ } } : {}
203
+ };
204
+ }
205
+ function normalizeMatrixLegacyCryptoMigrationState(value) {
206
+ if (!isRecord(value) || value.version !== 1 || typeof value.accountId !== "string") return null;
207
+ if (value.restoreStatus !== "pending" && value.restoreStatus !== "completed" && value.restoreStatus !== "manual-action-required") return null;
208
+ const roomKeyCounts = isRecord(value.roomKeyCounts) && typeof value.roomKeyCounts.total === "number" && typeof value.roomKeyCounts.backedUp === "number" ? {
209
+ total: value.roomKeyCounts.total,
210
+ backedUp: value.roomKeyCounts.backedUp
211
+ } : null;
212
+ return {
213
+ version: 1,
214
+ ...value.source === "matrix-bot-sdk-rust" ? { source: value.source } : {},
215
+ accountId: value.accountId,
216
+ ...typeof value.deviceId === "string" || value.deviceId === null ? { deviceId: value.deviceId } : {},
217
+ roomKeyCounts,
218
+ ...typeof value.backupVersion === "string" || value.backupVersion === null ? { backupVersion: value.backupVersion } : {},
219
+ ...typeof value.decryptionKeyImported === "boolean" ? { decryptionKeyImported: value.decryptionKeyImported } : {},
220
+ restoreStatus: value.restoreStatus,
221
+ ...typeof value.detectedAt === "string" ? { detectedAt: value.detectedAt } : {},
222
+ ...typeof value.restoredAt === "string" ? { restoredAt: value.restoredAt } : {},
223
+ ...typeof value.importedCount === "number" ? { importedCount: value.importedCount } : {},
224
+ ...typeof value.totalCount === "number" ? { totalCount: value.totalCount } : {},
225
+ ...typeof value.lastError === "string" || value.lastError === null ? { lastError: value.lastError } : {}
226
+ };
227
+ }
228
+ function openSyncStore(options) {
229
+ return getMatrixRuntime().state.openSyncKeyedStore(options);
230
+ }
231
+ function readJsonFileSync(filePath, normalize) {
232
+ try {
233
+ return normalize(JSON.parse(fs.readFileSync(filePath, "utf8")));
234
+ } catch {
235
+ return null;
236
+ }
237
+ }
238
+ function archiveLegacyStateFileIfPossible(filePath) {
239
+ if (!fs.existsSync(filePath)) return false;
240
+ const archivedPath = `${filePath}.migrated`;
241
+ if (fs.existsSync(archivedPath)) return false;
242
+ fs.renameSync(filePath, archivedPath);
243
+ return true;
244
+ }
245
+ function readIdbSnapshotJsonFromStore(store) {
246
+ const meta = store.lookup(idbMetaKey());
247
+ if (!isIdbSnapshotMeta(meta)) return null;
248
+ const chunks = readIdbSnapshotChunks(meta, (key) => store.lookup(key));
249
+ return chunks ? chunks.join("") : null;
250
+ }
251
+ async function readIdbSnapshotJsonFromAsyncStore(store) {
252
+ const meta = await store.lookup(idbMetaKey());
253
+ if (!isIdbSnapshotMeta(meta)) return null;
254
+ const chunks = await readIdbSnapshotChunksAsync(meta, (key) => store.lookup(key));
255
+ return chunks ? chunks.join("") : null;
256
+ }
257
+ function readIdbSnapshotChunks(meta, lookup) {
258
+ const chunks = [];
259
+ for (let index = 0; index < meta.chunkCount; index += 1) {
260
+ const chunk = lookup(idbChunkKey(meta.generation, index));
261
+ if (!isIdbSnapshotChunk(chunk) || chunk.index !== index) return null;
262
+ chunks.push(chunk.data);
263
+ }
264
+ const snapshotJson = chunks.join("");
265
+ if (meta.digest !== digestText(snapshotJson)) return null;
266
+ return chunks;
267
+ }
268
+ async function readIdbSnapshotChunksAsync(meta, lookup) {
269
+ const chunks = [];
270
+ for (let index = 0; index < meta.chunkCount; index += 1) {
271
+ const chunk = await lookup(idbChunkKey(meta.generation, index));
272
+ if (!isIdbSnapshotChunk(chunk) || chunk.index !== index) return null;
273
+ chunks.push(chunk.data);
274
+ }
275
+ const snapshotJson = chunks.join("");
276
+ if (meta.digest !== digestText(snapshotJson)) return null;
277
+ return chunks;
278
+ }
279
+ function writeIdbSnapshotJsonToStore(params) {
280
+ const rows = buildIdbSnapshotRows(params.snapshotJson, params.databaseCount);
281
+ for (const row of rows.chunks) params.store.register(row.key, row.value);
282
+ params.store.register(rows.meta.key, rows.meta.value);
283
+ for (const row of params.store.entries()) if (row.key.startsWith(idbChunkKeyPrefix()) && !rows.nextChunkKeys.has(row.key)) params.store.delete(row.key);
284
+ }
285
+ function buildIdbSnapshotRows(snapshotJson, databaseCount) {
286
+ const generation = randomUUID().replaceAll("-", "");
287
+ const chunks = chunkText(snapshotJson).map((data, index) => ({
288
+ key: idbChunkKey(generation, index),
289
+ value: {
290
+ kind: "snapshot-chunk",
291
+ index,
292
+ data
293
+ }
294
+ }));
295
+ return {
296
+ chunks,
297
+ nextChunkKeys: new Set(chunks.map((chunk) => chunk.key)),
298
+ meta: {
299
+ key: idbMetaKey(),
300
+ value: {
301
+ kind: "meta",
302
+ version: 1,
303
+ generation,
304
+ chunkCount: chunks.length,
305
+ digest: digestText(snapshotJson),
306
+ databaseCount,
307
+ persistedAt: (/* @__PURE__ */ new Date()).toISOString()
308
+ }
309
+ }
310
+ };
311
+ }
312
+ function idbMetaKey() {
313
+ return `${STATE_KEY}:meta`;
314
+ }
315
+ function idbChunkKeyPrefix() {
316
+ return `${STATE_KEY}:snapshot:`;
317
+ }
318
+ function idbChunkKey(generation, index) {
319
+ return `${idbChunkKeyPrefix()}${generation}:${index}`;
320
+ }
321
+ function chunkText(value) {
322
+ const chunks = [];
323
+ let current = "";
324
+ let currentBytes = 0;
325
+ for (const char of value) {
326
+ const charBytes = Buffer.byteLength(char, "utf8");
327
+ if (current && currentBytes + charBytes > IDB_SNAPSHOT_CHUNK_BYTES) {
328
+ pushChunk(chunks, current);
329
+ current = "";
330
+ currentBytes = 0;
331
+ }
332
+ current += char;
333
+ currentBytes += charBytes;
334
+ }
335
+ if (current) pushChunk(chunks, current);
336
+ return chunks;
337
+ }
338
+ function pushChunk(chunks, chunk) {
339
+ if (chunks.length >= IDB_SNAPSHOT_MAX_CHUNKS) throw new Error("Matrix IndexedDB snapshot exceeds SQLite chunk limit");
340
+ chunks.push(chunk);
341
+ }
342
+ function digestText(value) {
343
+ return createHash("sha256").update(value, "utf8").digest("hex");
344
+ }
345
+ function isIdbSnapshotMeta(value) {
346
+ return isRecord(value) && value.kind === "meta" && value.version === 1 && typeof value.generation === "string" && value.generation.trim() !== "" && typeof value.chunkCount === "number" && Number.isSafeInteger(value.chunkCount) && value.chunkCount >= 0 && value.chunkCount <= IDB_SNAPSHOT_MAX_CHUNKS && typeof value.digest === "string" && typeof value.databaseCount === "number" && Number.isSafeInteger(value.databaseCount) && value.databaseCount >= 0 && typeof value.persistedAt === "string";
347
+ }
348
+ function isIdbSnapshotChunk(value) {
349
+ return isRecord(value) && value.kind === "snapshot-chunk" && typeof value.index === "number" && Number.isSafeInteger(value.index) && value.index >= 0 && typeof value.data === "string";
350
+ }
351
+ //#endregion
352
+ export { writeMatrixLegacyCryptoMigrationState as C, writeMatrixRecoveryKeyStateToStore as D, writeMatrixRecoveryKeyStateForPath as E, resolveMatrixSqliteStateEnv as O, writeMatrixIdbSnapshotJsonToStore as S, writeMatrixRecoveryKeyState as T, readMatrixLegacyCryptoMigrationState as _, hasMatrixLegacyCryptoMigrationStateInStore as a, scoreMatrixCryptoStateInStore as b, migrateLegacyMatrixRecoveryKeyFilePathToStore as c, openMatrixLegacyCryptoMigrationStoreOptions as d, openMatrixRecoveryKeyStoreOptions as f, readMatrixIdbSnapshotJson as g, readLegacyMatrixRecoveryKeyState as h, hasMatrixIdbSnapshotStateInStore as i, resolveMatrixSqliteStateKey as k, migrateLegacyMatrixRecoveryKeyFileToStore as l, readLegacyMatrixRecoveryKeyFile as m, MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME as n, hasMatrixRecoveryKeyStateInStore as o, readLegacyMatrixLegacyCryptoMigrationState as p, MATRIX_RECOVERY_KEY_FILENAME as r, migrateLegacyMatrixLegacyCryptoMigrationFileToStore as s, MATRIX_IDB_SNAPSHOT_FILENAME as t, openMatrixIdbSnapshotStoreOptions as u, readMatrixRecoveryKeyState as v, writeMatrixLegacyCryptoMigrationStateToStore as w, writeMatrixIdbSnapshotJson as x, readMatrixRecoveryKeyStateForPath as y };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
2
  import { n as normalizeMatrixMessagingTarget, t as isMatrixQualifiedUserId } from "./target-ids-B-5aQxwn.js";
3
- import { g as resolveMatrixAuth } from "./shared-BbT5LdPp.js";
4
- import "./client-DRRL7Zv5.js";
3
+ import { f as resolveMatrixAuth } from "./shared-Bk7pOHMb.js";
4
+ import "./client-dLfa0qNk.js";
5
5
  import { t as MatrixAuthedHttpClient } from "./http-client-nipb5tk1.js";
6
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  //#region extensions/matrix/src/directory-live.ts
@@ -1,6 +1,6 @@
1
- import { t as isRecord } from "./record-shared-CvzjvHRn.js";
2
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-D9oKDvsJ.js";
3
- import { i as autoPrepareLegacyMatrixCrypto, o as autoMigrateLegacyMatrixState, r as resolveMatrixMigrationStatus } from "./matrix-migration.runtime-RzIEp7RP.js";
1
+ import { o as isRecord } from "./account-selection-Bv_ZuOu4.js";
2
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-Dq8OZWHF.js";
3
+ import { i as autoPrepareLegacyMatrixCrypto, o as autoMigrateLegacyMatrixState, r as resolveMatrixMigrationStatus } from "./matrix-migration.runtime-dvxE3e5l.js";
4
4
  import { t as maybeCreateMatrixMigrationSnapshot } from "./migration-snapshot-backup-YcCrSjbE.js";
5
5
  import { detectPluginInstallPathIssue, formatPluginInstallPathIssue, removePluginFromConfig } from "openclaw/plugin-sdk/runtime-doctor";
6
6
  //#region extensions/matrix/src/doctor.ts
@@ -32,8 +32,8 @@ function formatMatrixLegacyCryptoPreview(detection) {
32
32
  for (const plan of detection.plans) notes.push([
33
33
  `- Matrix encrypted-state migration is pending for account "${plan.accountId}".`,
34
34
  `- Legacy crypto store: ${plan.legacyCryptoPath}`,
35
- `- New recovery key file: ${plan.recoveryKeyPath}`,
36
- `- Migration state file: ${plan.statePath}`,
35
+ `- Recovery key state: Matrix SQLite state (imports ${plan.recoveryKeyPath} if present)`,
36
+ `- Migration state: Matrix SQLite state (imports ${plan.statePath} if present)`,
37
37
  "- Run \"openclaw doctor --fix\" to extract any saved backup key now. Backed-up room keys will restore automatically on next gateway start."
38
38
  ].join("\n"));
39
39
  return notes;
@@ -1,4 +1,4 @@
1
- import { t as isRecord } from "./record-shared-CvzjvHRn.js";
1
+ import { o as isRecord } from "./account-selection-Bv_ZuOu4.js";
2
2
  import { hasLegacyFlatAllowPrivateNetworkAlias, migrateLegacyFlatAllowPrivateNetworkAlias } from "openclaw/plugin-sdk/ssrf-runtime";
3
3
  //#region extensions/matrix/src/doctor-contract.ts
4
4
  function hasLegacyMatrixRoomAllowAlias(value) {
@@ -1,2 +1,265 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-D9oKDvsJ.js";
2
- export { legacyConfigRules, normalizeCompatibilityConfig };
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-Dq8OZWHF.js";
2
+ import { D as writeMatrixRecoveryKeyStateToStore, S as writeMatrixIdbSnapshotJsonToStore, a as hasMatrixLegacyCryptoMigrationStateInStore, d as openMatrixLegacyCryptoMigrationStoreOptions, f as openMatrixRecoveryKeyStoreOptions, h as readLegacyMatrixRecoveryKeyState, i as hasMatrixIdbSnapshotStateInStore, n as MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME, o as hasMatrixRecoveryKeyStateInStore, p as readLegacyMatrixLegacyCryptoMigrationState, r as MATRIX_RECOVERY_KEY_FILENAME, t as MATRIX_IDB_SNAPSHOT_FILENAME, u as openMatrixIdbSnapshotStoreOptions, w as writeMatrixLegacyCryptoMigrationStateToStore } from "./crypto-state-store-DK2tcEyP.js";
3
+ import { a as readLegacyMatrixSyncCacheState, i as openMatrixSyncCacheStoreOptions, o as writeMatrixSyncCacheStateToStore, r as hasMatrixSyncCacheStateInStore } from "./file-sync-store-Ni-pkFde.js";
4
+ import { r as readLegacyMatrixIdbSnapshotState } from "./idb-persistence-BGY1CJ7J.js";
5
+ import path from "node:path";
6
+ import fs from "node:fs/promises";
7
+ //#region extensions/matrix/doctor-contract-api.ts
8
+ const MATRIX_SYNC_CACHE_FILENAME = "bot-storage.json";
9
+ async function fileExists(filePath) {
10
+ try {
11
+ return (await fs.stat(filePath)).isFile();
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+ async function collectLegacyMatrixStateRoots(stateDir, filename) {
17
+ const matrixRoot = path.join(stateDir, "matrix");
18
+ const roots = [];
19
+ async function visit(dir) {
20
+ let entries;
21
+ try {
22
+ entries = await fs.readdir(dir, { withFileTypes: true });
23
+ } catch {
24
+ return;
25
+ }
26
+ for (const entry of entries) {
27
+ const entryPath = path.join(dir, entry.name);
28
+ if (entry.isFile() && entry.name === filename) {
29
+ roots.push(dir);
30
+ continue;
31
+ }
32
+ if (entry.isDirectory()) await visit(entryPath);
33
+ }
34
+ }
35
+ await visit(matrixRoot);
36
+ return roots.filter((root) => path.resolve(root) !== path.resolve(matrixRoot)).toSorted();
37
+ }
38
+ async function collectLegacySyncCacheRoots(stateDir) {
39
+ return collectLegacyMatrixStateRoots(stateDir, MATRIX_SYNC_CACHE_FILENAME);
40
+ }
41
+ async function archiveLegacySyncCache(params) {
42
+ const sourcePath = path.join(params.storageRootDir, MATRIX_SYNC_CACHE_FILENAME);
43
+ const archivedPath = `${sourcePath}.migrated`;
44
+ if (await fileExists(archivedPath)) {
45
+ params.warnings.push(`Left migrated Matrix sync cache in place because ${archivedPath} already exists`);
46
+ return;
47
+ }
48
+ try {
49
+ await fs.rename(sourcePath, archivedPath);
50
+ params.changes.push(`Archived Matrix sync cache legacy source -> ${archivedPath}`);
51
+ } catch (err) {
52
+ params.warnings.push(`Failed archiving Matrix sync cache legacy source: ${String(err)}`);
53
+ }
54
+ }
55
+ async function archiveLegacyMatrixStateFile(params) {
56
+ const sourcePath = path.join(params.storageRootDir, params.filename);
57
+ const archivedPath = `${sourcePath}.migrated`;
58
+ if (await fileExists(archivedPath)) {
59
+ params.warnings.push(`Left migrated ${params.label} in place because ${archivedPath} already exists`);
60
+ return;
61
+ }
62
+ try {
63
+ await fs.rename(sourcePath, archivedPath);
64
+ params.changes.push(`Archived ${params.label} legacy source -> ${archivedPath}`);
65
+ } catch (err) {
66
+ params.warnings.push(`Failed archiving ${params.label} legacy source: ${String(err)}`);
67
+ }
68
+ }
69
+ const stateMigrations = [
70
+ {
71
+ id: "matrix-sync-cache-json-to-plugin-state",
72
+ label: "Matrix sync cache",
73
+ async detectLegacyState(params) {
74
+ const previews = [];
75
+ for (const storageRootDir of await collectLegacySyncCacheRoots(params.stateDir)) {
76
+ if (!await readLegacyMatrixSyncCacheState(storageRootDir)) continue;
77
+ previews.push(`Matrix sync cache JSON can migrate to SQLite: ${storageRootDir}`);
78
+ }
79
+ return previews.length > 0 ? { preview: previews } : null;
80
+ },
81
+ async migrateLegacyState(params) {
82
+ const changes = [];
83
+ const warnings = [];
84
+ for (const storageRootDir of await collectLegacySyncCacheRoots(params.stateDir)) {
85
+ const persisted = await readLegacyMatrixSyncCacheState(storageRootDir);
86
+ if (!persisted) continue;
87
+ const store = params.context.openPluginStateKeyedStore(openMatrixSyncCacheStoreOptions(storageRootDir));
88
+ if (await hasMatrixSyncCacheStateInStore({
89
+ storageRootDir,
90
+ store
91
+ })) {
92
+ warnings.push(`Skipped Matrix sync cache import for ${storageRootDir} because SQLite already has sync cache state`);
93
+ await archiveLegacySyncCache({
94
+ storageRootDir,
95
+ changes,
96
+ warnings
97
+ });
98
+ continue;
99
+ }
100
+ await writeMatrixSyncCacheStateToStore({
101
+ storageRootDir,
102
+ payload: persisted,
103
+ store
104
+ });
105
+ changes.push(`Migrated Matrix sync cache JSON to SQLite for ${storageRootDir}`);
106
+ await archiveLegacySyncCache({
107
+ storageRootDir,
108
+ changes,
109
+ warnings
110
+ });
111
+ }
112
+ return {
113
+ changes,
114
+ warnings
115
+ };
116
+ }
117
+ },
118
+ {
119
+ id: "matrix-recovery-key-json-to-plugin-state",
120
+ label: "Matrix recovery key",
121
+ async detectLegacyState(params) {
122
+ const previews = [];
123
+ for (const storageRootDir of await collectLegacyMatrixStateRoots(params.stateDir, MATRIX_RECOVERY_KEY_FILENAME)) {
124
+ if (!readLegacyMatrixRecoveryKeyState(storageRootDir)) continue;
125
+ previews.push(`Matrix recovery-key JSON can migrate to SQLite: ${storageRootDir}`);
126
+ }
127
+ return previews.length > 0 ? { preview: previews } : null;
128
+ },
129
+ async migrateLegacyState(params) {
130
+ const changes = [];
131
+ const warnings = [];
132
+ for (const storageRootDir of await collectLegacyMatrixStateRoots(params.stateDir, MATRIX_RECOVERY_KEY_FILENAME)) {
133
+ const payload = readLegacyMatrixRecoveryKeyState(storageRootDir);
134
+ if (!payload) continue;
135
+ const store = params.context.openPluginStateKeyedStore(openMatrixRecoveryKeyStoreOptions(storageRootDir));
136
+ if (await hasMatrixRecoveryKeyStateInStore({ store })) {
137
+ warnings.push(`Skipped Matrix recovery-key import for ${storageRootDir} because SQLite already has recovery-key state`);
138
+ await archiveLegacyMatrixStateFile({
139
+ storageRootDir,
140
+ filename: MATRIX_RECOVERY_KEY_FILENAME,
141
+ label: "Matrix recovery key",
142
+ changes,
143
+ warnings
144
+ });
145
+ continue;
146
+ }
147
+ await writeMatrixRecoveryKeyStateToStore({
148
+ payload,
149
+ store
150
+ });
151
+ changes.push(`Migrated Matrix recovery-key JSON to SQLite for ${storageRootDir}`);
152
+ await archiveLegacyMatrixStateFile({
153
+ storageRootDir,
154
+ filename: MATRIX_RECOVERY_KEY_FILENAME,
155
+ label: "Matrix recovery key",
156
+ changes,
157
+ warnings
158
+ });
159
+ }
160
+ return {
161
+ changes,
162
+ warnings
163
+ };
164
+ }
165
+ },
166
+ {
167
+ id: "matrix-idb-snapshot-json-to-plugin-state",
168
+ label: "Matrix IndexedDB snapshot",
169
+ async detectLegacyState(params) {
170
+ const previews = [];
171
+ for (const storageRootDir of await collectLegacyMatrixStateRoots(params.stateDir, MATRIX_IDB_SNAPSHOT_FILENAME)) {
172
+ if (!await readLegacyMatrixIdbSnapshotState(storageRootDir)) continue;
173
+ previews.push(`Matrix IndexedDB snapshot JSON can migrate to SQLite: ${storageRootDir}`);
174
+ }
175
+ return previews.length > 0 ? { preview: previews } : null;
176
+ },
177
+ async migrateLegacyState(params) {
178
+ const changes = [];
179
+ const warnings = [];
180
+ for (const storageRootDir of await collectLegacyMatrixStateRoots(params.stateDir, MATRIX_IDB_SNAPSHOT_FILENAME)) {
181
+ const snapshot = await readLegacyMatrixIdbSnapshotState(storageRootDir);
182
+ if (!snapshot) continue;
183
+ const store = params.context.openPluginStateKeyedStore(openMatrixIdbSnapshotStoreOptions(storageRootDir));
184
+ if (await hasMatrixIdbSnapshotStateInStore({ store })) {
185
+ warnings.push(`Skipped Matrix IndexedDB snapshot import for ${storageRootDir} because SQLite already has snapshot state`);
186
+ await archiveLegacyMatrixStateFile({
187
+ storageRootDir,
188
+ filename: MATRIX_IDB_SNAPSHOT_FILENAME,
189
+ label: "Matrix IndexedDB snapshot",
190
+ changes,
191
+ warnings
192
+ });
193
+ continue;
194
+ }
195
+ await writeMatrixIdbSnapshotJsonToStore({
196
+ snapshotJson: JSON.stringify(snapshot),
197
+ databaseCount: snapshot.length,
198
+ store
199
+ });
200
+ changes.push(`Migrated Matrix IndexedDB snapshot JSON to SQLite for ${storageRootDir}`);
201
+ await archiveLegacyMatrixStateFile({
202
+ storageRootDir,
203
+ filename: MATRIX_IDB_SNAPSHOT_FILENAME,
204
+ label: "Matrix IndexedDB snapshot",
205
+ changes,
206
+ warnings
207
+ });
208
+ }
209
+ return {
210
+ changes,
211
+ warnings
212
+ };
213
+ }
214
+ },
215
+ {
216
+ id: "matrix-legacy-crypto-migration-json-to-plugin-state",
217
+ label: "Matrix legacy crypto migration",
218
+ async detectLegacyState(params) {
219
+ const previews = [];
220
+ for (const storageRootDir of await collectLegacyMatrixStateRoots(params.stateDir, MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME)) {
221
+ if (!readLegacyMatrixLegacyCryptoMigrationState(storageRootDir)) continue;
222
+ previews.push(`Matrix legacy crypto migration JSON can migrate to SQLite: ${storageRootDir}`);
223
+ }
224
+ return previews.length > 0 ? { preview: previews } : null;
225
+ },
226
+ async migrateLegacyState(params) {
227
+ const changes = [];
228
+ const warnings = [];
229
+ for (const storageRootDir of await collectLegacyMatrixStateRoots(params.stateDir, MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME)) {
230
+ const state = readLegacyMatrixLegacyCryptoMigrationState(storageRootDir);
231
+ if (!state) continue;
232
+ const store = params.context.openPluginStateKeyedStore(openMatrixLegacyCryptoMigrationStoreOptions(storageRootDir));
233
+ if (await hasMatrixLegacyCryptoMigrationStateInStore({ store })) {
234
+ warnings.push(`Skipped Matrix legacy crypto migration import for ${storageRootDir} because SQLite already has migration state`);
235
+ await archiveLegacyMatrixStateFile({
236
+ storageRootDir,
237
+ filename: MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME,
238
+ label: "Matrix legacy crypto migration",
239
+ changes,
240
+ warnings
241
+ });
242
+ continue;
243
+ }
244
+ await writeMatrixLegacyCryptoMigrationStateToStore({
245
+ state,
246
+ store
247
+ });
248
+ changes.push(`Migrated Matrix legacy crypto migration JSON to SQLite for ${storageRootDir}`);
249
+ await archiveLegacyMatrixStateFile({
250
+ storageRootDir,
251
+ filename: MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME,
252
+ label: "Matrix legacy crypto migration",
253
+ changes,
254
+ warnings
255
+ });
256
+ }
257
+ return {
258
+ changes,
259
+ warnings
260
+ };
261
+ }
262
+ }
263
+ ];
264
+ //#endregion
265
+ export { legacyConfigRules, normalizeCompatibilityConfig, stateMigrations };
@@ -1,4 +1,4 @@
1
- import { n as editMessageMatrix, r as prepareMatrixSingleText, s as sendSingleTextMessageMatrix, y as MsgType } from "./send-DEgWxp1p.js";
1
+ import { n as editMessageMatrix, r as prepareMatrixSingleText, s as sendSingleTextMessageMatrix, y as MsgType } from "./send-Bus9xhUh.js";
2
2
  import { createDraftStreamLoop } from "openclaw/plugin-sdk/channel-outbound";
3
3
  //#region extensions/matrix/src/matrix/draft-stream.ts
4
4
  const DEFAULT_THROTTLE_MS = 1e3;
@@ -1,4 +1,4 @@
1
- import { a as resolveMatrixDefaultOrOnlyAccountId } from "./account-selection-DEMtY2cn.js";
1
+ import { a as resolveMatrixDefaultOrOnlyAccountId } from "./account-selection-Bv_ZuOu4.js";
2
2
  import { t as resolveMatrixConfigFieldPath } from "./config-paths-ZBCMwSos.js";
3
3
  import { normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
4
4
  //#region extensions/matrix/src/matrix/encryption-guidance.ts