@openclaw/matrix 2026.7.1-beta.6 → 2026.7.2-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{account-selection-5e4mHR1m.js → account-selection-Bz00QTmQ.js} +4 -3
- package/dist/api.js +8 -8
- package/dist/{approval-handler.runtime-DI5x9r8I.js → approval-handler.runtime--Ei44Vo2.js} +27 -17
- package/dist/{approval-ids-ZgqbspmS.js → approval-ids-C_2kSMdJ.js} +1 -1
- package/dist/{approval-reaction-auth-D9LijQhr.js → approval-reaction-auth-TdVPcgxP.js} +2 -2
- package/dist/approval-reactions-BgU51JGd.js +202 -0
- package/dist/auth-presence.js +1 -1
- package/dist/{channel-jUTBsjHU.js → channel-CxqDh7mS.js} +102 -143
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-DO1Nv9ed.js → channel.runtime-wNfJc57I.js} +7 -7
- package/dist/{cli-metadata-CfiEO-CE.js → cli-metadata-Gf3HSJ2c.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{cli-CEfWwCKx.js → cli-o00oTJhx.js} +12 -12
- package/dist/{client-FRuyCNju.js → client-ClHisZbf.js} +2 -2
- package/dist/{client-tgnlQJk4.js → client-DP0nmFxK.js} +4 -4
- package/dist/{client-bootstrap-DjFJ7e0N.js → client-bootstrap-PqYOS-mO.js} +1 -1
- package/dist/{config-schema-DtnhNYd-.js → config-schema-CG9goLWp.js} +21 -55
- package/dist/contract-api.js +2 -2
- package/dist/{create-client-CNakT7zF.js → create-client-D9z9RjCM.js} +3 -3
- package/dist/{credentials-Ds9V1mn2.js → credentials-DnhsLAuR.js} +1 -1
- package/dist/{credentials-read-BlkvsNFg.js → credentials-read-BtS-HRT5.js} +3 -3
- package/dist/{credentials-write.runtime-CTqqxcut.js → credentials-write.runtime-J_EUt5WP.js} +1 -1
- package/dist/{crypto-runtime-B74cTS6A.js → crypto-runtime-BHcxauC4.js} +75 -45
- package/dist/{deps-CdjHvnmh.js → deps-DDbghaZH.js} +23 -90
- package/dist/{directory-live-Ufd4qSpX.js → directory-live-DPy2aaPF.js} +3 -3
- package/dist/doctor-BGTs609f.js +64 -0
- package/dist/{doctor-contract-BAja_fmb.js → doctor-contract-D2qTLe-C.js} +72 -6
- package/dist/doctor-contract-api.js +323 -45
- package/dist/{draft-stream-D4EH25gv.js → draft-stream-De7uikGn.js} +1 -1
- package/dist/{encryption-guidance-D8walY04.js → encryption-guidance-BFfgq7c7.js} +1 -1
- package/dist/{env-auth-DIzOApj0.js → env-auth-CQsYbz-p.js} +1 -1
- package/dist/{env-vars-KzaYveuy.js → env-vars-B0NxQnPk.js} +3 -1
- package/dist/{exec-approval-resolver-f9j6staN.js → exec-approval-resolver-BCgqRtZS.js} +2 -1
- package/dist/{file-sync-store-DVm0ACml.js → file-sync-store-Cxb0ckyX.js} +4 -5
- package/dist/helper-api.js +4 -4
- package/dist/{http-client-nSmFiVgk.js → http-client-W4TJQM6r.js} +17 -33
- package/dist/{idb-persistence-BHm97th-.js → idb-persistence-iUZoHZkp.js} +2 -2
- package/dist/inbound-dedupe-DcMs0YXL.js +67 -0
- package/dist/index.js +1 -1
- package/dist/{logger-D0GCSDQq.js → logger-BMClpI5b.js} +1 -1
- package/dist/{logging-QH-48Gr6.js → logging-CFJrbDAN.js} +1 -1
- package/dist/{media-text-p-LP21qs.js → media-text-DWaotsZB.js} +1 -1
- package/dist/{messages-DRKkiEY-.js → messages-Dm3K4ZvM.js} +3 -3
- package/dist/{monitor-CsGOGdwu.js → monitor-C_kgPPeV.js} +44 -382
- package/dist/plugin-entry.handlers.runtime.js +1 -1
- package/dist/probe.runtime-Dry8PTWC.js +3 -0
- package/dist/{profile-update-Ucc8RrJL.js → profile-update-iUHCoks3.js} +3 -3
- package/dist/{reaction-events-DentrVii.js → reaction-events-0tubdHRM.js} +60 -10
- package/dist/record-shared-CvzjvHRn.js +2 -0
- package/dist/{recovery-key-store-DSeLFvNx.js → recovery-key-store-Bx0zTJcB.js} +2 -2
- package/dist/{resolve-targets-DcV_KfgX.js → resolve-targets-DlLrfWDy.js} +1 -1
- package/dist/{resolver.runtime-Hr6bO5zl.js → resolver.runtime-MeaT1zXx.js} +1 -1
- package/dist/room-info-B6vKD5DF.js +86 -0
- package/dist/{runtime-6S3DNFNv.js → runtime-CveSqMOP.js} +1 -1
- package/dist/{runtime-api-CsBoesCU.js → runtime-api-D1xI_cvh.js} +3 -3
- package/dist/runtime-api.js +6 -6
- package/dist/runtime-setter-api.js +1 -1
- package/dist/{sdk-AZYVl34z.js → sdk-CI8E2TKg.js} +12 -17
- package/dist/{secret-contract-DTgQyQxc.js → secret-contract-OZoQf0kI.js} +7 -48
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-D92v6Yy0.js → send-C7xuGWpv.js} +10 -4
- package/dist/session-binding-contract-api.js +2 -2
- package/dist/{setup-bootstrap-Da564w5f.js → setup-bootstrap-CCsexWTZ.js} +2 -2
- package/dist/{setup-core-BGgbrdaJ.js → setup-core-DlmTyIP0.js} +9 -7
- package/dist/setup-plugin-api.js +3 -3
- package/dist/{setup-surface-iJ6pd-t5.js → setup-surface-2SS94JV0.js} +7 -7
- package/dist/{shared-DkFfq7mH.js → shared-DgvN5rBx.js} +14 -9
- package/dist/{startup-verification-BKMAXvcV.js → startup-verification-CbIyF7z1.js} +3 -4
- package/dist/storage-BtSOar8T.js +718 -0
- package/dist/{storage-paths-BWo_ZEMC.js → storage-paths-B4_I9iqO.js} +1 -12
- package/dist/{thread-bindings-BX5nmWpw.js → thread-bindings-BI8MHWp9.js} +4 -5
- package/dist/{tool-actions.runtime-C1d5fxE_.js → tool-actions.runtime-CnyhVPoY.js} +242 -53
- package/dist/{verification-BGCMiO1p.js → verification-DLSe3sP7.js} +2 -2
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +66 -55
- package/package.json +4 -4
- package/dist/approval-reactions-BdUaUXVw.js +0 -113
- package/dist/crypto-state-store-Jy3qwhdy.js +0 -352
- package/dist/doctor-DfaOqFtr.js +0 -167
- package/dist/legacy-crypto-inspector-vzXSkm18.js +0 -42
- package/dist/legacy-crypto-restore-CIBfOmLn.js +0 -93
- package/dist/matrix-migration.runtime-BMCyrANT.js +0 -524
- package/dist/migration-snapshot-backup-YcCrSjbE.js +0 -69
- package/dist/migration-snapshot.runtime-VGD4QfeS.js +0 -2
- package/dist/probe.runtime-2MZLc6ng.js +0 -3
- package/dist/runtime-heavy-api.js +0 -3
- package/dist/storage-CQdyKcGg.js +0 -430
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/matrix",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.2-beta.1",
|
|
4
4
|
"description": "OpenClaw Matrix channel plugin for rooms and direct messages.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"zod": "4.4.3"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"openclaw": ">=2026.7.
|
|
21
|
+
"openclaw": ">=2026.7.2-beta.1"
|
|
22
22
|
},
|
|
23
23
|
"peerDependenciesMeta": {
|
|
24
24
|
"openclaw": {
|
|
@@ -84,10 +84,10 @@
|
|
|
84
84
|
"allowInvalidConfigRecovery": true
|
|
85
85
|
},
|
|
86
86
|
"compat": {
|
|
87
|
-
"pluginApi": ">=2026.7.
|
|
87
|
+
"pluginApi": ">=2026.7.2-beta.1"
|
|
88
88
|
},
|
|
89
89
|
"build": {
|
|
90
|
-
"openclawVersion": "2026.7.
|
|
90
|
+
"openclawVersion": "2026.7.2-beta.1"
|
|
91
91
|
},
|
|
92
92
|
"release": {
|
|
93
93
|
"publishToClawHub": true,
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { n as getOptionalMatrixRuntime } from "./runtime-6S3DNFNv.js";
|
|
2
|
-
import { createApprovalReactionTargetStore } from "openclaw/plugin-sdk/approval-reaction-runtime";
|
|
3
|
-
//#region extensions/matrix/src/approval-reactions.ts
|
|
4
|
-
const MATRIX_APPROVAL_REACTION_META = {
|
|
5
|
-
"allow-once": {
|
|
6
|
-
emoji: "✅",
|
|
7
|
-
label: "Allow once"
|
|
8
|
-
},
|
|
9
|
-
"allow-always": {
|
|
10
|
-
emoji: "♾️",
|
|
11
|
-
label: "Allow always"
|
|
12
|
-
},
|
|
13
|
-
deny: {
|
|
14
|
-
emoji: "❌",
|
|
15
|
-
label: "Deny"
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
const MATRIX_APPROVAL_REACTION_ORDER = [
|
|
19
|
-
"allow-once",
|
|
20
|
-
"allow-always",
|
|
21
|
-
"deny"
|
|
22
|
-
];
|
|
23
|
-
const PERSISTENT_NAMESPACE = "matrix.approval-reactions";
|
|
24
|
-
const PERSISTENT_MAX_ENTRIES = 1e3;
|
|
25
|
-
const DEFAULT_REACTION_TARGET_TTL_MS = 1440 * 60 * 1e3;
|
|
26
|
-
function reportPersistentApprovalReactionError(error) {
|
|
27
|
-
try {
|
|
28
|
-
getOptionalMatrixRuntime()?.logging.getChildLogger({
|
|
29
|
-
plugin: "matrix",
|
|
30
|
-
feature: "approval-reaction-state"
|
|
31
|
-
}).warn("Matrix persistent approval reaction state failed", { error: String(error) });
|
|
32
|
-
} catch {}
|
|
33
|
-
}
|
|
34
|
-
function readPersistedTarget(target) {
|
|
35
|
-
const value = target;
|
|
36
|
-
if (!value || typeof value.approvalId !== "string" || !Array.isArray(value.allowedDecisions)) return null;
|
|
37
|
-
return {
|
|
38
|
-
approvalId: value.approvalId,
|
|
39
|
-
allowedDecisions: value.allowedDecisions
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
const matrixApprovalReactionTargets = createApprovalReactionTargetStore({
|
|
43
|
-
namespace: PERSISTENT_NAMESPACE,
|
|
44
|
-
maxEntries: PERSISTENT_MAX_ENTRIES,
|
|
45
|
-
defaultTtlMs: DEFAULT_REACTION_TARGET_TTL_MS,
|
|
46
|
-
openStore: (storeParams) => getOptionalMatrixRuntime()?.state.openKeyedStore(storeParams),
|
|
47
|
-
logPersistentError: reportPersistentApprovalReactionError,
|
|
48
|
-
readPersistedTarget
|
|
49
|
-
});
|
|
50
|
-
function buildReactionTargetKey(roomId, eventId) {
|
|
51
|
-
const normalizedRoomId = roomId.trim();
|
|
52
|
-
const normalizedEventId = eventId.trim();
|
|
53
|
-
if (!normalizedRoomId || !normalizedEventId) return null;
|
|
54
|
-
return `${normalizedRoomId}:${normalizedEventId}`;
|
|
55
|
-
}
|
|
56
|
-
function listMatrixApprovalReactionBindings(allowedDecisions) {
|
|
57
|
-
const allowed = new Set(allowedDecisions);
|
|
58
|
-
return MATRIX_APPROVAL_REACTION_ORDER.filter((decision) => allowed.has(decision)).map((decision) => ({
|
|
59
|
-
decision,
|
|
60
|
-
emoji: MATRIX_APPROVAL_REACTION_META[decision].emoji,
|
|
61
|
-
label: MATRIX_APPROVAL_REACTION_META[decision].label
|
|
62
|
-
}));
|
|
63
|
-
}
|
|
64
|
-
function buildMatrixApprovalReactionHint(allowedDecisions) {
|
|
65
|
-
const bindings = listMatrixApprovalReactionBindings(allowedDecisions);
|
|
66
|
-
if (bindings.length === 0) return null;
|
|
67
|
-
return `React here: ${bindings.map((binding) => `${binding.emoji} ${binding.label}`).join(", ")}`;
|
|
68
|
-
}
|
|
69
|
-
function resolveMatrixApprovalReactionDecision(reactionKey, allowedDecisions) {
|
|
70
|
-
const normalizedReaction = reactionKey.trim();
|
|
71
|
-
if (!normalizedReaction) return null;
|
|
72
|
-
const allowed = new Set(allowedDecisions);
|
|
73
|
-
for (const decision of MATRIX_APPROVAL_REACTION_ORDER) {
|
|
74
|
-
if (!allowed.has(decision)) continue;
|
|
75
|
-
if (MATRIX_APPROVAL_REACTION_META[decision].emoji === normalizedReaction) return decision;
|
|
76
|
-
}
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
function registerMatrixApprovalReactionTarget(params) {
|
|
80
|
-
const key = buildReactionTargetKey(params.roomId, params.eventId);
|
|
81
|
-
const approvalId = params.approvalId.trim();
|
|
82
|
-
const allowedDecisions = Array.from(new Set(params.allowedDecisions.filter((decision) => decision === "allow-once" || decision === "allow-always" || decision === "deny")));
|
|
83
|
-
if (!key || !approvalId || allowedDecisions.length === 0) return;
|
|
84
|
-
matrixApprovalReactionTargets.register(key, {
|
|
85
|
-
approvalId,
|
|
86
|
-
allowedDecisions
|
|
87
|
-
}, { ttlMs: params.ttlMs });
|
|
88
|
-
}
|
|
89
|
-
function unregisterMatrixApprovalReactionTarget(params) {
|
|
90
|
-
const key = buildReactionTargetKey(params.roomId, params.eventId);
|
|
91
|
-
if (!key) return;
|
|
92
|
-
matrixApprovalReactionTargets.delete(key);
|
|
93
|
-
}
|
|
94
|
-
function resolveTarget(params) {
|
|
95
|
-
const target = params.target;
|
|
96
|
-
if (!target) return null;
|
|
97
|
-
const decision = resolveMatrixApprovalReactionDecision(params.reactionKey, target.allowedDecisions);
|
|
98
|
-
if (!decision) return null;
|
|
99
|
-
return {
|
|
100
|
-
approvalId: target.approvalId,
|
|
101
|
-
decision
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
async function resolveMatrixApprovalReactionTargetWithPersistence(params) {
|
|
105
|
-
const key = buildReactionTargetKey(params.roomId, params.eventId);
|
|
106
|
-
if (!key) return null;
|
|
107
|
-
return resolveTarget({
|
|
108
|
-
target: await matrixApprovalReactionTargets.lookup(key),
|
|
109
|
-
reactionKey: params.reactionKey
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
//#endregion
|
|
113
|
-
export { unregisterMatrixApprovalReactionTarget as a, resolveMatrixApprovalReactionTargetWithPersistence as i, listMatrixApprovalReactionBindings as n, registerMatrixApprovalReactionTarget as r, buildMatrixApprovalReactionHint as t };
|
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
import { o as isRecord } from "./account-selection-5e4mHR1m.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 };
|
package/dist/doctor-DfaOqFtr.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { o as isRecord } from "./account-selection-5e4mHR1m.js";
|
|
2
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BAja_fmb.js";
|
|
3
|
-
import { i as autoPrepareLegacyMatrixCrypto, o as autoMigrateLegacyMatrixState, r as resolveMatrixMigrationStatus } from "./matrix-migration.runtime-BMCyrANT.js";
|
|
4
|
-
import { t as maybeCreateMatrixMigrationSnapshot } from "./migration-snapshot-backup-YcCrSjbE.js";
|
|
5
|
-
import { detectPluginInstallPathIssue, formatPluginInstallPathIssue, removePluginFromConfig } from "openclaw/plugin-sdk/runtime-doctor";
|
|
6
|
-
//#region extensions/matrix/src/doctor.ts
|
|
7
|
-
function hasConfiguredMatrixChannel(cfg) {
|
|
8
|
-
const channels = cfg.channels;
|
|
9
|
-
return isRecord(channels?.matrix);
|
|
10
|
-
}
|
|
11
|
-
function hasConfiguredMatrixPluginSurface(cfg) {
|
|
12
|
-
return Boolean(cfg.plugins?.installs?.matrix || cfg.plugins?.entries?.matrix || cfg.plugins?.allow?.includes("matrix") || cfg.plugins?.deny?.includes("matrix"));
|
|
13
|
-
}
|
|
14
|
-
function hasConfiguredMatrixEnv(env) {
|
|
15
|
-
return Object.entries(env).some(([key, value]) => key.startsWith("MATRIX_") && typeof value === "string" && value.trim());
|
|
16
|
-
}
|
|
17
|
-
function configMayNeedMatrixDoctorSequence(cfg, env) {
|
|
18
|
-
return hasConfiguredMatrixChannel(cfg) || hasConfiguredMatrixPluginSurface(cfg) || hasConfiguredMatrixEnv(env);
|
|
19
|
-
}
|
|
20
|
-
function formatMatrixLegacyStatePreview(detection) {
|
|
21
|
-
return [
|
|
22
|
-
"- Matrix plugin upgraded in place.",
|
|
23
|
-
`- Legacy sync store: ${detection.legacyStoragePath} -> ${detection.targetStoragePath}`,
|
|
24
|
-
`- Legacy crypto store: ${detection.legacyCryptoPath} -> ${detection.targetCryptoPath}`,
|
|
25
|
-
...detection.selectionNote ? [`- ${detection.selectionNote}`] : [],
|
|
26
|
-
"- Run \"openclaw doctor --fix\" to migrate this Matrix state now."
|
|
27
|
-
].join("\n");
|
|
28
|
-
}
|
|
29
|
-
function formatMatrixLegacyCryptoPreview(detection) {
|
|
30
|
-
const notes = [];
|
|
31
|
-
for (const warning of detection.warnings) notes.push(`- ${warning}`);
|
|
32
|
-
for (const plan of detection.plans) notes.push([
|
|
33
|
-
`- Matrix encrypted-state migration is pending for account "${plan.accountId}".`,
|
|
34
|
-
`- Legacy crypto store: ${plan.legacyCryptoPath}`,
|
|
35
|
-
`- Recovery key state: Matrix SQLite state (imports ${plan.recoveryKeyPath} if present)`,
|
|
36
|
-
`- Migration state: Matrix SQLite state (imports ${plan.statePath} if present)`,
|
|
37
|
-
"- Run \"openclaw doctor --fix\" to extract any saved backup key now. Backed-up room keys will restore automatically on next gateway start."
|
|
38
|
-
].join("\n"));
|
|
39
|
-
return notes;
|
|
40
|
-
}
|
|
41
|
-
async function collectMatrixInstallPathWarnings(cfg) {
|
|
42
|
-
const issue = await detectPluginInstallPathIssue({
|
|
43
|
-
pluginId: "matrix",
|
|
44
|
-
install: cfg.plugins?.installs?.matrix
|
|
45
|
-
});
|
|
46
|
-
if (!issue) return [];
|
|
47
|
-
return formatPluginInstallPathIssue({
|
|
48
|
-
issue,
|
|
49
|
-
pluginLabel: "Matrix",
|
|
50
|
-
defaultInstallCommand: "openclaw plugins install @openclaw/matrix"
|
|
51
|
-
}).map((entry) => `- ${entry}`);
|
|
52
|
-
}
|
|
53
|
-
async function cleanStaleMatrixPluginConfig(cfg) {
|
|
54
|
-
const issue = await detectPluginInstallPathIssue({
|
|
55
|
-
pluginId: "matrix",
|
|
56
|
-
install: cfg.plugins?.installs?.matrix
|
|
57
|
-
});
|
|
58
|
-
if (!issue || issue.kind !== "missing-path") return {
|
|
59
|
-
config: cfg,
|
|
60
|
-
changes: []
|
|
61
|
-
};
|
|
62
|
-
const { config, actions } = removePluginFromConfig(cfg, "matrix");
|
|
63
|
-
const removed = [];
|
|
64
|
-
if (actions.install) removed.push("install record");
|
|
65
|
-
if (actions.loadPath) removed.push("load path");
|
|
66
|
-
if (actions.entry) removed.push("plugin entry");
|
|
67
|
-
if (actions.allowlist) removed.push("allowlist entry");
|
|
68
|
-
if (removed.length === 0) return {
|
|
69
|
-
config: cfg,
|
|
70
|
-
changes: []
|
|
71
|
-
};
|
|
72
|
-
return {
|
|
73
|
-
config,
|
|
74
|
-
changes: [`Removed stale Matrix plugin references (${removed.join(", ")}). The previous install path no longer exists: ${issue.path}`]
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
async function applyMatrixDoctorRepair(params) {
|
|
78
|
-
const changes = [];
|
|
79
|
-
const warnings = [];
|
|
80
|
-
const migrationStatus = resolveMatrixMigrationStatus({
|
|
81
|
-
cfg: params.cfg,
|
|
82
|
-
env: params.env
|
|
83
|
-
});
|
|
84
|
-
let matrixSnapshotReady = true;
|
|
85
|
-
if (migrationStatus.actionable) try {
|
|
86
|
-
const snapshot = await maybeCreateMatrixMigrationSnapshot({
|
|
87
|
-
trigger: "doctor-fix",
|
|
88
|
-
env: params.env
|
|
89
|
-
});
|
|
90
|
-
changes.push(`Matrix migration snapshot ${snapshot.created ? "created" : "reused"} before applying Matrix upgrades.\n- ${snapshot.archivePath}`);
|
|
91
|
-
} catch (error) {
|
|
92
|
-
matrixSnapshotReady = false;
|
|
93
|
-
warnings.push(`- Failed creating a Matrix migration snapshot before repair: ${String(error)}`);
|
|
94
|
-
warnings.push("- Skipping Matrix migration changes for now. Resolve the snapshot failure, then rerun \"openclaw doctor --fix\".");
|
|
95
|
-
}
|
|
96
|
-
else if (migrationStatus.pending) warnings.push("- Matrix migration warnings are present, but no on-disk Matrix mutation is actionable yet. No pre-migration snapshot was needed.");
|
|
97
|
-
if (!matrixSnapshotReady) return {
|
|
98
|
-
changes,
|
|
99
|
-
warnings
|
|
100
|
-
};
|
|
101
|
-
const matrixStateRepair = await autoMigrateLegacyMatrixState({
|
|
102
|
-
cfg: params.cfg,
|
|
103
|
-
env: params.env
|
|
104
|
-
});
|
|
105
|
-
if (matrixStateRepair.changes.length > 0) changes.push([
|
|
106
|
-
"Matrix plugin upgraded in place.",
|
|
107
|
-
...matrixStateRepair.changes.map((entry) => `- ${entry}`),
|
|
108
|
-
"- No user action required."
|
|
109
|
-
].join("\n"));
|
|
110
|
-
if (matrixStateRepair.warnings.length > 0) warnings.push(matrixStateRepair.warnings.map((entry) => `- ${entry}`).join("\n"));
|
|
111
|
-
const matrixCryptoRepair = await autoPrepareLegacyMatrixCrypto({
|
|
112
|
-
cfg: params.cfg,
|
|
113
|
-
env: params.env
|
|
114
|
-
});
|
|
115
|
-
if (matrixCryptoRepair.changes.length > 0) changes.push(["Matrix encrypted-state migration prepared.", ...matrixCryptoRepair.changes.map((entry) => `- ${entry}`)].join("\n"));
|
|
116
|
-
if (matrixCryptoRepair.warnings.length > 0) warnings.push(matrixCryptoRepair.warnings.map((entry) => `- ${entry}`).join("\n"));
|
|
117
|
-
return {
|
|
118
|
-
changes,
|
|
119
|
-
warnings
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
async function runMatrixDoctorSequence(params) {
|
|
123
|
-
const warningNotes = [];
|
|
124
|
-
const changeNotes = [];
|
|
125
|
-
const installWarnings = await collectMatrixInstallPathWarnings(params.cfg);
|
|
126
|
-
if (installWarnings.length > 0) warningNotes.push(installWarnings.join("\n"));
|
|
127
|
-
if (!configMayNeedMatrixDoctorSequence(params.cfg, params.env)) return {
|
|
128
|
-
changeNotes,
|
|
129
|
-
warningNotes
|
|
130
|
-
};
|
|
131
|
-
if (params.shouldRepair) {
|
|
132
|
-
const repair = await applyMatrixDoctorRepair({
|
|
133
|
-
cfg: params.cfg,
|
|
134
|
-
env: params.env
|
|
135
|
-
});
|
|
136
|
-
changeNotes.push(...repair.changes);
|
|
137
|
-
warningNotes.push(...repair.warnings);
|
|
138
|
-
} else {
|
|
139
|
-
const migrationStatus = resolveMatrixMigrationStatus({
|
|
140
|
-
cfg: params.cfg,
|
|
141
|
-
env: params.env
|
|
142
|
-
});
|
|
143
|
-
if (migrationStatus.legacyState) if ("warning" in migrationStatus.legacyState) warningNotes.push(`- ${migrationStatus.legacyState.warning}`);
|
|
144
|
-
else warningNotes.push(formatMatrixLegacyStatePreview(migrationStatus.legacyState));
|
|
145
|
-
if (migrationStatus.legacyCrypto.warnings.length > 0 || migrationStatus.legacyCrypto.plans.length > 0) warningNotes.push(...formatMatrixLegacyCryptoPreview(migrationStatus.legacyCrypto));
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
changeNotes,
|
|
149
|
-
warningNotes
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
const matrixDoctor = {
|
|
153
|
-
dmAllowFromMode: "nestedOnly",
|
|
154
|
-
groupModel: "sender",
|
|
155
|
-
groupAllowFromFallbackToAllowFrom: false,
|
|
156
|
-
warnOnEmptyGroupSenderAllowlist: true,
|
|
157
|
-
legacyConfigRules,
|
|
158
|
-
normalizeCompatibilityConfig,
|
|
159
|
-
runConfigSequence: async ({ cfg, env, shouldRepair }) => await runMatrixDoctorSequence({
|
|
160
|
-
cfg,
|
|
161
|
-
env,
|
|
162
|
-
shouldRepair
|
|
163
|
-
}),
|
|
164
|
-
cleanStaleConfig: async ({ cfg }) => await cleanStaleMatrixPluginConfig(cfg)
|
|
165
|
-
};
|
|
166
|
-
//#endregion
|
|
167
|
-
export { applyMatrixDoctorRepair, cleanStaleMatrixPluginConfig, collectMatrixInstallPathWarnings, formatMatrixLegacyCryptoPreview, formatMatrixLegacyStatePreview, matrixDoctor, runMatrixDoctorSequence };
|