@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.
- package/dist/{account-selection-kqquRzCf.js → account-selection-CWuhuFn1.js} +7 -8
- package/dist/{accounts-DfngqebB.js → accounts-BCzyubQt.js} +3 -3
- package/dist/api.js +8 -11
- package/dist/{approval-handler.runtime-DSeaIsGa.js → approval-handler.runtime-CSvueU9P.js} +7 -6
- package/dist/{approval-ids-BdJGPAJT.js → approval-ids-CEcf-EiM.js} +1 -1
- package/dist/{approval-reaction-auth-BjOpELxu.js → approval-reaction-auth-CziKXatm.js} +2 -2
- package/dist/{approval-reactions-D-BxBK_L.js → approval-reactions-tXh9KYrW.js} +2 -8
- package/dist/auth-presence.js +2 -2
- package/dist/{channel-vj788dNZ.js → channel-CzQw5OZN.js} +376 -148
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CLoF2S9T.js → channel.runtime-I9pBRQb3.js} +79 -55
- package/dist/{config-schema-Djxw3C6b.js → channel.setup-aNaa3Uyn.js} +51 -10
- package/dist/{cli-DMqfDE-q.js → cli-iR6QJ5U0.js} +16 -16
- package/dist/{cli-metadata-C7D53SND.js → cli-metadata-BmUYWjuM.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-BBQdBG7t.js +799 -0
- package/dist/{client-6eRENr7k.js → client-D8XghqmX.js} +4 -4
- package/dist/{client-bootstrap-XsIkHNt0.js → client-bootstrap-Co3RlItb.js} +25 -61
- package/dist/client-support-DLj4vDeu.js +93 -0
- package/dist/config-update-Bor_Pjsv.js +150 -0
- package/dist/contract-api.js +2 -2
- package/dist/{credentials-W2EmwRhu.js → credentials-BdAaWuiR.js} +2 -1
- package/dist/credentials-read-B37cQknZ.js +51 -0
- package/dist/credentials-state-B3cuUFwZ.js +27 -0
- package/dist/{credentials-write.runtime-Be9zNSUw.js → credentials-write.runtime-nAV2-5uR.js} +1 -1
- package/dist/{crypto-runtime-D9_6J5tZ.js → crypto-runtime-Bnz3zEcS.js} +55 -32
- package/dist/direct-room-RinHjtqX.js +71 -0
- package/dist/{directory-live-C8dVBiCc.js → directory-live-DLQzel12.js} +2 -3
- package/dist/{doctor-CM8ijNpW.js → doctor-EWf9CDso.js} +2 -2
- package/dist/{doctor-contract-BMSJkkAE.js → doctor-contract-DEt4O4Zt.js} +2 -3
- package/dist/doctor-contract-api.js +209 -91
- package/dist/{draft-stream-CtvOXq0Z.js → draft-stream-DQ7QNC-l.js} +20 -23
- package/dist/{encryption-guidance-CbEFe38F.js → encryption-guidance-DmLY8NiO.js} +1 -1
- package/dist/{env-auth-CQsYbz-p.js → env-auth-MVS-Vv41.js} +4 -3
- package/dist/{env-vars-B0NxQnPk.js → env-vars-dGqak9dN.js} +1 -1
- package/dist/{errors-C47hvAF8.js → errors-DKVS3_DO.js} +2 -5
- package/dist/{file-sync-store-DiiFsayX.js → file-sync-store-DjskBX2o.js} +24 -3
- package/dist/helper-api.js +2 -2
- package/dist/{idb-persistence-B6x7dMsF.js → idb-persistence-BM0P27Zg.js} +3 -2
- package/dist/{inbound-dedupe-CaBLblef.js → inbound-dedupe-RvSLqdsz.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/{logger-D0GCSDQq.js → logger-B_71hN6W.js} +1 -1
- package/dist/{logging-DV-p52N0.js → logging-DRjvUOIh.js} +1 -1
- package/dist/{media-text-BTwzADS_.js → media-text-Dh-DpTc3.js} +4 -1
- package/dist/{messages-DxQJkhxs.js → messages-DEqg7HVy.js} +31 -11
- package/dist/{monitor-VyWlSLwo.js → monitor-FNrfkuWL.js} +413 -405
- package/dist/plugin-entry.handlers.runtime.js +3 -3
- package/dist/probe.runtime-NIJZYqc2.js +2 -0
- package/dist/profile-D-Wubo0A.js +108 -0
- package/dist/{profile-update-CffmyW_4.js → profile-update-BQlE5s2J.js} +3 -2
- package/dist/{reaction-events-B00WSi98.js → reaction-events-BKOLlnCo.js} +10 -7
- package/dist/{recovery-key-store-BNnHvXdk.js → recovery-key-store-CognuDys.js} +5 -4
- package/dist/{resolve-targets-nm2L48sh.js → resolve-targets-e7AI0P75.js} +2 -2
- package/dist/{resolver.runtime-DS6uPaEe.js → resolver.runtime-V8u0pHEb.js} +1 -1
- package/dist/{room-info-CAFZ3Z9J.js → room-info-BXQA7y10.js} +12 -3
- package/dist/runtime-api.js +7 -4
- package/dist/{sdk-bUytQHx7.js → sdk-NxK3vzMa.js} +242 -119
- package/dist/{secret-contract-M3hRmGO-.js → secret-contract-CufozuyJ.js} +1 -1
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-BldGYG8g.js → send-ClHgDZLT.js} +1477 -1210
- package/dist/session-binding-contract-api.js +2 -3
- package/dist/{setup-bootstrap-Deleiibz.js → setup-bootstrap-BGPjbA5N.js} +4 -4
- package/dist/{setup-core-BVfBv2ai.js → setup-core-DigrLebY.js} +17 -266
- package/dist/setup-plugin-api.js +1 -44
- package/dist/{setup-surface-BBq3WeqX.js → setup-surface-Dtn8sAWs.js} +15 -16
- package/dist/{startup-verification-wm3_i88s.js → startup-verification-Cs08ca8u.js} +3 -3
- package/dist/{storage-BvAkgzvT.js → storage-BsGuHngK.js} +3 -3
- package/dist/subagent-hooks-CMoZaARG.js +48 -0
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{target-ids-B-5aQxwn.js → target-ids-Nwx7cMVE.js} +11 -1
- package/dist/{thread-binding-api-DRbBZlhS.js → thread-binding-api-CzkeLZCU.js} +1 -1
- package/dist/thread-binding-api.js +1 -1
- package/dist/{thread-bindings-DGbl3vDW.js → thread-bindings-BYEGfw3h.js} +17 -10
- package/dist/thread-bindings-runtime.js +1 -1
- package/dist/{thread-bindings-shared-CKnY4LSd.js → thread-bindings-shared-oNPiyMWY.js} +1 -6
- package/dist/{tool-actions.runtime-uu9blSqO.js → tool-actions.runtime-ck6IJyP0.js} +36 -19
- package/dist/{verification-DYMQ1QpI.js → verification-CabtBTtB.js} +2 -2
- package/openclaw.plugin.json +61 -1
- package/package.json +4 -4
- package/dist/active-client-DXvz2gCo.js +0 -20
- package/dist/client-Dbso3-0V.js +0 -30
- package/dist/create-client-BmSU-q-D.js +0 -61
- package/dist/credentials-read-DVmFCm7X.js +0 -77
- package/dist/exec-approval-resolver-BCgqRtZS.js +0 -16
- package/dist/preflight-audio.runtime-BZxxQsxY.js +0 -11
- package/dist/probe.runtime-BuieqmS3.js +0 -3
- package/dist/record-shared-CWWx6fvI.js +0 -2
- package/dist/route-DY6at4qJ.js +0 -161
- package/dist/shared-CUMWxcMz.js +0 -673
- package/dist/subagent-hooks-dkPAF6Et.js +0 -143
- package/dist/sync-state-CWbp0QSY.js +0 -12
- package/dist/{runtime-api-D1xI_cvh.js → runtime-api-BGO16Fu8.js} +3 -3
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import { a as resolveMatrixDefaultOrOnlyAccountId, n as requiresExplicitMatrixDefaultAccount } from "./account-selection-
|
|
2
|
-
import { t as
|
|
1
|
+
import { a as resolveMatrixDefaultOrOnlyAccountId, n as requiresExplicitMatrixDefaultAccount } from "./account-selection-CWuhuFn1.js";
|
|
2
|
+
import { i as normalizeMatrixStoredCredentials, n as isMatrixCredentialRevocation, r as matrixCredentialsStoreKey, t as MATRIX_CREDENTIALS_NAMESPACE } from "./credentials-state-B3cuUFwZ.js";
|
|
3
3
|
import { r as resolveMatrixCredentialsDir } from "./storage-paths-gUmSydsW.js";
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
6
|
-
import {
|
|
7
|
-
import { a as readLegacyMatrixSyncCacheState, i as openMatrixSyncCacheStoreOptions, o as writeMatrixSyncCacheStateToStore, r as hasMatrixSyncCacheStateInStore } from "./file-sync-store-DiiFsayX.js";
|
|
4
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DEt4O4Zt.js";
|
|
5
|
+
import { C as readLegacyMatrixRecoveryKeyState, O as writeMatrixIdbSnapshotJsonToStore, T as readMatrixIdbSnapshotJsonFromStore, a as openMatrixStorageMetaStoreOptions, b as openMatrixRecoveryKeyStoreOptions, f as MATRIX_IDB_SNAPSHOT_FILENAME, g as hasMatrixRecoveryKeyStateInStore, h as hasMatrixLegacyCryptoMigrationStateInStore, i as normalizeMatrixStorageMetadata, j as writeMatrixRecoveryKeyStateToStore, k as writeMatrixLegacyCryptoMigrationStateToStore, m as MATRIX_RECOVERY_KEY_FILENAME, n as hasMatrixStorageMetaStateInStore, p as MATRIX_LEGACY_CRYPTO_MIGRATION_FILENAME, u as writeMatrixStorageMetaStateToStore, v as openMatrixIdbSnapshotStoreOptions, x as readLegacyMatrixLegacyCryptoMigrationState, y as openMatrixLegacyCryptoMigrationStoreOptions } from "./storage-BsGuHngK.js";
|
|
6
|
+
import { a as readLegacyMatrixSyncCacheState, i as openMatrixSyncCacheStoreOptions, o as writeMatrixSyncCacheStateToStore, r as hasMatrixSyncCacheStateInStore } from "./file-sync-store-DjskBX2o.js";
|
|
8
7
|
import { n as MATRIX_IDB_SNAPSHOT_LOCK_OPTIONS } from "./idb-persistence-lock-DAJ49nZX.js";
|
|
9
|
-
import { r as readLegacyMatrixIdbSnapshotStateUnlocked, t as isValidMatrixIdbSnapshotJson } from "./idb-persistence-
|
|
10
|
-
import { a as resolveMatrixInboundDedupeStateNamespace, n as MATRIX_INBOUND_DEDUPE_TTL_MS, r as buildMatrixInboundDedupeEventKey } from "./inbound-dedupe-CaBLblef.js";
|
|
8
|
+
import { r as readLegacyMatrixIdbSnapshotStateUnlocked, t as isValidMatrixIdbSnapshotJson } from "./idb-persistence-BM0P27Zg.js";
|
|
11
9
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
10
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
13
|
-
import { archiveLegacyStateSource } from "openclaw/plugin-sdk/runtime-doctor";
|
|
14
11
|
import { createHash, randomUUID } from "node:crypto";
|
|
15
12
|
import path from "node:path";
|
|
13
|
+
import { archiveLegacyStateSource } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
16
14
|
import fs from "node:fs";
|
|
17
15
|
import fs$1 from "node:fs/promises";
|
|
18
16
|
import { isDeepStrictEqual } from "node:util";
|
|
19
17
|
import { withFileLock } from "openclaw/plugin-sdk/file-lock";
|
|
20
|
-
import { createPersistentDedupeImportEntry } from "openclaw/plugin-sdk/persistent-dedupe";
|
|
21
18
|
//#region extensions/matrix/src/matrix/crypto-snapshot-doctor.ts
|
|
22
19
|
async function migrateLegacyMatrixIdbSnapshot(params) {
|
|
23
20
|
const snapshotPath = path.join(params.storageRootDir, MATRIX_IDB_SNAPSHOT_FILENAME);
|
|
@@ -101,21 +98,55 @@ async function archiveLegacyMatrixIdbSnapshot(params) {
|
|
|
101
98
|
//#endregion
|
|
102
99
|
//#region extensions/matrix/src/matrix/monitor/inbound-dedupe-migration.ts
|
|
103
100
|
const LEGACY_SQLITE_NAMESPACE = "inbound-dedupe";
|
|
104
|
-
const LEGACY_SQLITE_MAX_ENTRIES = 2e4;
|
|
105
101
|
const LEGACY_MARKERS_NAMESPACE = "inbound-dedupe-migrations";
|
|
106
|
-
const LEGACY_MARKERS_MAX_ENTRIES = 1e3;
|
|
107
102
|
const LEGACY_JSON_VERSION = 1;
|
|
103
|
+
const MATRIX_PLUGIN_ID = "matrix";
|
|
104
|
+
const MIGRATION_COMPLETION_NAMESPACE = "inbound-dedupe-migration-state";
|
|
105
|
+
const MIGRATION_COMPLETION_KEY = "sqlite-json-to-claimable-v1";
|
|
106
|
+
const STATE_DATABASE_RELATIVE_PATH = path.join("state", "openclaw.sqlite");
|
|
108
107
|
const STORAGE_META_FILENAME = "storage-meta.json";
|
|
109
108
|
const MATRIX_LEGACY_INBOUND_DEDUPE_FILENAME = "inbound-dedupe.json";
|
|
109
|
+
function openMatrixInboundDedupeMigrationCompletionStore(context, env) {
|
|
110
|
+
return context.openPluginStateKeyedStore({
|
|
111
|
+
namespace: MIGRATION_COMPLETION_NAMESPACE,
|
|
112
|
+
maxEntries: 4,
|
|
113
|
+
overflowPolicy: "reject-new",
|
|
114
|
+
env
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
async function hasCompletedMatrixInboundDedupeMigration(context, env) {
|
|
118
|
+
const marker = await openMatrixInboundDedupeMigrationCompletionStore(context, env).lookup(MIGRATION_COMPLETION_KEY);
|
|
119
|
+
return isRecord(marker) && marker.version === 1 && typeof marker.completedAt === "number" && Number.isFinite(marker.completedAt) && marker.completedAt >= 0;
|
|
120
|
+
}
|
|
121
|
+
async function recordMatrixInboundDedupeMigrationCompletion(context, env) {
|
|
122
|
+
await openMatrixInboundDedupeMigrationCompletionStore(context, env).register(MIGRATION_COMPLETION_KEY, {
|
|
123
|
+
version: 1,
|
|
124
|
+
completedAt: Date.now()
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Reserves the durable completion row before any legacy source is changed.
|
|
129
|
+
* The invalid timestamp keeps detection active after an interrupted run, while
|
|
130
|
+
* updating this same key after retirement remains possible at plugin capacity.
|
|
131
|
+
*/
|
|
132
|
+
async function reserveMatrixInboundDedupeMigrationCompletion(context, env) {
|
|
133
|
+
await openMatrixInboundDedupeMigrationCompletionStore(context, env).register(MIGRATION_COMPLETION_KEY, {
|
|
134
|
+
version: 1,
|
|
135
|
+
completedAt: -1
|
|
136
|
+
});
|
|
137
|
+
}
|
|
110
138
|
async function collectMatrixInboundDedupeSources(stateDir) {
|
|
111
139
|
const matrixRoot = path.join(stateDir, "matrix");
|
|
112
140
|
const sqliteRoots = /* @__PURE__ */ new Set();
|
|
113
141
|
const jsonRoots = /* @__PURE__ */ new Set();
|
|
114
|
-
|
|
142
|
+
const warnings = [];
|
|
143
|
+
async function visit(dir, allowMissing = false) {
|
|
115
144
|
let entries;
|
|
116
145
|
try {
|
|
117
146
|
entries = await fs$1.readdir(dir, { withFileTypes: true });
|
|
118
|
-
} catch {
|
|
147
|
+
} catch (err) {
|
|
148
|
+
if (allowMissing && err.code === "ENOENT") return;
|
|
149
|
+
warnings.push(`Failed scanning Matrix inbound dedupe sources under ${dir}: ${String(err)}`);
|
|
119
150
|
return;
|
|
120
151
|
}
|
|
121
152
|
for (const entry of entries) {
|
|
@@ -128,40 +159,41 @@ async function collectMatrixInboundDedupeSources(stateDir) {
|
|
|
128
159
|
if (entry.isDirectory()) await visit(entryPath);
|
|
129
160
|
}
|
|
130
161
|
}
|
|
131
|
-
await visit(matrixRoot);
|
|
162
|
+
await visit(matrixRoot, true);
|
|
132
163
|
const matrixRootResolved = path.resolve(matrixRoot);
|
|
133
164
|
const isAccountRoot = (root) => path.resolve(root) !== matrixRootResolved;
|
|
134
|
-
|
|
165
|
+
const roots = {
|
|
135
166
|
sqliteRoots: [...sqliteRoots].filter(isAccountRoot).toSorted(),
|
|
136
167
|
jsonRoots: [...jsonRoots].filter(isAccountRoot).toSorted()
|
|
137
168
|
};
|
|
169
|
+
return warnings.length === 0 ? {
|
|
170
|
+
status: "complete",
|
|
171
|
+
...roots
|
|
172
|
+
} : {
|
|
173
|
+
status: "incomplete",
|
|
174
|
+
...roots,
|
|
175
|
+
warnings
|
|
176
|
+
};
|
|
138
177
|
}
|
|
139
|
-
function
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
});
|
|
178
|
+
function selectLegacySqliteRows(db) {
|
|
179
|
+
if (!db.prepare(`SELECT 1 AS present
|
|
180
|
+
FROM sqlite_master
|
|
181
|
+
WHERE type = 'table' AND name = 'plugin_state_entries'`).get()) return [];
|
|
182
|
+
return db.prepare(`SELECT namespace, entry_key, value_json, expires_at
|
|
183
|
+
FROM plugin_state_entries
|
|
184
|
+
WHERE plugin_id = ? AND namespace IN (?, ?)
|
|
185
|
+
ORDER BY namespace ASC, created_at ASC, entry_key ASC`).all(MATRIX_PLUGIN_ID, LEGACY_SQLITE_NAMESPACE, LEGACY_MARKERS_NAMESPACE);
|
|
148
186
|
}
|
|
149
|
-
function
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
maxEntries: LEGACY_MARKERS_MAX_ENTRIES,
|
|
153
|
-
env: {
|
|
154
|
-
...io.env,
|
|
155
|
-
OPENCLAW_STATE_DIR: storageRootDir
|
|
156
|
-
}
|
|
157
|
-
});
|
|
187
|
+
function isLegacySqliteRowExpired(row, now) {
|
|
188
|
+
if (typeof row.expires_at === "bigint") return row.expires_at <= BigInt(now);
|
|
189
|
+
return row.expires_at !== null && row.expires_at <= now;
|
|
158
190
|
}
|
|
159
191
|
function normalizeLegacyTimestamp(raw) {
|
|
160
192
|
if (typeof raw !== "number" || !Number.isFinite(raw)) return null;
|
|
161
193
|
return Math.max(0, Math.floor(raw));
|
|
162
194
|
}
|
|
163
195
|
function parseLegacySqliteRow(row) {
|
|
164
|
-
const value = isRecord
|
|
196
|
+
const value = isRecord(row.value) ? row.value : {};
|
|
165
197
|
const roomId = typeof value.roomId === "string" ? value.roomId.trim() : "";
|
|
166
198
|
const eventId = typeof value.eventId === "string" ? value.eventId.trim() : "";
|
|
167
199
|
const ts = normalizeLegacyTimestamp(value.ts);
|
|
@@ -177,24 +209,63 @@ function parseLegacySqliteRow(row) {
|
|
|
177
209
|
ts
|
|
178
210
|
};
|
|
179
211
|
}
|
|
180
|
-
/**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Reads one storage root's legacy SQLite dedupe rows without opening it through
|
|
214
|
+
* the current state runtime. Historical per-account databases can predate the
|
|
215
|
+
* current core schema, and detection must not upgrade them merely to inspect
|
|
216
|
+
* these retired plugin-state namespaces.
|
|
217
|
+
*/
|
|
218
|
+
async function readLegacyInboundDedupeSqliteSource(storageRootDir) {
|
|
219
|
+
const { openNodeSqliteDatabase } = await import("openclaw/plugin-sdk/sqlite-runtime");
|
|
220
|
+
const db = openNodeSqliteDatabase(path.join(storageRootDir, STATE_DATABASE_RELATIVE_PATH), { readOnly: true });
|
|
221
|
+
try {
|
|
222
|
+
const rows = selectLegacySqliteRows(db);
|
|
223
|
+
const markers = [];
|
|
224
|
+
const now = Date.now();
|
|
225
|
+
for (const row of rows) {
|
|
226
|
+
if (isLegacySqliteRowExpired(row, now)) continue;
|
|
227
|
+
const value = JSON.parse(row.value_json);
|
|
228
|
+
if (row.namespace !== LEGACY_SQLITE_NAMESPACE) continue;
|
|
229
|
+
const marker = parseLegacySqliteRow({
|
|
230
|
+
key: row.entry_key,
|
|
231
|
+
value
|
|
232
|
+
});
|
|
233
|
+
if (marker) markers.push(marker);
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
markers,
|
|
237
|
+
legacyRowCount: rows.length
|
|
238
|
+
};
|
|
239
|
+
} finally {
|
|
240
|
+
db.close();
|
|
188
241
|
}
|
|
189
|
-
return {
|
|
190
|
-
markers,
|
|
191
|
-
legacyRowCount: rows.length + markerRows.length
|
|
192
|
-
};
|
|
193
242
|
}
|
|
194
|
-
/**
|
|
195
|
-
async function retireLegacyInboundDedupeSqliteRows(
|
|
196
|
-
|
|
197
|
-
|
|
243
|
+
/** Deletes only the two retired Matrix namespaces after a successful import. */
|
|
244
|
+
async function retireLegacyInboundDedupeSqliteRows(storageRootDir) {
|
|
245
|
+
const { openNodeSqliteDatabase, runSqliteImmediateTransactionSync } = await import("openclaw/plugin-sdk/sqlite-runtime");
|
|
246
|
+
const db = openNodeSqliteDatabase(path.join(storageRootDir, STATE_DATABASE_RELATIVE_PATH));
|
|
247
|
+
try {
|
|
248
|
+
if (selectLegacySqliteRows(db).length === 0) return;
|
|
249
|
+
runSqliteImmediateTransactionSync(db, () => {
|
|
250
|
+
if (selectLegacySqliteRows(db).length === 0) return;
|
|
251
|
+
db.prepare(`DELETE FROM plugin_state_entries
|
|
252
|
+
WHERE plugin_id = ? AND namespace IN (?, ?)`).run(MATRIX_PLUGIN_ID, LEGACY_SQLITE_NAMESPACE, LEGACY_MARKERS_NAMESPACE);
|
|
253
|
+
});
|
|
254
|
+
} finally {
|
|
255
|
+
db.close();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async function verifyMatrixInboundDedupeSourcesRetired(stateDir) {
|
|
259
|
+
const warnings = [];
|
|
260
|
+
const remaining = await collectMatrixInboundDedupeSources(stateDir);
|
|
261
|
+
if (remaining.status === "incomplete") warnings.push(...remaining.warnings);
|
|
262
|
+
for (const storageRootDir of remaining.sqliteRoots) try {
|
|
263
|
+
if ((await readLegacyInboundDedupeSqliteSource(storageRootDir)).legacyRowCount > 0) warnings.push(`Matrix inbound dedupe rows remain after retirement for ${storageRootDir}`);
|
|
264
|
+
} catch (err) {
|
|
265
|
+
warnings.push(`Failed verifying retired Matrix inbound dedupe rows for ${storageRootDir}: ${String(err)}`);
|
|
266
|
+
}
|
|
267
|
+
for (const storageRootDir of remaining.jsonRoots) warnings.push(`Matrix inbound dedupe JSON remains after retirement for ${storageRootDir}`);
|
|
268
|
+
return warnings;
|
|
198
269
|
}
|
|
199
270
|
async function resolveJsonRootAccountId(storageRootDir) {
|
|
200
271
|
for (const filename of [STORAGE_META_FILENAME, `${STORAGE_META_FILENAME}.migrated`]) try {
|
|
@@ -217,11 +288,11 @@ async function readLegacyInboundDedupeJsonSource(storageRootDir) {
|
|
|
217
288
|
} catch {
|
|
218
289
|
return null;
|
|
219
290
|
}
|
|
220
|
-
if (!isRecord
|
|
291
|
+
if (!isRecord(parsed) || parsed.version !== LEGACY_JSON_VERSION || !Array.isArray(parsed.entries)) return null;
|
|
221
292
|
const accountId = await resolveJsonRootAccountId(storageRootDir);
|
|
222
293
|
const markers = [];
|
|
223
294
|
for (const entry of parsed.entries) {
|
|
224
|
-
if (!isRecord
|
|
295
|
+
if (!isRecord(entry) || typeof entry.key !== "string") continue;
|
|
225
296
|
const separator = entry.key.indexOf("|");
|
|
226
297
|
if (separator <= 0) continue;
|
|
227
298
|
const roomId = entry.key.slice(0, separator).trim();
|
|
@@ -239,14 +310,16 @@ async function readLegacyInboundDedupeJsonSource(storageRootDir) {
|
|
|
239
310
|
}
|
|
240
311
|
/**
|
|
241
312
|
* Imports the globally newest legacy markers into the claimable-dedupe store.
|
|
242
|
-
* Never exceeds capacity
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
313
|
+
* Never exceeds capacity, never replaces a post-upgrade destination row, and
|
|
314
|
+
* preserves source timestamps because eviction is ordered by row creation
|
|
315
|
+
* time. Throws on import or verification errors so the caller keeps the legacy
|
|
316
|
+
* sources for the next doctor attempt.
|
|
246
317
|
*/
|
|
247
318
|
async function importNewestInboundDedupeMarkers(params) {
|
|
319
|
+
const { createPersistentDedupeImportEntry } = await import("openclaw/plugin-sdk/persistent-dedupe");
|
|
320
|
+
const { buildMatrixInboundDedupeEventKey, MATRIX_INBOUND_DEDUPE_STATE_MAX_ENTRIES, MATRIX_INBOUND_DEDUPE_TTL_MS, resolveMatrixInboundDedupeStateNamespace } = await import("./inbound-dedupe-RvSLqdsz.js");
|
|
248
321
|
const now = params.now ?? Date.now();
|
|
249
|
-
const stateMaxEntries = params.stateMaxEntries ??
|
|
322
|
+
const stateMaxEntries = params.stateMaxEntries ?? MATRIX_INBOUND_DEDUPE_STATE_MAX_ENTRIES;
|
|
250
323
|
const newestByKey = /* @__PURE__ */ new Map();
|
|
251
324
|
for (const marker of params.markers) {
|
|
252
325
|
const key = buildMatrixInboundDedupeEventKey(marker);
|
|
@@ -264,24 +337,47 @@ async function importNewestInboundDedupeMarkers(params) {
|
|
|
264
337
|
defaultTtlMs: MATRIX_INBOUND_DEDUPE_TTL_MS,
|
|
265
338
|
env: params.io.env
|
|
266
339
|
});
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (capacity <= 0) break;
|
|
340
|
+
const existingEntries = await store.entries();
|
|
341
|
+
const existingKeys = new Set(existingEntries.map((entry) => entry.key));
|
|
342
|
+
const missingEntries = markers.flatMap((marker) => {
|
|
271
343
|
const remainingTtlMs = MATRIX_INBOUND_DEDUPE_TTL_MS - (now - marker.ts);
|
|
272
|
-
if (remainingTtlMs <= 0)
|
|
344
|
+
if (remainingTtlMs <= 0) return [];
|
|
273
345
|
const entry = createPersistentDedupeImportEntry({
|
|
274
346
|
key: marker.key,
|
|
275
347
|
seenAt: marker.ts,
|
|
276
348
|
ttlMs: Math.max(1, Math.floor(remainingTtlMs))
|
|
277
349
|
});
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
350
|
+
return existingKeys.has(entry.key) ? [] : [{
|
|
351
|
+
marker,
|
|
352
|
+
entry
|
|
353
|
+
}];
|
|
354
|
+
});
|
|
355
|
+
const namespaceCapacity = Math.max(0, stateMaxEntries - existingEntries.length);
|
|
356
|
+
const pluginCapacity = missingEntries.length > 0 ? params.io.context.getPluginStateCapacity?.() : void 0;
|
|
357
|
+
if (missingEntries.length > 0 && !pluginCapacity) throw new Error("plugin-wide Matrix inbound dedupe import capacity is unavailable");
|
|
358
|
+
const pluginRemainingCapacity = pluginCapacity ? Math.max(0, pluginCapacity.maxEntries - pluginCapacity.liveEntries) : namespaceCapacity;
|
|
359
|
+
const capacity = Math.min(namespaceCapacity, pluginRemainingCapacity);
|
|
360
|
+
const selectedEntries = missingEntries.slice(0, capacity);
|
|
361
|
+
if (selectedEntries.length > 0) {
|
|
362
|
+
const importEntries = params.io.context.importPluginStateEntries;
|
|
363
|
+
if (!importEntries) throw new Error("retention-aware Matrix inbound dedupe import is unavailable");
|
|
364
|
+
importEntries({
|
|
365
|
+
namespace: resolveMatrixInboundDedupeStateNamespace(),
|
|
366
|
+
maxEntries: stateMaxEntries,
|
|
367
|
+
defaultTtlMs: MATRIX_INBOUND_DEDUPE_TTL_MS,
|
|
368
|
+
env: params.io.env
|
|
369
|
+
}, selectedEntries.map(({ marker, entry }) => ({
|
|
370
|
+
key: entry.key,
|
|
371
|
+
value: entry.value,
|
|
372
|
+
createdAt: marker.ts,
|
|
373
|
+
...entry.ttlMs != null ? { ttlMs: entry.ttlMs } : {}
|
|
374
|
+
})));
|
|
375
|
+
const importedKeys = new Set((await store.entries()).map((entry) => entry.key));
|
|
376
|
+
const missingKey = selectedEntries.find(({ entry }) => !importedKeys.has(entry.key))?.entry.key;
|
|
377
|
+
if (missingKey) throw new Error(`retention-aware Matrix inbound dedupe import did not persist ${missingKey}`);
|
|
282
378
|
}
|
|
283
379
|
return {
|
|
284
|
-
imported,
|
|
380
|
+
imported: selectedEntries.length,
|
|
285
381
|
total: markers.length
|
|
286
382
|
};
|
|
287
383
|
}
|
|
@@ -412,7 +508,13 @@ const stateMigrations = [
|
|
|
412
508
|
}
|
|
413
509
|
const existing = normalizeMatrixStoredCredentials(stored, source.accountId);
|
|
414
510
|
if (existing && JSON.stringify(existing) !== JSON.stringify(credentials)) {
|
|
415
|
-
|
|
511
|
+
changes.push(`Kept existing Matrix credentials for account ${source.accountId}`);
|
|
512
|
+
await archiveLegacyStateSource({
|
|
513
|
+
filePath: source.filePath,
|
|
514
|
+
label: "Matrix credentials",
|
|
515
|
+
changes,
|
|
516
|
+
warnings
|
|
517
|
+
});
|
|
416
518
|
continue;
|
|
417
519
|
}
|
|
418
520
|
if (!existing) try {
|
|
@@ -444,22 +546,7 @@ const stateMigrations = [
|
|
|
444
546
|
id: "matrix-inbound-dedupe-to-claimable-dedupe",
|
|
445
547
|
label: "Matrix inbound dedupe markers",
|
|
446
548
|
async detectLegacyState(params) {
|
|
447
|
-
|
|
448
|
-
context: params.context,
|
|
449
|
-
env: params.env
|
|
450
|
-
};
|
|
451
|
-
const preview = [];
|
|
452
|
-
const sources = await collectMatrixInboundDedupeSources(params.stateDir);
|
|
453
|
-
for (const storageRootDir of sources.sqliteRoots) {
|
|
454
|
-
try {
|
|
455
|
-
if ((await readLegacyInboundDedupeSqliteSource(io, storageRootDir)).legacyRowCount === 0) continue;
|
|
456
|
-
} catch {
|
|
457
|
-
continue;
|
|
458
|
-
}
|
|
459
|
-
preview.push(`Matrix inbound dedupe rows can migrate to the claimable dedupe store: ${storageRootDir}`);
|
|
460
|
-
}
|
|
461
|
-
for (const storageRootDir of sources.jsonRoots) preview.push(`Matrix inbound dedupe JSON can migrate to the claimable dedupe store: ${path.join(storageRootDir, MATRIX_LEGACY_INBOUND_DEDUPE_FILENAME)}`);
|
|
462
|
-
return preview.length > 0 ? { preview } : null;
|
|
549
|
+
return await hasCompletedMatrixInboundDedupeMigration(params.context, params.env) ? null : { preview: ["Matrix inbound dedupe legacy sources need a one-time migration scan"] };
|
|
463
550
|
},
|
|
464
551
|
async migrateLegacyState(params) {
|
|
465
552
|
const io = {
|
|
@@ -468,11 +555,38 @@ const stateMigrations = [
|
|
|
468
555
|
};
|
|
469
556
|
const changes = [];
|
|
470
557
|
const warnings = [];
|
|
558
|
+
if (await hasCompletedMatrixInboundDedupeMigration(params.context, params.env)) return {
|
|
559
|
+
changes,
|
|
560
|
+
warnings
|
|
561
|
+
};
|
|
562
|
+
try {
|
|
563
|
+
await reserveMatrixInboundDedupeMigrationCompletion(params.context, params.env);
|
|
564
|
+
} catch (err) {
|
|
565
|
+
warnings.push(`Failed reserving Matrix inbound dedupe migration completion: ${String(err)}; left legacy sources in place`);
|
|
566
|
+
return {
|
|
567
|
+
changes,
|
|
568
|
+
warnings
|
|
569
|
+
};
|
|
570
|
+
}
|
|
471
571
|
const sources = await collectMatrixInboundDedupeSources(params.stateDir);
|
|
572
|
+
if (sources.status === "incomplete") warnings.push(...sources.warnings);
|
|
573
|
+
const recordCompletionIfClean = async (verifyRetirement = false) => {
|
|
574
|
+
if (warnings.length > 0) return;
|
|
575
|
+
if (verifyRetirement) {
|
|
576
|
+
warnings.push(...await verifyMatrixInboundDedupeSourcesRetired(params.stateDir));
|
|
577
|
+
if (warnings.length > 0) return;
|
|
578
|
+
}
|
|
579
|
+
try {
|
|
580
|
+
await recordMatrixInboundDedupeMigrationCompletion(params.context, params.env);
|
|
581
|
+
if (sources.sqliteRoots.length + sources.jsonRoots.length > 0) changes.push(`Recorded Matrix inbound dedupe migration completion (${sources.sqliteRoots.length} SQLite roots, ${sources.jsonRoots.length} JSON roots scanned)`);
|
|
582
|
+
} catch (err) {
|
|
583
|
+
warnings.push(`Failed recording Matrix inbound dedupe migration completion: ${String(err)}`);
|
|
584
|
+
}
|
|
585
|
+
};
|
|
472
586
|
const gathered = [];
|
|
473
587
|
const sqliteRootsToRetire = [];
|
|
474
588
|
for (const storageRootDir of sources.sqliteRoots) try {
|
|
475
|
-
const source = await readLegacyInboundDedupeSqliteSource(
|
|
589
|
+
const source = await readLegacyInboundDedupeSqliteSource(storageRootDir);
|
|
476
590
|
if (source.legacyRowCount === 0) continue;
|
|
477
591
|
gathered.push(...source.markers);
|
|
478
592
|
sqliteRootsToRetire.push(storageRootDir);
|
|
@@ -488,10 +602,13 @@ const stateMigrations = [
|
|
|
488
602
|
} catch (err) {
|
|
489
603
|
warnings.push(`Failed reading Matrix inbound dedupe JSON for ${storageRootDir}: ${String(err)}; left legacy file in place`);
|
|
490
604
|
}
|
|
491
|
-
if (sqliteRootsToRetire.length + jsonRootsToRetire.length === 0)
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
605
|
+
if (sqliteRootsToRetire.length + jsonRootsToRetire.length === 0) {
|
|
606
|
+
await recordCompletionIfClean();
|
|
607
|
+
return {
|
|
608
|
+
changes,
|
|
609
|
+
warnings
|
|
610
|
+
};
|
|
611
|
+
}
|
|
495
612
|
try {
|
|
496
613
|
const result = await importNewestInboundDedupeMarkers({
|
|
497
614
|
io,
|
|
@@ -506,7 +623,7 @@ const stateMigrations = [
|
|
|
506
623
|
};
|
|
507
624
|
}
|
|
508
625
|
for (const storageRootDir of sqliteRootsToRetire) try {
|
|
509
|
-
await retireLegacyInboundDedupeSqliteRows(
|
|
626
|
+
await retireLegacyInboundDedupeSqliteRows(storageRootDir);
|
|
510
627
|
changes.push(`Retired Matrix inbound dedupe rows for ${storageRootDir}`);
|
|
511
628
|
} catch (err) {
|
|
512
629
|
warnings.push(`Failed retiring Matrix inbound dedupe rows for ${storageRootDir}: ${String(err)}`);
|
|
@@ -518,6 +635,7 @@ const stateMigrations = [
|
|
|
518
635
|
changes,
|
|
519
636
|
warnings
|
|
520
637
|
});
|
|
638
|
+
await recordCompletionIfClean(true);
|
|
521
639
|
return {
|
|
522
640
|
changes,
|
|
523
641
|
warnings
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { E as MsgType, a as sendSingleTextMessageMatrix, l as prepareMatrixSingleText, t as editMessageMatrix } from "./send-ClHgDZLT.js";
|
|
2
|
+
import { createFinalizableDraftStreamControlsForState } from "openclaw/plugin-sdk/channel-outbound";
|
|
3
3
|
//#region extensions/matrix/src/matrix/draft-stream.ts
|
|
4
4
|
const DEFAULT_THROTTLE_MS = 1e3;
|
|
5
5
|
function resolveDraftPreviewOptions(mode) {
|
|
@@ -19,22 +19,26 @@ function createMatrixDraftStream(params) {
|
|
|
19
19
|
let currentEventId;
|
|
20
20
|
let lastSentText = "";
|
|
21
21
|
let lastSentContent = "";
|
|
22
|
-
|
|
22
|
+
const streamState = {
|
|
23
|
+
stopped: false,
|
|
24
|
+
final: false
|
|
25
|
+
};
|
|
23
26
|
let sendFailed = false;
|
|
24
27
|
let finalizeInPlaceBlocked = false;
|
|
25
28
|
let liveFinalized = false;
|
|
26
29
|
let replyToId = params.replyToId;
|
|
27
30
|
const sendOrEdit = async (text) => {
|
|
28
31
|
const trimmed = text.trimEnd();
|
|
29
|
-
if (!trimmed) return false;
|
|
32
|
+
if (!trimmed.trim()) return false;
|
|
30
33
|
const preparedText = prepareMatrixSingleText(trimmed, {
|
|
31
34
|
cfg,
|
|
32
|
-
accountId
|
|
35
|
+
accountId,
|
|
36
|
+
preserveWhitespace: true
|
|
33
37
|
});
|
|
34
38
|
if (!preparedText.fitsInSingleEvent) {
|
|
35
39
|
finalizeInPlaceBlocked = true;
|
|
36
40
|
if (!currentEventId) sendFailed = true;
|
|
37
|
-
stopped = true;
|
|
41
|
+
streamState.stopped = true;
|
|
38
42
|
log?.(`draft-stream: preview exceeded single-event limit (${preparedText.convertedText.length} > ${preparedText.singleEventLimit})`);
|
|
39
43
|
return false;
|
|
40
44
|
}
|
|
@@ -73,13 +77,13 @@ function createMatrixDraftStream(params) {
|
|
|
73
77
|
log?.(`draft-stream: send/edit failed: ${String(err)}`);
|
|
74
78
|
if (err instanceof Error && err.message.startsWith("Matrix single-message text exceeds limit")) finalizeInPlaceBlocked = true;
|
|
75
79
|
if (!currentEventId) sendFailed = true;
|
|
76
|
-
stopped = true;
|
|
80
|
+
streamState.stopped = true;
|
|
77
81
|
return false;
|
|
78
82
|
}
|
|
79
83
|
};
|
|
80
|
-
const loop =
|
|
84
|
+
const { loop, update, stop: stopDraft, discardPending } = createFinalizableDraftStreamControlsForState({
|
|
81
85
|
throttleMs: DEFAULT_THROTTLE_MS,
|
|
82
|
-
|
|
86
|
+
state: streamState,
|
|
83
87
|
sendOrEditStreamMessage: sendOrEdit
|
|
84
88
|
});
|
|
85
89
|
log?.(`draft-stream: ready (throttleMs=${DEFAULT_THROTTLE_MS})`);
|
|
@@ -107,21 +111,16 @@ function createMatrixDraftStream(params) {
|
|
|
107
111
|
return true;
|
|
108
112
|
};
|
|
109
113
|
const stop = async () => {
|
|
110
|
-
await
|
|
111
|
-
stopped = true;
|
|
114
|
+
await stopDraft();
|
|
112
115
|
return currentEventId;
|
|
113
116
|
};
|
|
114
|
-
const discardPending = async () => {
|
|
115
|
-
stopped = true;
|
|
116
|
-
loop.stop();
|
|
117
|
-
await loop.waitForInFlight();
|
|
118
|
-
};
|
|
119
117
|
const reset = () => {
|
|
120
118
|
replyToId = params.preserveReplyId ? params.replyToId : void 0;
|
|
121
119
|
currentEventId = void 0;
|
|
122
120
|
lastSentText = "";
|
|
123
121
|
lastSentContent = "";
|
|
124
|
-
stopped = false;
|
|
122
|
+
streamState.stopped = false;
|
|
123
|
+
streamState.final = false;
|
|
125
124
|
sendFailed = false;
|
|
126
125
|
finalizeInPlaceBlocked = false;
|
|
127
126
|
liveFinalized = false;
|
|
@@ -129,10 +128,7 @@ function createMatrixDraftStream(params) {
|
|
|
129
128
|
loop.resetThrottleWindow();
|
|
130
129
|
};
|
|
131
130
|
return {
|
|
132
|
-
update
|
|
133
|
-
if (stopped) return;
|
|
134
|
-
loop.update(text);
|
|
135
|
-
},
|
|
131
|
+
update,
|
|
136
132
|
flush: loop.flush,
|
|
137
133
|
stop,
|
|
138
134
|
discardPending,
|
|
@@ -140,9 +136,10 @@ function createMatrixDraftStream(params) {
|
|
|
140
136
|
reset,
|
|
141
137
|
eventId: () => currentEventId,
|
|
142
138
|
content: () => lastSentContent || void 0,
|
|
143
|
-
matchesPreparedText: (text) => prepareMatrixSingleText(text, {
|
|
139
|
+
matchesPreparedText: (text) => prepareMatrixSingleText(text.trimEnd(), {
|
|
144
140
|
cfg,
|
|
145
|
-
accountId
|
|
141
|
+
accountId,
|
|
142
|
+
preserveWhitespace: true
|
|
146
143
|
}).trimmedText === lastSentText,
|
|
147
144
|
mustDeliverFinalNormally: () => sendFailed || finalizeInPlaceBlocked
|
|
148
145
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as resolveMatrixDefaultOrOnlyAccountId } from "./account-selection-
|
|
1
|
+
import { a as resolveMatrixDefaultOrOnlyAccountId } from "./account-selection-CWuhuFn1.js";
|
|
2
2
|
import { t as resolveMatrixConfigFieldPath } from "./config-paths-CnREYb1Y.js";
|
|
3
3
|
import { normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
|
|
4
4
|
//#region extensions/matrix/src/matrix/encryption-guidance.ts
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { t as getMatrixScopedEnvVarNames } from "./env-vars-
|
|
1
|
+
import { t as getMatrixScopedEnvVarNames } from "./env-vars-dGqak9dN.js";
|
|
2
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
3
|
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
|
3
4
|
//#region extensions/matrix/src/matrix/client/env-auth.ts
|
|
4
5
|
function cleanEnv(value) {
|
|
5
|
-
return
|
|
6
|
+
return normalizeOptionalString(value) ?? "";
|
|
6
7
|
}
|
|
7
8
|
function resolveGlobalMatrixEnvConfig(env) {
|
|
8
9
|
return {
|
|
@@ -60,4 +61,4 @@ function resolveMatrixEnvAuthReadiness(accountId, env = process.env) {
|
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
//#endregion
|
|
63
|
-
export {
|
|
64
|
+
export { resolveMatrixEnvAuthReadiness as n, resolveScopedMatrixEnvConfig as r, resolveGlobalMatrixEnvConfig as t };
|
|
@@ -31,7 +31,7 @@ function decodeMatrixEnvAccountToken(token) {
|
|
|
31
31
|
if (hexEscape) {
|
|
32
32
|
const hex = hexEscape[1];
|
|
33
33
|
const codePoint = hex ? Number.parseInt(hex, 16) : NaN;
|
|
34
|
-
if (!Number.
|
|
34
|
+
if (!Number.isInteger(codePoint) || codePoint > 1114111) return;
|
|
35
35
|
decoded += String.fromCodePoint(codePoint);
|
|
36
36
|
index += hexEscape[0].length;
|
|
37
37
|
continue;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
2
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
3
3
|
//#region extensions/matrix/src/matrix/errors.ts
|
|
4
|
-
function formatMatrixErrorMessage(err) {
|
|
5
|
-
return formatErrorMessage(err);
|
|
6
|
-
}
|
|
7
4
|
function formatMatrixErrorReason(err) {
|
|
8
|
-
return normalizeLowercaseStringOrEmpty(
|
|
5
|
+
return normalizeLowercaseStringOrEmpty(formatErrorMessage(err));
|
|
9
6
|
}
|
|
10
7
|
function isMatrixNotFoundError(err) {
|
|
11
8
|
const errObj = err;
|
|
@@ -14,4 +11,4 @@ function isMatrixNotFoundError(err) {
|
|
|
14
11
|
return message.includes("m_not_found") || message.includes("[404]") || message.includes("not found");
|
|
15
12
|
}
|
|
16
13
|
//#endregion
|
|
17
|
-
export {
|
|
14
|
+
export { isMatrixNotFoundError as n, formatMatrixErrorReason as t };
|