@openclaw/matrix 2026.3.13 → 2026.5.9-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.
Files changed (206) hide show
  1. package/dist/account-config-D2W-V1eQ.js +96 -0
  2. package/dist/account-selection-BWwIruri.js +158 -0
  3. package/dist/accounts-Bm90Rzvp.js +130 -0
  4. package/dist/active-client-uhlxdhEy.js +20 -0
  5. package/dist/allowlist-sTzpCn5d.js +68 -0
  6. package/dist/api.js +12 -0
  7. package/dist/approval-handler.runtime-DWTQfd4m.js +370 -0
  8. package/dist/approval-ids-DoC2z7tR.js +7 -0
  9. package/dist/approval-reaction-auth-DbcA1gGd.js +27 -0
  10. package/dist/approval-reactions-o2_tuH8D.js +162 -0
  11. package/dist/async-lock-uQfhfQIY.js +19 -0
  12. package/dist/auth-presence.js +26 -0
  13. package/dist/backup-health-Cabu_WQC.js +60 -0
  14. package/dist/channel-DJNir3Rb.js +1116 -0
  15. package/dist/channel-plugin-api.js +2 -0
  16. package/dist/channel.runtime-BQu0hTih.js +246 -0
  17. package/dist/cli-BmfTmg7x.js +1340 -0
  18. package/dist/cli-metadata-B-PCEzrA.js +22 -0
  19. package/dist/cli-metadata.js +2 -0
  20. package/dist/client-DkcXnm0X.js +25 -0
  21. package/dist/client-_hckQNGW.js +31 -0
  22. package/dist/client-bootstrap-Rb8oHvhH.js +114 -0
  23. package/dist/config--5-S2Akv.js +452 -0
  24. package/dist/config-paths-nsVaysCu.js +19 -0
  25. package/dist/config-schema-nPLpEgHl.js +200 -0
  26. package/dist/config-secret-input.runtime-DiKFehsE.js +2 -0
  27. package/dist/config-update-wZX-HLMn.js +143 -0
  28. package/dist/contract-api.js +9 -0
  29. package/dist/create-client-DCnqDaqd.js +64 -0
  30. package/dist/credentials-DV6fWXhC.js +56 -0
  31. package/dist/credentials-read-cmHgousK.js +112 -0
  32. package/dist/credentials-write.runtime-zniTq-Gr.js +17 -0
  33. package/dist/crypto-node.runtime-pihzdpY7.js +12 -0
  34. package/dist/crypto-runtime-ZI0zAtn3.js +1214 -0
  35. package/dist/deps-C6WqKY7m.js +235 -0
  36. package/dist/device-health-UVYpbA_W.js +16 -0
  37. package/dist/direct-management-DMMMgtTB.js +249 -0
  38. package/dist/direct-room-XkutHjES.js +76 -0
  39. package/dist/directory-live-DmOtMhyr.js +150 -0
  40. package/dist/doctor-C4__7c-U.js +153 -0
  41. package/dist/doctor-contract-D4-64QuJ.js +246 -0
  42. package/dist/doctor-contract-api.js +2 -0
  43. package/dist/draft-stream-BE2QevQQ.js +144 -0
  44. package/dist/encryption-guidance-BPi3A_m3.js +15 -0
  45. package/dist/env-auth-BJqGI8M6.js +63 -0
  46. package/dist/env-vars-C7uQCTKn.js +63 -0
  47. package/dist/errors-CTcpEDq-.js +17 -0
  48. package/dist/exec-approval-resolver-Bza9Dhlm.js +15 -0
  49. package/dist/exec-approvals-Crnh543m.js +196 -0
  50. package/dist/helper-api.js +4 -0
  51. package/dist/http-client-C7AeVJay.js +319 -0
  52. package/dist/index.js +46 -0
  53. package/dist/legacy-crypto-inspector-poDWldgy.js +41 -0
  54. package/dist/legacy-crypto-restore-Biw-w2ng.js +85 -0
  55. package/dist/logger-CnZRVrux.js +78 -0
  56. package/dist/logging-DZHSPP5N.js +99 -0
  57. package/dist/matrix-migration.runtime-WY6ffcrf.js +525 -0
  58. package/dist/media-text-DU6nWZuj.js +146 -0
  59. package/dist/messages-BpihMh82.js +140 -0
  60. package/dist/migration-snapshot-backup-DaCHTp8C.js +69 -0
  61. package/dist/migration-snapshot.runtime-CKHE3xF9.js +2 -0
  62. package/dist/monitor-C_81r_Ck.js +4125 -0
  63. package/dist/plugin-entry.handlers.runtime.js +51 -0
  64. package/dist/probe.runtime-BvAzYAIe.js +3 -0
  65. package/dist/profile-BlHu0wDX.js +111 -0
  66. package/dist/profile-update-DjeBNgIV.js +69 -0
  67. package/dist/reaction-common-ejrL19w-.js +71 -0
  68. package/dist/reaction-events-CiARZfjk.js +121 -0
  69. package/dist/record-shared-CHWJCTWf.js +2 -0
  70. package/dist/recovery-key-store-BTJ6jz5v.js +294 -0
  71. package/dist/resolve-targets-YtJnw1Tb.js +140 -0
  72. package/dist/resolver.runtime-D9piiGEl.js +5 -0
  73. package/dist/rolldown-runtime-DUslC3ob.js +14 -0
  74. package/dist/route-D6rg-iXN.js +161 -0
  75. package/dist/runtime-C6X4h_SJ.js +6 -0
  76. package/dist/runtime-Dog86njy.js +8 -0
  77. package/dist/runtime-api-BXWBFIqm.js +25 -0
  78. package/dist/runtime-api.js +25 -0
  79. package/dist/runtime-heavy-api.js +3 -0
  80. package/dist/runtime-setter-api.js +2 -0
  81. package/dist/sdk-B2vZA27-.js +1416 -0
  82. package/dist/secret-contract-DcrJWCQI.js +120 -0
  83. package/dist/secret-contract-api.js +2 -0
  84. package/dist/send-Bo0DU1ca.js +1200 -0
  85. package/dist/session-store-metadata-DI5SCofx.js +77 -0
  86. package/dist/setup-bootstrap-ImenBsMt.js +62 -0
  87. package/dist/setup-core-CfZy05oW.js +116 -0
  88. package/dist/setup-dm-policy-2-r1FrQh.js +194 -0
  89. package/dist/setup-entry.js +19 -0
  90. package/dist/setup-plugin-api.js +44 -0
  91. package/dist/setup-surface-CqT_o61M.js +540 -0
  92. package/dist/shared-CpMoYKm1.js +195 -0
  93. package/dist/startup-abort-56edvmbM.js +32 -0
  94. package/dist/startup-verification-Demyp0bP.js +132 -0
  95. package/dist/storage-paths-BJLdnCjV.js +52 -0
  96. package/dist/storage-tC3ujLiW.js +281 -0
  97. package/dist/subagent-hooks-DQbyqq9V.js +149 -0
  98. package/dist/subagent-hooks-api.js +23 -0
  99. package/dist/sync-state-C_beeevA.js +12 -0
  100. package/dist/target-ids-80nQ2gql.js +77 -0
  101. package/dist/test-api.js +4 -0
  102. package/dist/thread-binding-api-Cq_E-E1K.js +17 -0
  103. package/dist/thread-binding-api.js +2 -0
  104. package/dist/thread-bindings-B9mesxXk.js +352 -0
  105. package/dist/thread-bindings-runtime.js +2 -0
  106. package/dist/thread-bindings-shared-DK-d-oYX.js +97 -0
  107. package/dist/timeout-abort-signal-CtaIaP1v.js +2 -0
  108. package/dist/tool-actions.runtime-BIH49vRr.js +532 -0
  109. package/dist/url-validation-DiK9j7jz.js +36 -0
  110. package/dist/verification-CZ2rDeHL.js +345 -0
  111. package/openclaw.plugin.json +788 -1
  112. package/package.json +82 -16
  113. package/CHANGELOG.md +0 -104
  114. package/index.ts +0 -22
  115. package/src/actions.ts +0 -195
  116. package/src/channel.directory.test.ts +0 -135
  117. package/src/channel.ts +0 -461
  118. package/src/config-schema.test.ts +0 -26
  119. package/src/config-schema.ts +0 -62
  120. package/src/directory-live.test.ts +0 -85
  121. package/src/directory-live.ts +0 -209
  122. package/src/group-mentions.ts +0 -52
  123. package/src/matrix/accounts.test.ts +0 -131
  124. package/src/matrix/accounts.ts +0 -114
  125. package/src/matrix/actions/client.ts +0 -47
  126. package/src/matrix/actions/limits.test.ts +0 -15
  127. package/src/matrix/actions/limits.ts +0 -6
  128. package/src/matrix/actions/messages.ts +0 -126
  129. package/src/matrix/actions/pins.test.ts +0 -74
  130. package/src/matrix/actions/pins.ts +0 -84
  131. package/src/matrix/actions/reactions.test.ts +0 -109
  132. package/src/matrix/actions/reactions.ts +0 -102
  133. package/src/matrix/actions/room.ts +0 -85
  134. package/src/matrix/actions/summary.ts +0 -75
  135. package/src/matrix/actions/types.ts +0 -85
  136. package/src/matrix/actions.ts +0 -15
  137. package/src/matrix/active-client.ts +0 -32
  138. package/src/matrix/client/config.ts +0 -245
  139. package/src/matrix/client/create-client.ts +0 -125
  140. package/src/matrix/client/logging.ts +0 -46
  141. package/src/matrix/client/runtime.ts +0 -4
  142. package/src/matrix/client/shared.test.ts +0 -85
  143. package/src/matrix/client/shared.ts +0 -210
  144. package/src/matrix/client/startup.test.ts +0 -49
  145. package/src/matrix/client/startup.ts +0 -29
  146. package/src/matrix/client/storage.ts +0 -131
  147. package/src/matrix/client/types.ts +0 -34
  148. package/src/matrix/client-bootstrap.ts +0 -47
  149. package/src/matrix/client.test.ts +0 -56
  150. package/src/matrix/client.ts +0 -14
  151. package/src/matrix/credentials.ts +0 -125
  152. package/src/matrix/deps.test.ts +0 -74
  153. package/src/matrix/deps.ts +0 -126
  154. package/src/matrix/format.test.ts +0 -33
  155. package/src/matrix/format.ts +0 -22
  156. package/src/matrix/index.ts +0 -11
  157. package/src/matrix/monitor/access-policy.ts +0 -126
  158. package/src/matrix/monitor/allowlist.test.ts +0 -45
  159. package/src/matrix/monitor/allowlist.ts +0 -94
  160. package/src/matrix/monitor/auto-join.ts +0 -72
  161. package/src/matrix/monitor/direct.test.ts +0 -396
  162. package/src/matrix/monitor/direct.ts +0 -152
  163. package/src/matrix/monitor/events.test.ts +0 -186
  164. package/src/matrix/monitor/events.ts +0 -168
  165. package/src/matrix/monitor/handler.body-for-agent.test.ts +0 -196
  166. package/src/matrix/monitor/handler.ts +0 -768
  167. package/src/matrix/monitor/inbound-body.test.ts +0 -73
  168. package/src/matrix/monitor/inbound-body.ts +0 -28
  169. package/src/matrix/monitor/index.test.ts +0 -18
  170. package/src/matrix/monitor/index.ts +0 -414
  171. package/src/matrix/monitor/location.ts +0 -100
  172. package/src/matrix/monitor/media.test.ts +0 -86
  173. package/src/matrix/monitor/media.ts +0 -118
  174. package/src/matrix/monitor/mentions.test.ts +0 -154
  175. package/src/matrix/monitor/mentions.ts +0 -62
  176. package/src/matrix/monitor/replies.test.ts +0 -184
  177. package/src/matrix/monitor/replies.ts +0 -124
  178. package/src/matrix/monitor/room-info.ts +0 -55
  179. package/src/matrix/monitor/rooms.test.ts +0 -124
  180. package/src/matrix/monitor/rooms.ts +0 -47
  181. package/src/matrix/monitor/threads.ts +0 -68
  182. package/src/matrix/monitor/types.ts +0 -39
  183. package/src/matrix/poll-types.test.ts +0 -21
  184. package/src/matrix/poll-types.ts +0 -167
  185. package/src/matrix/probe.ts +0 -69
  186. package/src/matrix/sdk-runtime.ts +0 -18
  187. package/src/matrix/send/client.ts +0 -99
  188. package/src/matrix/send/formatting.ts +0 -93
  189. package/src/matrix/send/media.ts +0 -230
  190. package/src/matrix/send/targets.test.ts +0 -98
  191. package/src/matrix/send/targets.ts +0 -150
  192. package/src/matrix/send/types.ts +0 -110
  193. package/src/matrix/send-queue.test.ts +0 -145
  194. package/src/matrix/send-queue.ts +0 -28
  195. package/src/matrix/send.test.ts +0 -319
  196. package/src/matrix/send.ts +0 -267
  197. package/src/onboarding.ts +0 -462
  198. package/src/outbound.test.ts +0 -159
  199. package/src/outbound.ts +0 -58
  200. package/src/resolve-targets.test.ts +0 -68
  201. package/src/resolve-targets.ts +0 -125
  202. package/src/runtime.ts +0 -6
  203. package/src/secret-input.ts +0 -13
  204. package/src/test-mocks.ts +0 -53
  205. package/src/tool-actions.ts +0 -164
  206. package/src/types.ts +0 -118
@@ -0,0 +1,1116 @@
1
+ import { a as resolveMatrixTargetIdentity, i as resolveMatrixDirectUserId, n as normalizeMatrixMessagingTarget, r as normalizeMatrixResolvableTarget } from "./target-ids-80nQ2gql.js";
2
+ import { d as setMatrixThreadBindingIdleTimeoutBySessionKey, p as setMatrixThreadBindingMaxAgeBySessionKey } from "./thread-bindings-shared-DK-d-oYX.js";
3
+ import { n as requiresExplicitMatrixDefaultAccount } from "./account-selection-BWwIruri.js";
4
+ import { a as resolveMatrixAccountConfig } from "./account-config-D2W-V1eQ.js";
5
+ import { i as resolveMatrixAccount, r as resolveDefaultMatrixAccountId, t as listMatrixAccountIds } from "./accounts-Bm90Rzvp.js";
6
+ import { n as normalizeMatrixUserId } from "./allowlist-sTzpCn5d.js";
7
+ import { t as normalizeMatrixApproverId } from "./approval-ids-DoC2z7tR.js";
8
+ import { a as isMatrixExecApprovalAuthorizedSender, c as shouldHandleMatrixApprovalRequest, d as matrixApprovalAuth, i as isMatrixApprovalClientEnabled, l as shouldSuppressLocalMatrixExecApprovalPrompt, n as getMatrixExecApprovalApprovers, o as isMatrixExecApprovalClientEnabled, r as isMatrixAnyApprovalClientEnabled, s as resolveMatrixExecApprovalTarget, t as getMatrixApprovalApprovers, u as getMatrixApprovalAuthApprovers } from "./exec-approvals-Crnh543m.js";
9
+ import { t as formatMatrixErrorMessage } from "./errors-CTcpEDq-.js";
10
+ import { n as DEFAULT_ACCOUNT_ID$2, r as matrixConfigAdapter, t as MatrixChannelConfigSchema } from "./config-schema-nPLpEgHl.js";
11
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-D4-64QuJ.js";
12
+ import { n as resolveMatrixRoomConfig, t as resolveMatrixStoredSessionMeta } from "./session-store-metadata-DI5SCofx.js";
13
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DcrJWCQI.js";
14
+ import { a as namedAccountPromotionKeys, o as resolveSingleAccountPromotionTarget, s as singleAccountKeysToMove } from "./setup-dm-policy-2-r1FrQh.js";
15
+ import { n as matrixSetupAdapter, t as createMatrixSetupWizardProxy } from "./setup-core-CfZy05oW.js";
16
+ import { i as autoPrepareLegacyMatrixCrypto, o as autoMigrateLegacyMatrixState, r as resolveMatrixMigrationStatus } from "./matrix-migration.runtime-WY6ffcrf.js";
17
+ import { t as maybeCreateMatrixMigrationSnapshot } from "./migration-snapshot-backup-DaCHTp8C.js";
18
+ import { n as resolveMatrixInboundConversation } from "./thread-binding-api-Cq_E-E1K.js";
19
+ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
20
+ import { createScopedAccountReplyToModeResolver } from "openclaw/plugin-sdk/conversation-runtime";
21
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
22
+ import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
23
+ import { adaptScopedAccountAccessor, createScopedDmSecurityResolver } from "openclaw/plugin-sdk/channel-config-helpers";
24
+ import { buildChannelOutboundSessionRoute, buildThreadAwareOutboundSessionRoute, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
25
+ import { createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-message";
26
+ import { createAllowlistProviderOpenWarningCollector, projectAccountConfigWarningCollector } from "openclaw/plugin-sdk/channel-policy";
27
+ import { createChannelDirectoryAdapter, createResolvedDirectoryEntriesLister, createRuntimeDirectoryLiveAdapter } from "openclaw/plugin-sdk/directory-runtime";
28
+ import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
29
+ import { createRuntimeOutboundDelegates } from "openclaw/plugin-sdk/outbound-runtime";
30
+ import { buildProbeChannelStatusSummary, collectStatusIssuesFromLastError, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
31
+ import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
32
+ import { ToolAuthorizationError, createActionGate, readNumberParam, readStringParam } from "openclaw/plugin-sdk/channel-actions";
33
+ import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
34
+ import { Type } from "typebox";
35
+ import { createApproverRestrictedNativeApprovalCapability, createChannelApprovalCapability, splitChannelApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
36
+ import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
37
+ import { createChannelNativeOriginTargetResolver, resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
38
+ import { parseThreadSessionSuffix } from "openclaw/plugin-sdk/routing";
39
+ import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
40
+ import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
41
+ import { loadSessionStore, resolveSessionStoreEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
42
+ //#region extensions/matrix/src/actions.ts
43
+ const MATRIX_PLUGIN_HANDLED_ACTIONS = new Set([
44
+ "send",
45
+ "poll-vote",
46
+ "react",
47
+ "reactions",
48
+ "read",
49
+ "edit",
50
+ "delete",
51
+ "pin",
52
+ "unpin",
53
+ "list-pins",
54
+ "set-profile",
55
+ "member-info",
56
+ "channel-info",
57
+ "permissions"
58
+ ]);
59
+ const MATRIX_PROFILE_MEDIA_PROPERTIES = {
60
+ avatarUrl: Type.Optional(Type.String({ description: "Profile avatar URL for Matrix self-profile update actions. Matrix accepts mxc:// and http(s) URLs." })),
61
+ avatar_url: Type.Optional(Type.String({ description: "snake_case alias of avatarUrl for Matrix self-profile update actions. Matrix accepts mxc:// and http(s) URLs." })),
62
+ avatarPath: Type.Optional(Type.String({ description: "Local avatar file path for Matrix self-profile update actions. Matrix uploads this file and sets the resulting MXC URI." })),
63
+ avatar_path: Type.Optional(Type.String({ description: "snake_case alias of avatarPath for Matrix self-profile update actions. Matrix uploads this file and sets the resulting MXC URI." }))
64
+ };
65
+ const MATRIX_PROFILE_MEDIA_SOURCE_PARAMS = Object.freeze(["avatarUrl", "avatarPath"]);
66
+ function createMatrixExposedActions(params) {
67
+ const actions = new Set(["poll", "poll-vote"]);
68
+ if (params.gate("messages")) {
69
+ actions.add("send");
70
+ actions.add("read");
71
+ actions.add("edit");
72
+ actions.add("delete");
73
+ }
74
+ if (params.gate("reactions")) {
75
+ actions.add("react");
76
+ actions.add("reactions");
77
+ }
78
+ if (params.gate("pins")) {
79
+ actions.add("pin");
80
+ actions.add("unpin");
81
+ actions.add("list-pins");
82
+ }
83
+ if (params.gate("profile") && params.senderIsOwner === true) actions.add("set-profile");
84
+ if (params.gate("memberInfo")) actions.add("member-info");
85
+ if (params.gate("channelInfo")) actions.add("channel-info");
86
+ if (params.encryptionEnabled && params.gate("verification")) actions.add("permissions");
87
+ return actions;
88
+ }
89
+ function buildMatrixProfileToolSchema() {
90
+ return {
91
+ actions: ["set-profile"],
92
+ properties: {
93
+ displayName: Type.Optional(Type.String({ description: "Profile display name for Matrix self-profile update actions." })),
94
+ display_name: Type.Optional(Type.String({ description: "snake_case alias of displayName for Matrix self-profile update actions." })),
95
+ ...MATRIX_PROFILE_MEDIA_PROPERTIES
96
+ }
97
+ };
98
+ }
99
+ const matrixMessageActions = {
100
+ describeMessageTool: ({ cfg, accountId, senderIsOwner }) => {
101
+ const resolvedCfg = cfg;
102
+ if (!accountId && requiresExplicitMatrixDefaultAccount(resolvedCfg)) return {
103
+ actions: [],
104
+ capabilities: []
105
+ };
106
+ const account = resolveMatrixAccount({
107
+ cfg: resolvedCfg,
108
+ accountId: accountId ?? resolveDefaultMatrixAccountId(resolvedCfg)
109
+ });
110
+ if (!account.enabled || !account.configured) return {
111
+ actions: [],
112
+ capabilities: []
113
+ };
114
+ const actions = createMatrixExposedActions({
115
+ gate: createActionGate(account.config.actions),
116
+ encryptionEnabled: account.config.encryption === true,
117
+ senderIsOwner
118
+ });
119
+ const listedActions = Array.from(actions);
120
+ return {
121
+ actions: listedActions,
122
+ capabilities: [],
123
+ schema: listedActions.includes("set-profile") ? buildMatrixProfileToolSchema() : null,
124
+ mediaSourceParams: listedActions.includes("set-profile") ? { "set-profile": MATRIX_PROFILE_MEDIA_SOURCE_PARAMS } : null
125
+ };
126
+ },
127
+ supportsAction: ({ action }) => MATRIX_PLUGIN_HANDLED_ACTIONS.has(action),
128
+ extractToolSend: ({ args }) => {
129
+ return extractToolSend(args, "sendMessage");
130
+ },
131
+ handleAction: async (ctx) => {
132
+ const { handleMatrixAction } = await import("./tool-actions.runtime-BIH49vRr.js");
133
+ const { action, params, cfg, accountId, mediaLocalRoots } = ctx;
134
+ const dispatch = async (actionParams) => await handleMatrixAction({
135
+ ...actionParams,
136
+ ...accountId ? { accountId } : {}
137
+ }, cfg, { mediaLocalRoots });
138
+ const resolveRoomId = () => readStringParam(params, "roomId") ?? readStringParam(params, "channelId") ?? readStringParam(params, "to", { required: true });
139
+ if (action === "send") {
140
+ const to = readStringParam(params, "to", { required: true });
141
+ const mediaUrl = readStringParam(params, "media", { trim: false }) ?? readStringParam(params, "mediaUrl", { trim: false }) ?? readStringParam(params, "filePath", { trim: false }) ?? readStringParam(params, "path", { trim: false });
142
+ const content = readStringParam(params, "message", {
143
+ required: !mediaUrl,
144
+ allowEmpty: true
145
+ });
146
+ const replyTo = readStringParam(params, "replyTo");
147
+ const threadId = readStringParam(params, "threadId");
148
+ const audioAsVoice = typeof params.asVoice === "boolean" ? params.asVoice : typeof params.audioAsVoice === "boolean" ? params.audioAsVoice : void 0;
149
+ return await dispatch({
150
+ action: "sendMessage",
151
+ to,
152
+ content,
153
+ mediaUrl: mediaUrl ?? void 0,
154
+ replyToId: replyTo ?? void 0,
155
+ threadId: threadId ?? void 0,
156
+ audioAsVoice
157
+ });
158
+ }
159
+ if (action === "poll-vote") return await dispatch({
160
+ ...params,
161
+ action: "pollVote"
162
+ });
163
+ if (action === "react") {
164
+ const messageId = readStringParam(params, "messageId", { required: true });
165
+ const emoji = readStringParam(params, "emoji", { allowEmpty: true });
166
+ const remove = typeof params.remove === "boolean" ? params.remove : void 0;
167
+ return await dispatch({
168
+ action: "react",
169
+ roomId: resolveRoomId(),
170
+ messageId,
171
+ emoji,
172
+ remove
173
+ });
174
+ }
175
+ if (action === "reactions") {
176
+ const messageId = readStringParam(params, "messageId", { required: true });
177
+ const limit = readNumberParam(params, "limit", { integer: true });
178
+ return await dispatch({
179
+ action: "reactions",
180
+ roomId: resolveRoomId(),
181
+ messageId,
182
+ limit
183
+ });
184
+ }
185
+ if (action === "read") {
186
+ const limit = readNumberParam(params, "limit", { integer: true });
187
+ return await dispatch({
188
+ action: "readMessages",
189
+ roomId: resolveRoomId(),
190
+ limit,
191
+ before: readStringParam(params, "before"),
192
+ after: readStringParam(params, "after")
193
+ });
194
+ }
195
+ if (action === "edit") {
196
+ const messageId = readStringParam(params, "messageId", { required: true });
197
+ const content = readStringParam(params, "message", { required: true });
198
+ return await dispatch({
199
+ action: "editMessage",
200
+ roomId: resolveRoomId(),
201
+ messageId,
202
+ content
203
+ });
204
+ }
205
+ if (action === "delete") {
206
+ const messageId = readStringParam(params, "messageId", { required: true });
207
+ return await dispatch({
208
+ action: "deleteMessage",
209
+ roomId: resolveRoomId(),
210
+ messageId
211
+ });
212
+ }
213
+ if (action === "pin" || action === "unpin" || action === "list-pins") {
214
+ const messageId = action === "list-pins" ? void 0 : readStringParam(params, "messageId", { required: true });
215
+ return await dispatch({
216
+ action: action === "pin" ? "pinMessage" : action === "unpin" ? "unpinMessage" : "listPins",
217
+ roomId: resolveRoomId(),
218
+ messageId
219
+ });
220
+ }
221
+ if (action === "set-profile") {
222
+ if (ctx.senderIsOwner !== true) throw new ToolAuthorizationError("Matrix profile updates require owner access.");
223
+ const avatarPath = readStringParam(params, "avatarPath") ?? readStringParam(params, "path") ?? readStringParam(params, "filePath");
224
+ return await dispatch({
225
+ action: "setProfile",
226
+ displayName: readStringParam(params, "displayName") ?? readStringParam(params, "name"),
227
+ avatarUrl: readStringParam(params, "avatarUrl"),
228
+ avatarPath
229
+ });
230
+ }
231
+ if (action === "member-info") return await dispatch({
232
+ action: "memberInfo",
233
+ userId: readStringParam(params, "userId", { required: true }),
234
+ roomId: readStringParam(params, "roomId") ?? readStringParam(params, "channelId")
235
+ });
236
+ if (action === "channel-info") return await dispatch({
237
+ action: "channelInfo",
238
+ roomId: resolveRoomId()
239
+ });
240
+ if (action === "permissions") {
241
+ const operation = normalizeLowercaseStringOrEmpty(readStringParam(params, "operation") ?? readStringParam(params, "mode") ?? "verification-list");
242
+ const operationToAction = {
243
+ "encryption-status": "encryptionStatus",
244
+ "verification-status": "verificationStatus",
245
+ "verification-bootstrap": "verificationBootstrap",
246
+ "verification-recovery-key": "verificationRecoveryKey",
247
+ "verification-backup-status": "verificationBackupStatus",
248
+ "verification-backup-restore": "verificationBackupRestore",
249
+ "verification-list": "verificationList",
250
+ "verification-request": "verificationRequest",
251
+ "verification-accept": "verificationAccept",
252
+ "verification-cancel": "verificationCancel",
253
+ "verification-start": "verificationStart",
254
+ "verification-generate-qr": "verificationGenerateQr",
255
+ "verification-scan-qr": "verificationScanQr",
256
+ "verification-sas": "verificationSas",
257
+ "verification-confirm": "verificationConfirm",
258
+ "verification-mismatch": "verificationMismatch",
259
+ "verification-confirm-qr": "verificationConfirmQr"
260
+ };
261
+ const resolvedAction = operationToAction[operation];
262
+ if (!resolvedAction) throw new Error(`Unsupported Matrix permissions operation: ${operation}. Supported values: ${Object.keys(operationToAction).join(", ")}`);
263
+ return await dispatch({
264
+ ...params,
265
+ action: resolvedAction
266
+ });
267
+ }
268
+ throw new Error(`Action ${action} is not supported for provider matrix.`);
269
+ }
270
+ };
271
+ //#endregion
272
+ //#region extensions/matrix/src/approval-native.ts
273
+ function normalizeComparableTarget(value) {
274
+ const target = resolveMatrixTargetIdentity(value);
275
+ if (!target) return normalizeLowercaseStringOrEmpty(value);
276
+ if (target.kind === "user") return `user:${normalizeMatrixUserId(target.id)}`;
277
+ return `${normalizeLowercaseStringOrEmpty(target.kind)}:${target.id}`;
278
+ }
279
+ function resolveMatrixNativeTarget(raw) {
280
+ const target = resolveMatrixTargetIdentity(raw);
281
+ if (!target) return null;
282
+ return target.kind === "user" ? `user:${target.id}` : `room:${target.id}`;
283
+ }
284
+ function resolveTurnSourceMatrixOriginTarget(request) {
285
+ const turnSourceChannel = normalizeLowercaseStringOrEmpty(request.request.turnSourceChannel);
286
+ const target = resolveMatrixNativeTarget(request.request.turnSourceTo?.trim() || "");
287
+ if (turnSourceChannel !== "matrix" || !target) return null;
288
+ return {
289
+ to: target,
290
+ threadId: normalizeOptionalStringifiedId(request.request.turnSourceThreadId)
291
+ };
292
+ }
293
+ function resolveSessionMatrixOriginTarget(sessionTarget) {
294
+ const target = resolveMatrixNativeTarget(sessionTarget.to);
295
+ if (!target) return null;
296
+ return {
297
+ to: target,
298
+ threadId: normalizeOptionalStringifiedId(sessionTarget.threadId)
299
+ };
300
+ }
301
+ function normalizeMatrixOriginTarget(target) {
302
+ return {
303
+ ...target,
304
+ to: normalizeComparableTarget(target.to)
305
+ };
306
+ }
307
+ function hasMatrixPluginApprovers(params) {
308
+ return getMatrixApprovalAuthApprovers(params).length > 0;
309
+ }
310
+ function availabilityState(enabled) {
311
+ return enabled ? { kind: "enabled" } : { kind: "disabled" };
312
+ }
313
+ function hasMatrixApprovalApprovers(params) {
314
+ return getMatrixApprovalApprovers({
315
+ cfg: params.cfg,
316
+ accountId: params.accountId,
317
+ approvalKind: params.approvalKind
318
+ }).length > 0;
319
+ }
320
+ function hasAnyMatrixApprovalApprovers(params) {
321
+ return getMatrixExecApprovalApprovers(params).length > 0 || getMatrixApprovalAuthApprovers(params).length > 0;
322
+ }
323
+ function isMatrixPluginAuthorizedSender(params) {
324
+ const normalizedSenderId = params.senderId ? normalizeMatrixApproverId(params.senderId) : void 0;
325
+ if (!normalizedSenderId) return false;
326
+ return getMatrixApprovalAuthApprovers(params).includes(normalizedSenderId);
327
+ }
328
+ function resolveSuppressionAccountId(params) {
329
+ return params.target.accountId?.trim() || params.request.request.turnSourceAccountId?.trim() || void 0;
330
+ }
331
+ const resolveMatrixOriginTarget = createChannelNativeOriginTargetResolver({
332
+ channel: "matrix",
333
+ shouldHandleRequest: ({ cfg, accountId, request }) => shouldHandleMatrixApprovalRequest({
334
+ cfg,
335
+ accountId,
336
+ request
337
+ }),
338
+ resolveTurnSourceTarget: resolveTurnSourceMatrixOriginTarget,
339
+ resolveSessionTarget: resolveSessionMatrixOriginTarget,
340
+ normalizeTargetForMatch: normalizeMatrixOriginTarget,
341
+ resolveFallbackTarget: (request) => {
342
+ const sessionConversation = resolveApprovalRequestSessionConversation({
343
+ request,
344
+ channel: "matrix"
345
+ });
346
+ if (!sessionConversation) return null;
347
+ const target = resolveMatrixNativeTarget(sessionConversation.id);
348
+ if (!target) return null;
349
+ return {
350
+ to: target,
351
+ threadId: normalizeOptionalStringifiedId(sessionConversation.threadId)
352
+ };
353
+ }
354
+ });
355
+ function resolveMatrixApproverDmTargets(params) {
356
+ if (!shouldHandleMatrixApprovalRequest(params)) return [];
357
+ return getMatrixApprovalApprovers(params).map((approver) => {
358
+ const normalized = normalizeMatrixUserId(approver);
359
+ return normalized ? { to: `user:${normalized}` } : null;
360
+ }).filter((target) => target !== null);
361
+ }
362
+ const matrixNativeApprovalCapability = createApproverRestrictedNativeApprovalCapability({
363
+ channel: "matrix",
364
+ channelLabel: "Matrix",
365
+ describeExecApprovalSetup: ({ accountId }) => {
366
+ const prefix = accountId && accountId !== "default" ? `channels.matrix.accounts.${accountId}` : "channels.matrix";
367
+ return `Approve it from the Web UI or terminal UI for now. Matrix supports native exec approvals for this account. Configure \`${prefix}.execApprovals.approvers\` or \`${prefix}.dm.allowFrom\`; leave \`${prefix}.execApprovals.enabled\` unset/\`auto\` or set it to \`true\`.`;
368
+ },
369
+ listAccountIds: listMatrixAccountIds,
370
+ hasApprovers: ({ cfg, accountId }) => hasAnyMatrixApprovalApprovers({
371
+ cfg,
372
+ accountId
373
+ }),
374
+ isExecAuthorizedSender: ({ cfg, accountId, senderId }) => isMatrixExecApprovalAuthorizedSender({
375
+ cfg,
376
+ accountId,
377
+ senderId
378
+ }),
379
+ isPluginAuthorizedSender: ({ cfg, accountId, senderId }) => isMatrixPluginAuthorizedSender({
380
+ cfg,
381
+ accountId,
382
+ senderId
383
+ }),
384
+ isNativeDeliveryEnabled: ({ cfg, accountId }) => isMatrixExecApprovalClientEnabled({
385
+ cfg,
386
+ accountId
387
+ }),
388
+ resolveNativeDeliveryMode: ({ cfg, accountId }) => resolveMatrixExecApprovalTarget({
389
+ cfg,
390
+ accountId
391
+ }),
392
+ requireMatchingTurnSourceChannel: true,
393
+ resolveSuppressionAccountId,
394
+ resolveOriginTarget: resolveMatrixOriginTarget,
395
+ resolveApproverDmTargets: resolveMatrixApproverDmTargets,
396
+ notifyOriginWhenDmOnly: true,
397
+ nativeRuntime: createLazyChannelApprovalNativeRuntimeAdapter({
398
+ eventKinds: ["exec", "plugin"],
399
+ isConfigured: ({ cfg, accountId }) => isMatrixAnyApprovalClientEnabled({
400
+ cfg,
401
+ accountId
402
+ }),
403
+ shouldHandle: ({ cfg, accountId, request }) => shouldHandleMatrixApprovalRequest({
404
+ cfg,
405
+ accountId,
406
+ request
407
+ }),
408
+ load: async () => (await import("./approval-handler.runtime-DWTQfd4m.js")).matrixApprovalNativeRuntime
409
+ })
410
+ });
411
+ const splitMatrixApprovalCapability = splitChannelApprovalCapability(matrixNativeApprovalCapability);
412
+ const matrixBaseNativeApprovalAdapter = splitMatrixApprovalCapability.native;
413
+ const matrixBaseDeliveryAdapter = splitMatrixApprovalCapability.delivery;
414
+ const matrixDeliveryAdapter = matrixBaseDeliveryAdapter && {
415
+ ...matrixBaseDeliveryAdapter,
416
+ shouldSuppressForwardingFallback: (params) => {
417
+ const accountId = resolveSuppressionAccountId(params);
418
+ if (!hasMatrixApprovalApprovers({
419
+ cfg: params.cfg,
420
+ accountId,
421
+ approvalKind: params.approvalKind
422
+ })) return false;
423
+ return matrixBaseDeliveryAdapter.shouldSuppressForwardingFallback?.(params) ?? false;
424
+ }
425
+ };
426
+ const matrixNativeAdapter = matrixBaseNativeApprovalAdapter && {
427
+ describeDeliveryCapabilities: (params) => {
428
+ const capabilities = matrixBaseNativeApprovalAdapter.describeDeliveryCapabilities(params);
429
+ const hasApprovers = hasMatrixApprovalApprovers({
430
+ cfg: params.cfg,
431
+ accountId: params.accountId,
432
+ approvalKind: params.approvalKind
433
+ });
434
+ const clientEnabled = isMatrixApprovalClientEnabled({
435
+ cfg: params.cfg,
436
+ accountId: params.accountId,
437
+ approvalKind: params.approvalKind
438
+ });
439
+ return {
440
+ ...capabilities,
441
+ enabled: capabilities.enabled && hasApprovers && clientEnabled
442
+ };
443
+ },
444
+ resolveOriginTarget: matrixBaseNativeApprovalAdapter.resolveOriginTarget,
445
+ resolveApproverDmTargets: matrixBaseNativeApprovalAdapter.resolveApproverDmTargets
446
+ };
447
+ const matrixApprovalCapability = createChannelApprovalCapability({
448
+ authorizeActorAction: (params) => {
449
+ if (params.approvalKind !== "plugin") return matrixNativeApprovalCapability.authorizeActorAction?.(params) ?? { authorized: true };
450
+ if (!hasMatrixPluginApprovers({
451
+ cfg: params.cfg,
452
+ accountId: params.accountId
453
+ })) return {
454
+ authorized: false,
455
+ reason: "❌ Matrix plugin approvals are not enabled for this bot account."
456
+ };
457
+ return matrixApprovalAuth.authorizeActorAction(params);
458
+ },
459
+ getActionAvailabilityState: (params) => {
460
+ if (params.approvalKind === "plugin") return availabilityState(hasMatrixPluginApprovers({
461
+ cfg: params.cfg,
462
+ accountId: params.accountId
463
+ }));
464
+ return matrixNativeApprovalCapability.getActionAvailabilityState?.(params) ?? { kind: "disabled" };
465
+ },
466
+ getExecInitiatingSurfaceState: (params) => matrixNativeApprovalCapability.getExecInitiatingSurfaceState?.(params) ?? { kind: "disabled" },
467
+ describeExecApprovalSetup: matrixNativeApprovalCapability.describeExecApprovalSetup,
468
+ delivery: matrixDeliveryAdapter,
469
+ nativeRuntime: matrixNativeApprovalCapability.nativeRuntime,
470
+ native: matrixNativeAdapter,
471
+ render: matrixNativeApprovalCapability.render
472
+ });
473
+ //#endregion
474
+ //#region extensions/matrix/src/channel-account-paths.ts
475
+ function createMatrixProbeAccount(params) {
476
+ return async ({ account, timeoutMs, cfg }) => {
477
+ try {
478
+ const auth = await params.resolveMatrixAuth({
479
+ cfg,
480
+ accountId: account.accountId
481
+ });
482
+ return await params.probeMatrix({
483
+ homeserver: auth.homeserver,
484
+ accessToken: auth.accessToken,
485
+ userId: auth.userId,
486
+ deviceId: auth.deviceId,
487
+ timeoutMs: timeoutMs ?? 5e3,
488
+ accountId: account.accountId,
489
+ allowPrivateNetwork: auth.allowPrivateNetwork,
490
+ ssrfPolicy: auth.ssrfPolicy,
491
+ dispatcherPolicy: auth.dispatcherPolicy
492
+ });
493
+ } catch (err) {
494
+ return {
495
+ ok: false,
496
+ error: formatMatrixErrorMessage(err),
497
+ elapsedMs: 0
498
+ };
499
+ }
500
+ };
501
+ }
502
+ function createMatrixPairingText(sendMessageMatrix) {
503
+ return {
504
+ idLabel: "matrixUserId",
505
+ message: PAIRING_APPROVED_MESSAGE,
506
+ normalizeAllowEntry: createPairingPrefixStripper(/^matrix:/i),
507
+ notify: async ({ id, message, cfg, accountId }) => {
508
+ await sendMessageMatrix(`user:${id}`, message, {
509
+ cfg,
510
+ ...accountId ? { accountId } : {}
511
+ });
512
+ }
513
+ };
514
+ }
515
+ //#endregion
516
+ //#region extensions/matrix/src/group-mentions.ts
517
+ function resolveMatrixRoomConfigForGroup(params) {
518
+ const roomId = normalizeMatrixResolvableTarget(params.groupId?.trim() ?? "");
519
+ const groupChannel = params.groupChannel?.trim() ?? "";
520
+ const aliases = groupChannel ? [normalizeMatrixResolvableTarget(groupChannel)] : [];
521
+ const cfg = params.cfg;
522
+ const matrixConfig = resolveMatrixAccountConfig({
523
+ cfg,
524
+ accountId: params.accountId
525
+ });
526
+ return resolveMatrixRoomConfig({
527
+ rooms: matrixConfig.groups ?? matrixConfig.rooms,
528
+ roomId,
529
+ aliases
530
+ }).config;
531
+ }
532
+ function resolveMatrixGroupRequireMention(params) {
533
+ const resolved = resolveMatrixRoomConfigForGroup(params);
534
+ if (resolved) {
535
+ if (resolved.autoReply === true) return false;
536
+ if (resolved.autoReply === false) return true;
537
+ if (typeof resolved.requireMention === "boolean") return resolved.requireMention;
538
+ }
539
+ return true;
540
+ }
541
+ function resolveMatrixGroupToolPolicy(params) {
542
+ return resolveMatrixRoomConfigForGroup(params)?.tools;
543
+ }
544
+ //#endregion
545
+ //#region extensions/matrix/src/resolver.ts
546
+ const loadMatrixChannelRuntime$1 = createLazyRuntimeNamedExport(() => import("./resolver.runtime-D9piiGEl.js"), "matrixResolverRuntime");
547
+ const matrixResolverAdapter = { resolveTargets: async ({ cfg, accountId, inputs, kind, runtime }) => (await loadMatrixChannelRuntime$1()).resolveMatrixTargets({
548
+ cfg,
549
+ accountId,
550
+ inputs,
551
+ kind,
552
+ runtime
553
+ }) };
554
+ //#endregion
555
+ //#region extensions/matrix/src/session-route.ts
556
+ function resolveEffectiveMatrixAccountId(params) {
557
+ return normalizeAccountId(params.accountId ?? resolveDefaultMatrixAccountId(params.cfg));
558
+ }
559
+ function resolveMatrixDmSessionScope(params) {
560
+ return resolveMatrixAccountConfig({
561
+ cfg: params.cfg,
562
+ accountId: params.accountId
563
+ }).dm?.sessionScope ?? "per-user";
564
+ }
565
+ function resolveMatrixCurrentDmRoomId(params) {
566
+ const sessionKey = parseThreadSessionSuffix(params.currentSessionKey).baseSessionKey ?? params.currentSessionKey?.trim();
567
+ if (!sessionKey) return;
568
+ try {
569
+ const existing = resolveSessionStoreEntry({
570
+ store: loadSessionStore(resolveStorePath(params.cfg.session?.store, { agentId: params.agentId })),
571
+ sessionKey
572
+ }).existing;
573
+ const currentSession = resolveMatrixStoredSessionMeta(existing);
574
+ if (!currentSession) return;
575
+ if (currentSession.accountId && currentSession.accountId !== params.accountId) return;
576
+ if (!currentSession.directUserId || currentSession.directUserId !== params.targetUserId) return;
577
+ return currentSession.roomId;
578
+ } catch {
579
+ return;
580
+ }
581
+ }
582
+ function resolveMatrixOutboundSessionRoute(params) {
583
+ const target = resolveMatrixTargetIdentity(params.resolvedTarget?.to ?? params.target) ?? resolveMatrixTargetIdentity(params.target);
584
+ if (!target) return null;
585
+ const effectiveAccountId = resolveEffectiveMatrixAccountId(params);
586
+ const roomScopedDmId = target.kind === "user" && resolveMatrixDmSessionScope({
587
+ cfg: params.cfg,
588
+ accountId: effectiveAccountId
589
+ }) === "per-room" ? resolveMatrixCurrentDmRoomId({
590
+ cfg: params.cfg,
591
+ agentId: params.agentId,
592
+ accountId: effectiveAccountId,
593
+ currentSessionKey: params.currentSessionKey,
594
+ targetUserId: target.id
595
+ }) : void 0;
596
+ const peer = roomScopedDmId !== void 0 ? {
597
+ kind: "channel",
598
+ id: roomScopedDmId
599
+ } : {
600
+ kind: target.kind === "user" ? "direct" : "channel",
601
+ id: target.id
602
+ };
603
+ const chatType = target.kind === "user" ? "direct" : "channel";
604
+ const from = target.kind === "user" ? `matrix:${target.id}` : `matrix:channel:${target.id}`;
605
+ const to = `room:${roomScopedDmId ?? target.id}`;
606
+ return buildThreadAwareOutboundSessionRoute({
607
+ route: buildChannelOutboundSessionRoute({
608
+ cfg: params.cfg,
609
+ agentId: params.agentId,
610
+ channel: "matrix",
611
+ accountId: effectiveAccountId,
612
+ peer,
613
+ chatType,
614
+ from,
615
+ to
616
+ }),
617
+ replyToId: params.replyToId,
618
+ threadId: params.threadId,
619
+ currentSessionKey: params.currentSessionKey,
620
+ normalizeThreadId: (threadId) => threadId,
621
+ canRecoverCurrentThread: ({ route }) => route.peer.kind !== "direct" || (params.cfg.session?.dmScope ?? "main") !== "main"
622
+ });
623
+ }
624
+ //#endregion
625
+ //#region extensions/matrix/src/startup-maintenance.ts
626
+ function logWarningOnlyMatrixMigrationReasons(params) {
627
+ if (params.status.legacyState && "warning" in params.status.legacyState) params.log.warn?.(`matrix: ${params.status.legacyState.warning}`);
628
+ if (params.status.legacyCrypto.warnings.length > 0) params.log.warn?.(`matrix: legacy encrypted-state warnings:\n${params.status.legacyCrypto.warnings.map((entry) => `- ${entry}`).join("\n")}`);
629
+ }
630
+ async function runBestEffortMatrixMigrationStep(params) {
631
+ try {
632
+ await params.run();
633
+ } catch (err) {
634
+ params.log.warn?.(`${params.logPrefix?.trim() || "gateway"}: ${params.label} failed during Matrix migration; continuing startup: ${String(err)}`);
635
+ }
636
+ }
637
+ async function runMatrixStartupMaintenance(params) {
638
+ const env = params.env ?? process.env;
639
+ const createSnapshot = params.deps?.maybeCreateMatrixMigrationSnapshot ?? maybeCreateMatrixMigrationSnapshot;
640
+ const migrateLegacyState = params.deps?.autoMigrateLegacyMatrixState ?? autoMigrateLegacyMatrixState;
641
+ const prepareLegacyCrypto = params.deps?.autoPrepareLegacyMatrixCrypto ?? autoPrepareLegacyMatrixCrypto;
642
+ const trigger = params.trigger?.trim() || "gateway-startup";
643
+ const logPrefix = params.logPrefix?.trim() || "gateway";
644
+ const migrationStatus = resolveMatrixMigrationStatus({
645
+ cfg: params.cfg,
646
+ env
647
+ });
648
+ if (!migrationStatus.pending) return;
649
+ if (!migrationStatus.actionable) {
650
+ params.log.info?.("matrix: migration remains in a warning-only state; no pre-migration snapshot was needed yet");
651
+ logWarningOnlyMatrixMigrationReasons({
652
+ status: migrationStatus,
653
+ log: params.log
654
+ });
655
+ return;
656
+ }
657
+ try {
658
+ await createSnapshot({
659
+ trigger,
660
+ env,
661
+ log: params.log
662
+ });
663
+ } catch (err) {
664
+ params.log.warn?.(`${logPrefix}: failed creating a Matrix migration snapshot; skipping Matrix migration for now: ${String(err)}`);
665
+ return;
666
+ }
667
+ await runBestEffortMatrixMigrationStep({
668
+ label: "legacy Matrix state migration",
669
+ log: params.log,
670
+ logPrefix,
671
+ run: () => migrateLegacyState({
672
+ cfg: params.cfg,
673
+ env,
674
+ log: params.log
675
+ })
676
+ });
677
+ await runBestEffortMatrixMigrationStep({
678
+ label: "legacy Matrix encrypted-state preparation",
679
+ log: params.log,
680
+ logPrefix,
681
+ run: () => prepareLegacyCrypto({
682
+ cfg: params.cfg,
683
+ env,
684
+ log: params.log
685
+ })
686
+ });
687
+ }
688
+ //#endregion
689
+ //#region extensions/matrix/src/channel.ts
690
+ let matrixStartupLock = Promise.resolve();
691
+ const loadMatrixSetupWizard = createLazyRuntimeNamedExport(() => import("./setup-surface-CqT_o61M.js").then((n) => n.t), "matrixSetupWizard");
692
+ const loadMatrixChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-BQu0hTih.js"), "matrixChannelRuntime");
693
+ const meta = {
694
+ id: "matrix",
695
+ label: "Matrix",
696
+ selectionLabel: "Matrix (plugin)",
697
+ docsPath: "/channels/matrix",
698
+ docsLabel: "matrix",
699
+ blurb: "open protocol; configure a homeserver + access token.",
700
+ order: 70,
701
+ quickstartAllowFrom: true
702
+ };
703
+ function buildMatrixTrafficStatusSummary(snapshot) {
704
+ return {
705
+ lastInboundAt: snapshot?.lastInboundAt ?? null,
706
+ lastOutboundAt: snapshot?.lastOutboundAt ?? null
707
+ };
708
+ }
709
+ const matrixDoctor = {
710
+ dmAllowFromMode: "nestedOnly",
711
+ groupModel: "sender",
712
+ groupAllowFromFallbackToAllowFrom: false,
713
+ warnOnEmptyGroupSenderAllowlist: true,
714
+ legacyConfigRules,
715
+ normalizeCompatibilityConfig,
716
+ runConfigSequence: async ({ cfg, env, shouldRepair }) => await (await import("./doctor-C4__7c-U.js")).runMatrixDoctorSequence({
717
+ cfg,
718
+ env,
719
+ shouldRepair
720
+ }),
721
+ cleanStaleConfig: async ({ cfg }) => await (await import("./doctor-C4__7c-U.js")).cleanStaleMatrixPluginConfig(cfg)
722
+ };
723
+ const listMatrixDirectoryPeersFromConfig = createResolvedDirectoryEntriesLister({
724
+ kind: "user",
725
+ resolveAccount: adaptScopedAccountAccessor(resolveMatrixAccount),
726
+ resolveSources: (account) => [
727
+ account.config.dm?.allowFrom ?? [],
728
+ account.config.groupAllowFrom ?? [],
729
+ ...Object.values(account.config.groups ?? account.config.rooms ?? {}).map((room) => room.users ?? [])
730
+ ],
731
+ normalizeId: (entry) => {
732
+ const raw = entry.replace(/^matrix:/i, "").trim();
733
+ if (!raw || raw === "*") return null;
734
+ const cleaned = normalizeLowercaseStringOrEmpty(raw).startsWith("user:") ? raw.slice(5).trim() : raw;
735
+ return cleaned.startsWith("@") ? `user:${cleaned}` : cleaned;
736
+ }
737
+ });
738
+ const listMatrixDirectoryGroupsFromConfig = createResolvedDirectoryEntriesLister({
739
+ kind: "group",
740
+ resolveAccount: adaptScopedAccountAccessor(resolveMatrixAccount),
741
+ resolveSources: (account) => [Object.keys(account.config.groups ?? account.config.rooms ?? {})],
742
+ normalizeId: (entry) => {
743
+ const raw = entry.replace(/^matrix:/i, "").trim();
744
+ if (!raw || raw === "*") return null;
745
+ const lowered = normalizeLowercaseStringOrEmpty(raw);
746
+ if (lowered.startsWith("room:") || lowered.startsWith("channel:")) return raw;
747
+ return raw.startsWith("!") ? `room:${raw}` : raw;
748
+ }
749
+ });
750
+ function projectMatrixConversationBinding(binding) {
751
+ return {
752
+ boundAt: binding.boundAt,
753
+ lastActivityAt: typeof binding.metadata?.lastActivityAt === "number" ? binding.metadata.lastActivityAt : binding.boundAt,
754
+ idleTimeoutMs: typeof binding.metadata?.idleTimeoutMs === "number" ? binding.metadata.idleTimeoutMs : void 0,
755
+ maxAgeMs: typeof binding.metadata?.maxAgeMs === "number" ? binding.metadata.maxAgeMs : void 0
756
+ };
757
+ }
758
+ const resolveMatrixDmPolicy = createScopedDmSecurityResolver({
759
+ channelKey: "matrix",
760
+ resolvePolicy: (account) => account.config.dm?.policy,
761
+ resolveAllowFrom: (account) => account.config.dm?.allowFrom,
762
+ allowFromPathSuffix: "dm.",
763
+ normalizeEntry: (raw) => normalizeMatrixUserId(raw)
764
+ });
765
+ const collectMatrixSecurityWarnings = createAllowlistProviderOpenWarningCollector({
766
+ providerConfigPresent: (cfg) => cfg.channels?.matrix !== void 0,
767
+ resolveGroupPolicy: (account) => account.config.groupPolicy,
768
+ buildOpenWarning: {
769
+ surface: "Matrix rooms",
770
+ openBehavior: "allows any room to trigger (mention-gated)",
771
+ remediation: "Set channels.matrix.groupPolicy=\"allowlist\" + channels.matrix.groups (and optionally channels.matrix.groupAllowFrom) to restrict rooms"
772
+ }
773
+ });
774
+ function resolveMatrixAccountConfigPath(accountId, field) {
775
+ return accountId === DEFAULT_ACCOUNT_ID$2 ? `channels.matrix.${field}` : `channels.matrix.accounts.${accountId}.${field}`;
776
+ }
777
+ function collectMatrixSecurityWarningsForAccount(params) {
778
+ const warnings = collectMatrixSecurityWarnings(params);
779
+ if (params.account.accountId !== DEFAULT_ACCOUNT_ID$2) {
780
+ const groupPolicyPath = resolveMatrixAccountConfigPath(params.account.accountId, "groupPolicy");
781
+ const groupsPath = resolveMatrixAccountConfigPath(params.account.accountId, "groups");
782
+ const groupAllowFromPath = resolveMatrixAccountConfigPath(params.account.accountId, "groupAllowFrom");
783
+ return warnings.map((warning) => warning.replace("channels.matrix.groupPolicy", groupPolicyPath).replace("channels.matrix.groups", groupsPath).replace("channels.matrix.groupAllowFrom", groupAllowFromPath));
784
+ }
785
+ if (params.account.config.autoJoin !== "always") return warnings;
786
+ const autoJoinPath = resolveMatrixAccountConfigPath(params.account.accountId, "autoJoin");
787
+ const autoJoinAllowlistPath = resolveMatrixAccountConfigPath(params.account.accountId, "autoJoinAllowlist");
788
+ return [...warnings, `- Matrix invites: autoJoin="always" joins any invited room before message policy applies. Set ${autoJoinPath}="allowlist" + ${autoJoinAllowlistPath} (or ${autoJoinPath}="off") to restrict joins.`];
789
+ }
790
+ function normalizeMatrixAcpConversationId(conversationId) {
791
+ const target = resolveMatrixTargetIdentity(conversationId);
792
+ if (!target || target.kind !== "room") return null;
793
+ return { conversationId: target.id };
794
+ }
795
+ function matchMatrixAcpConversation(params) {
796
+ const binding = normalizeMatrixAcpConversationId(params.bindingConversationId);
797
+ if (!binding) return null;
798
+ if (binding.conversationId === params.conversationId) return {
799
+ conversationId: params.conversationId,
800
+ matchPriority: 2
801
+ };
802
+ if (params.parentConversationId && params.parentConversationId !== params.conversationId && binding.conversationId === params.parentConversationId) return {
803
+ conversationId: params.parentConversationId,
804
+ matchPriority: 1
805
+ };
806
+ return null;
807
+ }
808
+ function resolveMatrixCommandConversation(params) {
809
+ const parentConversationId = [
810
+ params.originatingTo,
811
+ params.commandTo,
812
+ params.fallbackTo
813
+ ].map((candidate) => {
814
+ const trimmed = candidate?.trim();
815
+ if (!trimmed) return;
816
+ const target = resolveMatrixTargetIdentity(trimmed);
817
+ return target?.kind === "room" ? target.id : void 0;
818
+ }).find((candidate) => Boolean(candidate));
819
+ if (params.threadId) return {
820
+ conversationId: params.threadId,
821
+ ...parentConversationId ? { parentConversationId } : {}
822
+ };
823
+ return parentConversationId ? { conversationId: parentConversationId } : null;
824
+ }
825
+ function resolveMatrixDeliveryTarget(params) {
826
+ const parentConversationId = params.parentConversationId?.trim();
827
+ if (parentConversationId && parentConversationId !== params.conversationId.trim()) {
828
+ const parentTarget = resolveMatrixTargetIdentity(parentConversationId);
829
+ if (parentTarget?.kind === "room") return {
830
+ to: `room:${parentTarget.id}`,
831
+ threadId: params.conversationId.trim()
832
+ };
833
+ }
834
+ const conversationTarget = resolveMatrixTargetIdentity(params.conversationId);
835
+ if (conversationTarget?.kind === "room") return { to: `room:${conversationTarget.id}` };
836
+ return null;
837
+ }
838
+ const matrixChannelOutbound = {
839
+ deliveryMode: "direct",
840
+ chunker: chunkTextForOutbound,
841
+ chunkerMode: "markdown",
842
+ textChunkLimit: 4e3,
843
+ deliveryCapabilities: { durableFinal: {
844
+ text: true,
845
+ media: true,
846
+ replyTo: true,
847
+ thread: true,
848
+ messageSendingHooks: true
849
+ } },
850
+ presentationCapabilities: {
851
+ supported: true,
852
+ buttons: true,
853
+ selects: true,
854
+ context: true,
855
+ divider: true
856
+ },
857
+ shouldSuppressLocalPayloadPrompt: ({ cfg, accountId, payload }) => shouldSuppressLocalMatrixExecApprovalPrompt({
858
+ cfg,
859
+ accountId,
860
+ payload
861
+ }),
862
+ ...createRuntimeOutboundDelegates({
863
+ getRuntime: loadMatrixChannelRuntime,
864
+ renderPresentation: {
865
+ resolve: (runtime) => runtime.matrixOutbound.renderPresentation,
866
+ unavailableMessage: "Matrix outbound presentation rendering is unavailable"
867
+ },
868
+ sendPayload: {
869
+ resolve: (runtime) => runtime.matrixOutbound.sendPayload,
870
+ unavailableMessage: "Matrix outbound payload delivery is unavailable"
871
+ },
872
+ sendText: {
873
+ resolve: (runtime) => runtime.matrixOutbound.sendText,
874
+ unavailableMessage: "Matrix outbound text delivery is unavailable"
875
+ },
876
+ sendMedia: {
877
+ resolve: (runtime) => runtime.matrixOutbound.sendMedia,
878
+ unavailableMessage: "Matrix outbound media delivery is unavailable"
879
+ },
880
+ sendPoll: {
881
+ resolve: (runtime) => runtime.matrixOutbound.sendPoll,
882
+ unavailableMessage: "Matrix outbound poll delivery is unavailable"
883
+ }
884
+ })
885
+ };
886
+ const matrixMessageAdapter = createChannelMessageAdapterFromOutbound({
887
+ id: "matrix",
888
+ outbound: matrixChannelOutbound,
889
+ live: {
890
+ capabilities: {
891
+ draftPreview: true,
892
+ previewFinalization: true,
893
+ progressUpdates: true,
894
+ quietFinalization: true
895
+ },
896
+ finalizer: { capabilities: {
897
+ finalEdit: true,
898
+ normalFallback: true,
899
+ discardPending: true,
900
+ previewReceipt: true
901
+ } }
902
+ }
903
+ });
904
+ const matrixPlugin = createChatChannelPlugin({
905
+ base: {
906
+ id: "matrix",
907
+ meta,
908
+ setupWizard: createMatrixSetupWizardProxy(async () => ({ matrixSetupWizard: await loadMatrixSetupWizard() })),
909
+ capabilities: {
910
+ chatTypes: [
911
+ "direct",
912
+ "group",
913
+ "thread"
914
+ ],
915
+ polls: true,
916
+ reactions: true,
917
+ threads: true,
918
+ media: true,
919
+ tts: { voice: { synthesisTarget: "voice-note" } }
920
+ },
921
+ reload: { configPrefixes: ["channels.matrix"] },
922
+ configSchema: MatrixChannelConfigSchema,
923
+ config: {
924
+ ...matrixConfigAdapter,
925
+ isConfigured: (account) => account.configured,
926
+ describeAccount: (account) => describeAccountSnapshot({
927
+ account,
928
+ configured: account.configured,
929
+ extra: { baseUrl: account.homeserver }
930
+ })
931
+ },
932
+ approvalCapability: matrixApprovalCapability,
933
+ groups: {
934
+ resolveRequireMention: resolveMatrixGroupRequireMention,
935
+ resolveToolPolicy: resolveMatrixGroupToolPolicy
936
+ },
937
+ conversationBindings: {
938
+ supportsCurrentConversationBinding: true,
939
+ defaultTopLevelPlacement: "child",
940
+ setIdleTimeoutBySessionKey: ({ targetSessionKey, accountId, idleTimeoutMs }) => setMatrixThreadBindingIdleTimeoutBySessionKey({
941
+ targetSessionKey,
942
+ accountId: accountId ?? "",
943
+ idleTimeoutMs
944
+ }).map(projectMatrixConversationBinding),
945
+ setMaxAgeBySessionKey: ({ targetSessionKey, accountId, maxAgeMs }) => setMatrixThreadBindingMaxAgeBySessionKey({
946
+ targetSessionKey,
947
+ accountId: accountId ?? "",
948
+ maxAgeMs
949
+ }).map(projectMatrixConversationBinding)
950
+ },
951
+ messaging: {
952
+ targetPrefixes: ["matrix"],
953
+ normalizeTarget: normalizeMatrixMessagingTarget,
954
+ resolveInboundConversation: ({ to, conversationId, threadId }) => resolveMatrixInboundConversation({
955
+ to,
956
+ conversationId,
957
+ threadId
958
+ }),
959
+ resolveDeliveryTarget: ({ conversationId, parentConversationId }) => resolveMatrixDeliveryTarget({
960
+ conversationId,
961
+ parentConversationId
962
+ }),
963
+ resolveOutboundSessionRoute: (params) => resolveMatrixOutboundSessionRoute(params),
964
+ targetResolver: {
965
+ looksLikeId: (raw) => {
966
+ const trimmed = raw.trim();
967
+ if (!trimmed) return false;
968
+ if (/^(matrix:)?[!#@]/i.test(trimmed)) return true;
969
+ return trimmed.includes(":");
970
+ },
971
+ hint: "<room|alias|user>"
972
+ }
973
+ },
974
+ directory: createChannelDirectoryAdapter({
975
+ listPeers: async (params) => {
976
+ return (await listMatrixDirectoryPeersFromConfig(params)).map((entry) => {
977
+ const raw = entry.id.startsWith("user:") ? entry.id.slice(5) : entry.id;
978
+ return !raw.startsWith("@") || !raw.includes(":") ? Object.assign({}, entry, { name: `incomplete id; expected @user:server` }) : entry;
979
+ });
980
+ },
981
+ listGroups: async (params) => await listMatrixDirectoryGroupsFromConfig(params),
982
+ ...createRuntimeDirectoryLiveAdapter({
983
+ getRuntime: loadMatrixChannelRuntime,
984
+ listPeersLive: (runtime) => runtime.listMatrixDirectoryPeersLive,
985
+ listGroupsLive: (runtime) => runtime.listMatrixDirectoryGroupsLive
986
+ })
987
+ }),
988
+ resolver: matrixResolverAdapter,
989
+ actions: matrixMessageActions,
990
+ message: matrixMessageAdapter,
991
+ secrets: {
992
+ secretTargetRegistryEntries,
993
+ collectRuntimeConfigAssignments
994
+ },
995
+ setup: {
996
+ ...matrixSetupAdapter,
997
+ singleAccountKeysToMove,
998
+ namedAccountPromotionKeys,
999
+ resolveSingleAccountPromotionTarget
1000
+ },
1001
+ bindings: {
1002
+ compileConfiguredBinding: ({ conversationId }) => normalizeMatrixAcpConversationId(conversationId),
1003
+ matchInboundConversation: ({ compiledBinding, conversationId, parentConversationId }) => matchMatrixAcpConversation({
1004
+ bindingConversationId: compiledBinding.conversationId,
1005
+ conversationId,
1006
+ parentConversationId
1007
+ }),
1008
+ resolveCommandConversation: ({ threadId, originatingTo, commandTo, fallbackTo }) => resolveMatrixCommandConversation({
1009
+ threadId,
1010
+ originatingTo,
1011
+ commandTo,
1012
+ fallbackTo
1013
+ })
1014
+ },
1015
+ status: createComputedAccountStatusAdapter({
1016
+ defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$2),
1017
+ collectStatusIssues: (accounts) => collectStatusIssuesFromLastError("matrix", accounts),
1018
+ buildChannelSummary: ({ snapshot }) => buildProbeChannelStatusSummary(snapshot, { baseUrl: snapshot.baseUrl ?? null }),
1019
+ probeAccount: async ({ account, timeoutMs, cfg }) => await createMatrixProbeAccount({
1020
+ resolveMatrixAuth: async ({ cfg, accountId }) => (await loadMatrixChannelRuntime()).resolveMatrixAuth({
1021
+ cfg,
1022
+ accountId
1023
+ }),
1024
+ probeMatrix: async (params) => await (await loadMatrixChannelRuntime()).probeMatrix(params)
1025
+ })({
1026
+ account,
1027
+ timeoutMs,
1028
+ cfg
1029
+ }),
1030
+ resolveAccountSnapshot: ({ account, runtime }) => ({
1031
+ accountId: account.accountId,
1032
+ name: account.name,
1033
+ enabled: account.enabled,
1034
+ configured: account.configured,
1035
+ extra: {
1036
+ baseUrl: account.homeserver,
1037
+ lastProbeAt: runtime?.lastProbeAt ?? null,
1038
+ ...buildMatrixTrafficStatusSummary(runtime)
1039
+ }
1040
+ })
1041
+ }),
1042
+ gateway: { startAccount: async (ctx) => {
1043
+ const account = ctx.account;
1044
+ ctx.setStatus({
1045
+ accountId: account.accountId,
1046
+ baseUrl: account.homeserver
1047
+ });
1048
+ ctx.log?.info(`[${account.accountId}] starting provider (${account.homeserver ?? "matrix"})`);
1049
+ const previousLock = matrixStartupLock;
1050
+ let releaseLock = () => {};
1051
+ matrixStartupLock = new Promise((resolve) => {
1052
+ releaseLock = resolve;
1053
+ });
1054
+ await previousLock;
1055
+ let monitorMatrixProvider;
1056
+ try {
1057
+ monitorMatrixProvider = (await import("./monitor-C_81r_Ck.js")).monitorMatrixProvider;
1058
+ } finally {
1059
+ releaseLock();
1060
+ }
1061
+ return monitorMatrixProvider({
1062
+ runtime: ctx.runtime,
1063
+ channelRuntime: ctx.channelRuntime,
1064
+ abortSignal: ctx.abortSignal,
1065
+ mediaMaxMb: account.config.mediaMaxMb,
1066
+ initialSyncLimit: account.config.initialSyncLimit,
1067
+ replyToMode: account.config.replyToMode,
1068
+ accountId: account.accountId,
1069
+ setStatus: ctx.setStatus
1070
+ });
1071
+ } },
1072
+ doctor: matrixDoctor,
1073
+ lifecycle: { runStartupMaintenance: runMatrixStartupMaintenance },
1074
+ heartbeat: {
1075
+ sendTyping: async ({ cfg, to, accountId }) => {
1076
+ await (await loadMatrixChannelRuntime()).sendTypingMatrix(to, true, {
1077
+ cfg,
1078
+ ...accountId ? { accountId } : {}
1079
+ });
1080
+ },
1081
+ clearTyping: async ({ cfg, to, accountId }) => {
1082
+ await (await loadMatrixChannelRuntime()).sendTypingMatrix(to, false, {
1083
+ cfg,
1084
+ ...accountId ? { accountId } : {}
1085
+ });
1086
+ }
1087
+ }
1088
+ },
1089
+ security: {
1090
+ resolveDmPolicy: resolveMatrixDmPolicy,
1091
+ collectWarnings: projectAccountConfigWarningCollector((cfg) => cfg, collectMatrixSecurityWarningsForAccount)
1092
+ },
1093
+ pairing: { text: createMatrixPairingText(async (to, message, options) => await (await loadMatrixChannelRuntime()).sendMessageMatrix(to, message, options)) },
1094
+ threading: {
1095
+ resolveReplyToMode: createScopedAccountReplyToModeResolver({
1096
+ resolveAccount: adaptScopedAccountAccessor(resolveMatrixAccountConfig),
1097
+ resolveReplyToMode: (account) => account.replyToMode
1098
+ }),
1099
+ buildToolContext: ({ context, hasRepliedRef }) => {
1100
+ const currentTarget = context.To;
1101
+ return {
1102
+ currentChannelId: normalizeOptionalString(currentTarget),
1103
+ currentThreadTs: context.MessageThreadId != null ? String(context.MessageThreadId) : void 0,
1104
+ currentDirectUserId: resolveMatrixDirectUserId({
1105
+ from: context.From,
1106
+ to: context.To,
1107
+ chatType: context.ChatType
1108
+ }),
1109
+ hasRepliedRef
1110
+ };
1111
+ }
1112
+ },
1113
+ outbound: matrixChannelOutbound
1114
+ });
1115
+ //#endregion
1116
+ export { matrixPlugin as t };