@gakr-gakr/matrix 0.1.0

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 (205) hide show
  1. package/CHANGELOG.md +285 -0
  2. package/SPEC-SUPPORT.md +116 -0
  3. package/api.ts +38 -0
  4. package/auth-presence.ts +56 -0
  5. package/autobot.plugin.json +28 -0
  6. package/channel-plugin-api.ts +3 -0
  7. package/cli-metadata.ts +11 -0
  8. package/contract-api.ts +17 -0
  9. package/doctor-contract-api.ts +1 -0
  10. package/helper-api.ts +3 -0
  11. package/index.ts +55 -0
  12. package/package.json +101 -0
  13. package/plugin-entry.handlers.runtime.ts +1 -0
  14. package/runtime-api.ts +72 -0
  15. package/runtime-heavy-api.ts +1 -0
  16. package/runtime-setter-api.ts +3 -0
  17. package/secret-contract-api.ts +5 -0
  18. package/setup-entry.ts +17 -0
  19. package/setup-plugin-api.ts +3 -0
  20. package/src/account-selection.ts +223 -0
  21. package/src/actions.ts +346 -0
  22. package/src/approval-auth.ts +25 -0
  23. package/src/approval-handler.runtime.ts +595 -0
  24. package/src/approval-ids.ts +6 -0
  25. package/src/approval-native.ts +348 -0
  26. package/src/approval-reaction-auth.ts +45 -0
  27. package/src/approval-reactions.ts +313 -0
  28. package/src/auth-precedence.ts +61 -0
  29. package/src/channel-account-paths.ts +97 -0
  30. package/src/channel.runtime.ts +17 -0
  31. package/src/channel.setup.ts +48 -0
  32. package/src/channel.ts +667 -0
  33. package/src/cli-metadata.ts +19 -0
  34. package/src/cli.ts +2298 -0
  35. package/src/config-adapter.ts +41 -0
  36. package/src/config-schema.ts +159 -0
  37. package/src/config-ui-hints.ts +56 -0
  38. package/src/directory-live.ts +238 -0
  39. package/src/doctor-contract.ts +287 -0
  40. package/src/doctor.ts +262 -0
  41. package/src/env-vars.ts +92 -0
  42. package/src/exec-approval-resolver.ts +23 -0
  43. package/src/exec-approvals.ts +293 -0
  44. package/src/group-mentions.ts +41 -0
  45. package/src/legacy-crypto-inspector-availability.ts +60 -0
  46. package/src/legacy-crypto.ts +531 -0
  47. package/src/legacy-state.ts +156 -0
  48. package/src/matrix/account-config.ts +175 -0
  49. package/src/matrix/accounts.ts +194 -0
  50. package/src/matrix/actions/client.ts +31 -0
  51. package/src/matrix/actions/devices.ts +34 -0
  52. package/src/matrix/actions/limits.ts +6 -0
  53. package/src/matrix/actions/messages.ts +129 -0
  54. package/src/matrix/actions/pins.ts +63 -0
  55. package/src/matrix/actions/polls.ts +109 -0
  56. package/src/matrix/actions/profile.ts +37 -0
  57. package/src/matrix/actions/reactions.ts +59 -0
  58. package/src/matrix/actions/room.ts +71 -0
  59. package/src/matrix/actions/summary.ts +88 -0
  60. package/src/matrix/actions/types.ts +63 -0
  61. package/src/matrix/actions/verification.ts +589 -0
  62. package/src/matrix/actions.ts +37 -0
  63. package/src/matrix/active-client.ts +26 -0
  64. package/src/matrix/async-lock.ts +18 -0
  65. package/src/matrix/backup-health.ts +124 -0
  66. package/src/matrix/client/config-runtime-api.ts +9 -0
  67. package/src/matrix/client/config-secret-input.runtime.ts +1 -0
  68. package/src/matrix/client/config.ts +853 -0
  69. package/src/matrix/client/create-client.ts +105 -0
  70. package/src/matrix/client/env-auth.ts +95 -0
  71. package/src/matrix/client/file-sync-store.ts +289 -0
  72. package/src/matrix/client/logging.ts +140 -0
  73. package/src/matrix/client/migration-snapshot.runtime.ts +1 -0
  74. package/src/matrix/client/private-network-host.ts +1 -0
  75. package/src/matrix/client/runtime.ts +4 -0
  76. package/src/matrix/client/shared.ts +316 -0
  77. package/src/matrix/client/storage.ts +543 -0
  78. package/src/matrix/client/types.ts +50 -0
  79. package/src/matrix/client/url-validation.ts +76 -0
  80. package/src/matrix/client-bootstrap.ts +173 -0
  81. package/src/matrix/client.ts +23 -0
  82. package/src/matrix/config-paths.ts +31 -0
  83. package/src/matrix/config-update.ts +292 -0
  84. package/src/matrix/credentials-read.ts +207 -0
  85. package/src/matrix/credentials-write.runtime.ts +35 -0
  86. package/src/matrix/credentials.ts +95 -0
  87. package/src/matrix/deps.ts +309 -0
  88. package/src/matrix/device-health.ts +31 -0
  89. package/src/matrix/direct-management.ts +349 -0
  90. package/src/matrix/direct-room.ts +128 -0
  91. package/src/matrix/draft-stream.ts +225 -0
  92. package/src/matrix/encryption-guidance.ts +24 -0
  93. package/src/matrix/errors.ts +21 -0
  94. package/src/matrix/format.ts +426 -0
  95. package/src/matrix/legacy-crypto-inspector.ts +95 -0
  96. package/src/matrix/media-errors.ts +20 -0
  97. package/src/matrix/media-text.ts +162 -0
  98. package/src/matrix/monitor/access-state.ts +145 -0
  99. package/src/matrix/monitor/ack-config.ts +27 -0
  100. package/src/matrix/monitor/allowlist.ts +92 -0
  101. package/src/matrix/monitor/auto-join.ts +86 -0
  102. package/src/matrix/monitor/config.ts +569 -0
  103. package/src/matrix/monitor/context-summary.ts +43 -0
  104. package/src/matrix/monitor/direct.ts +296 -0
  105. package/src/matrix/monitor/events.ts +397 -0
  106. package/src/matrix/monitor/handler.ts +2271 -0
  107. package/src/matrix/monitor/inbound-dedupe.ts +267 -0
  108. package/src/matrix/monitor/index.ts +540 -0
  109. package/src/matrix/monitor/legacy-crypto-restore.ts +139 -0
  110. package/src/matrix/monitor/location.ts +108 -0
  111. package/src/matrix/monitor/media.ts +119 -0
  112. package/src/matrix/monitor/mentions.ts +256 -0
  113. package/src/matrix/monitor/reaction-events.ts +197 -0
  114. package/src/matrix/monitor/recent-invite.ts +30 -0
  115. package/src/matrix/monitor/replies.ts +136 -0
  116. package/src/matrix/monitor/reply-context.ts +92 -0
  117. package/src/matrix/monitor/room-history.ts +301 -0
  118. package/src/matrix/monitor/room-info.ts +126 -0
  119. package/src/matrix/monitor/rooms.ts +52 -0
  120. package/src/matrix/monitor/route.ts +179 -0
  121. package/src/matrix/monitor/runtime-api.ts +28 -0
  122. package/src/matrix/monitor/startup-verification.ts +237 -0
  123. package/src/matrix/monitor/startup.ts +218 -0
  124. package/src/matrix/monitor/status.ts +120 -0
  125. package/src/matrix/monitor/sync-lifecycle.ts +91 -0
  126. package/src/matrix/monitor/task-runner.ts +38 -0
  127. package/src/matrix/monitor/test-events.ts +21 -0
  128. package/src/matrix/monitor/thread-context.ts +108 -0
  129. package/src/matrix/monitor/threads.ts +85 -0
  130. package/src/matrix/monitor/types.ts +30 -0
  131. package/src/matrix/monitor/verification-events.ts +643 -0
  132. package/src/matrix/monitor/verification-utils.ts +46 -0
  133. package/src/matrix/outbound-media-runtime.ts +1 -0
  134. package/src/matrix/poll-summary.ts +110 -0
  135. package/src/matrix/poll-types.ts +429 -0
  136. package/src/matrix/probe.runtime.ts +4 -0
  137. package/src/matrix/probe.ts +97 -0
  138. package/src/matrix/profile.ts +184 -0
  139. package/src/matrix/reaction-common.ts +147 -0
  140. package/src/matrix/sdk/crypto-bootstrap.ts +438 -0
  141. package/src/matrix/sdk/crypto-facade.ts +242 -0
  142. package/src/matrix/sdk/crypto-node.runtime.ts +17 -0
  143. package/src/matrix/sdk/crypto-runtime.ts +14 -0
  144. package/src/matrix/sdk/decrypt-bridge.ts +410 -0
  145. package/src/matrix/sdk/event-helpers.ts +83 -0
  146. package/src/matrix/sdk/http-client.ts +87 -0
  147. package/src/matrix/sdk/idb-persistence-lock.ts +51 -0
  148. package/src/matrix/sdk/idb-persistence.ts +286 -0
  149. package/src/matrix/sdk/logger.ts +108 -0
  150. package/src/matrix/sdk/read-response-with-limit.ts +19 -0
  151. package/src/matrix/sdk/recovery-key-store.ts +453 -0
  152. package/src/matrix/sdk/timeout-abort-signal.ts +1 -0
  153. package/src/matrix/sdk/transport-runtime-api.ts +18 -0
  154. package/src/matrix/sdk/transport.ts +352 -0
  155. package/src/matrix/sdk/types.ts +245 -0
  156. package/src/matrix/sdk/verification-manager.ts +795 -0
  157. package/src/matrix/sdk/verification-status.ts +23 -0
  158. package/src/matrix/sdk.ts +2152 -0
  159. package/src/matrix/send/client.ts +93 -0
  160. package/src/matrix/send/formatting.ts +189 -0
  161. package/src/matrix/send/media.ts +244 -0
  162. package/src/matrix/send/targets.ts +104 -0
  163. package/src/matrix/send/types.ts +131 -0
  164. package/src/matrix/send.ts +660 -0
  165. package/src/matrix/session-store-metadata.ts +108 -0
  166. package/src/matrix/startup-abort.ts +44 -0
  167. package/src/matrix/subagent-hooks.ts +308 -0
  168. package/src/matrix/sync-state.ts +27 -0
  169. package/src/matrix/target-ids.ts +79 -0
  170. package/src/matrix/thread-bindings-shared.ts +206 -0
  171. package/src/matrix/thread-bindings.ts +580 -0
  172. package/src/matrix-migration.runtime.ts +9 -0
  173. package/src/migration-config.ts +243 -0
  174. package/src/migration-snapshot-backup.ts +116 -0
  175. package/src/migration-snapshot.ts +53 -0
  176. package/src/onboarding.ts +775 -0
  177. package/src/outbound.ts +248 -0
  178. package/src/plugin-entry.runtime.js +115 -0
  179. package/src/plugin-entry.runtime.ts +70 -0
  180. package/src/profile-update.ts +71 -0
  181. package/src/record-shared.ts +3 -0
  182. package/src/resolve-targets.ts +175 -0
  183. package/src/resolver.runtime.ts +5 -0
  184. package/src/resolver.ts +21 -0
  185. package/src/runtime-api.ts +106 -0
  186. package/src/runtime.ts +13 -0
  187. package/src/secret-contract.ts +174 -0
  188. package/src/session-route.ts +126 -0
  189. package/src/setup-bootstrap.ts +102 -0
  190. package/src/setup-config.ts +222 -0
  191. package/src/setup-contract.ts +90 -0
  192. package/src/setup-core.ts +146 -0
  193. package/src/setup-dm-policy.ts +15 -0
  194. package/src/setup-surface.ts +4 -0
  195. package/src/startup-maintenance.ts +114 -0
  196. package/src/storage-paths.ts +92 -0
  197. package/src/thread-binding-api.ts +23 -0
  198. package/src/tool-actions.runtime.ts +1 -0
  199. package/src/tool-actions.ts +498 -0
  200. package/src/types.ts +257 -0
  201. package/subagent-hooks-api.ts +31 -0
  202. package/test-api.ts +21 -0
  203. package/thread-binding-api.ts +4 -0
  204. package/thread-bindings-runtime.ts +4 -0
  205. package/tsconfig.json +16 -0
@@ -0,0 +1,21 @@
1
+ import type { ChannelPlugin } from "autobot/plugin-sdk/channel-core";
2
+ import { createLazyRuntimeNamedExport } from "autobot/plugin-sdk/lazy-runtime";
3
+ import type { ResolvedMatrixAccount } from "./matrix/accounts.js";
4
+
5
+ const loadMatrixChannelRuntime = createLazyRuntimeNamedExport(
6
+ () => import("./resolver.runtime.js"),
7
+ "matrixResolverRuntime",
8
+ );
9
+
10
+ type MatrixResolver = NonNullable<ChannelPlugin<ResolvedMatrixAccount>["resolver"]>;
11
+
12
+ export const matrixResolverAdapter: MatrixResolver = {
13
+ resolveTargets: async ({ cfg, accountId, inputs, kind, runtime }) =>
14
+ (await loadMatrixChannelRuntime()).resolveMatrixTargets({
15
+ cfg,
16
+ accountId,
17
+ inputs,
18
+ kind,
19
+ runtime,
20
+ }),
21
+ };
@@ -0,0 +1,106 @@
1
+ export {
2
+ DEFAULT_ACCOUNT_ID,
3
+ normalizeAccountId,
4
+ normalizeOptionalAccountId,
5
+ } from "autobot/plugin-sdk/account-id";
6
+ export {
7
+ createActionGate,
8
+ jsonResult,
9
+ readNumberParam,
10
+ readReactionParams,
11
+ readStringArrayParam,
12
+ readStringParam,
13
+ ToolAuthorizationError,
14
+ } from "autobot/plugin-sdk/channel-actions";
15
+ export { buildChannelConfigSchema } from "autobot/plugin-sdk/channel-config-primitives";
16
+ export type { ChannelPlugin } from "autobot/plugin-sdk/channel-core";
17
+ export type {
18
+ BaseProbeResult,
19
+ ChannelDirectoryEntry,
20
+ ChannelGroupContext,
21
+ ChannelMessageActionAdapter,
22
+ ChannelMessageActionContext,
23
+ ChannelMessageActionName,
24
+ ChannelMessageToolDiscovery,
25
+ ChannelOutboundAdapter,
26
+ ChannelResolveKind,
27
+ ChannelResolveResult,
28
+ ChannelToolSend,
29
+ } from "autobot/plugin-sdk/channel-contract";
30
+ export {
31
+ formatLocationText,
32
+ toLocationContext,
33
+ type NormalizedLocation,
34
+ } from "autobot/plugin-sdk/channel-location";
35
+ export { logInboundDrop, logTypingFailure } from "autobot/plugin-sdk/channel-logging";
36
+ export { resolveAckReaction } from "autobot/plugin-sdk/channel-feedback";
37
+ export type { ChannelSetupInput } from "autobot/plugin-sdk/setup";
38
+ export type {
39
+ AutoBotConfig,
40
+ ContextVisibilityMode,
41
+ DmPolicy,
42
+ GroupPolicy,
43
+ } from "autobot/plugin-sdk/config-contracts";
44
+ export type { GroupToolPolicyConfig } from "autobot/plugin-sdk/config-contracts";
45
+ export type { WizardPrompter } from "autobot/plugin-sdk/setup";
46
+ export type { SecretInput } from "autobot/plugin-sdk/secret-input";
47
+ export {
48
+ GROUP_POLICY_BLOCKED_LABEL,
49
+ resolveAllowlistProviderRuntimeGroupPolicy,
50
+ resolveDefaultGroupPolicy,
51
+ warnMissingProviderGroupPolicyFallbackOnce,
52
+ } from "autobot/plugin-sdk/runtime-group-policy";
53
+ export {
54
+ addWildcardAllowFrom,
55
+ formatDocsLink,
56
+ hasConfiguredSecretInput,
57
+ mergeAllowFromEntries,
58
+ moveSingleAccountChannelSectionToDefaultAccount,
59
+ promptAccountId,
60
+ promptChannelAccessConfig,
61
+ splitSetupEntries,
62
+ } from "autobot/plugin-sdk/setup";
63
+ export type { RuntimeEnv } from "autobot/plugin-sdk/runtime";
64
+ export {
65
+ assertHttpUrlTargetsPrivateNetwork,
66
+ closeDispatcher,
67
+ createPinnedDispatcher,
68
+ isPrivateOrLoopbackHost,
69
+ resolvePinnedHostnameWithPolicy,
70
+ ssrfPolicyFromDangerouslyAllowPrivateNetwork,
71
+ ssrfPolicyFromAllowPrivateNetwork,
72
+ type LookupFn,
73
+ type SsrFPolicy,
74
+ } from "autobot/plugin-sdk/ssrf-runtime";
75
+ export { dispatchReplyFromConfigWithSettledDispatcher } from "autobot/plugin-sdk/inbound-reply-dispatch";
76
+ export {
77
+ ensureConfiguredAcpBindingReady,
78
+ resolveConfiguredAcpBindingRecord,
79
+ } from "autobot/plugin-sdk/acp-binding-runtime";
80
+ export {
81
+ buildProbeChannelStatusSummary,
82
+ collectStatusIssuesFromLastError,
83
+ PAIRING_APPROVED_MESSAGE,
84
+ } from "autobot/plugin-sdk/channel-status";
85
+ export {
86
+ getSessionBindingService,
87
+ resolveThreadBindingIdleTimeoutMsForChannel,
88
+ resolveThreadBindingMaxAgeMsForChannel,
89
+ } from "autobot/plugin-sdk/conversation-runtime";
90
+ export { resolveOutboundSendDep } from "autobot/plugin-sdk/outbound-send-deps";
91
+ export { resolveAgentIdFromSessionKey } from "autobot/plugin-sdk/routing";
92
+ export { chunkTextForOutbound } from "autobot/plugin-sdk/text-chunking";
93
+ export { createChannelMessageReplyPipeline } from "autobot/plugin-sdk/channel-message";
94
+ export { loadOutboundMediaFromUrl } from "autobot/plugin-sdk/outbound-media";
95
+ export { normalizePollInput, type PollInput } from "autobot/plugin-sdk/poll-runtime";
96
+ export { writeJsonFileAtomically } from "autobot/plugin-sdk/json-store";
97
+ export {
98
+ buildChannelKeyCandidates,
99
+ resolveChannelEntryMatch,
100
+ } from "autobot/plugin-sdk/channel-targets";
101
+ export { buildTimeoutAbortSignal } from "./matrix/sdk/timeout-abort-signal.js";
102
+ export { formatZonedTimestamp } from "autobot/plugin-sdk/time-runtime";
103
+ export type { PluginRuntime, RuntimeLogger } from "autobot/plugin-sdk/plugin-runtime";
104
+ export type { ReplyPayload } from "autobot/plugin-sdk/reply-runtime";
105
+ // resolveMatrixAccountStringValues already comes from the Matrix API barrel.
106
+ // Re-exporting auth-precedence here makes TS source loaders define the export twice.
package/src/runtime.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { createPluginRuntimeStore } from "autobot/plugin-sdk/runtime-store";
2
+ import type { PluginRuntime } from "./runtime-api.js";
3
+
4
+ const {
5
+ setRuntime: setMatrixRuntime,
6
+ getRuntime: getMatrixRuntime,
7
+ tryGetRuntime: getOptionalMatrixRuntime,
8
+ } = createPluginRuntimeStore<PluginRuntime>({
9
+ pluginId: "matrix",
10
+ errorMessage: "Matrix runtime not initialized",
11
+ });
12
+
13
+ export { getMatrixRuntime, getOptionalMatrixRuntime, setMatrixRuntime };
@@ -0,0 +1,174 @@
1
+ import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "autobot/plugin-sdk/account-id";
2
+ import {
3
+ collectSecretInputAssignment,
4
+ getChannelSurface,
5
+ hasConfiguredSecretInputValue,
6
+ hasOwnProperty,
7
+ normalizeSecretStringValue,
8
+ type ResolverContext,
9
+ type SecretDefaults,
10
+ } from "autobot/plugin-sdk/channel-secret-basic-runtime";
11
+ import { getMatrixScopedEnvVarNames } from "./env-vars.js";
12
+
13
+ export const secretTargetRegistryEntries: import("autobot/plugin-sdk/channel-secret-basic-runtime").SecretTargetRegistryEntry[] =
14
+ [
15
+ {
16
+ id: "channels.matrix.accounts.*.accessToken",
17
+ targetType: "channels.matrix.accounts.*.accessToken",
18
+ configFile: "autobot.json",
19
+ pathPattern: "channels.matrix.accounts.*.accessToken",
20
+ secretShape: "secret_input",
21
+ expectedResolvedValue: "string",
22
+ includeInPlan: true,
23
+ includeInConfigure: true,
24
+ includeInAudit: true,
25
+ },
26
+ {
27
+ id: "channels.matrix.accounts.*.password",
28
+ targetType: "channels.matrix.accounts.*.password",
29
+ configFile: "autobot.json",
30
+ pathPattern: "channels.matrix.accounts.*.password",
31
+ secretShape: "secret_input",
32
+ expectedResolvedValue: "string",
33
+ includeInPlan: true,
34
+ includeInConfigure: true,
35
+ includeInAudit: true,
36
+ },
37
+ {
38
+ id: "channels.matrix.accessToken",
39
+ targetType: "channels.matrix.accessToken",
40
+ configFile: "autobot.json",
41
+ pathPattern: "channels.matrix.accessToken",
42
+ secretShape: "secret_input",
43
+ expectedResolvedValue: "string",
44
+ includeInPlan: true,
45
+ includeInConfigure: true,
46
+ includeInAudit: true,
47
+ },
48
+ {
49
+ id: "channels.matrix.password",
50
+ targetType: "channels.matrix.password",
51
+ configFile: "autobot.json",
52
+ pathPattern: "channels.matrix.password",
53
+ secretShape: "secret_input",
54
+ expectedResolvedValue: "string",
55
+ includeInPlan: true,
56
+ includeInConfigure: true,
57
+ includeInAudit: true,
58
+ },
59
+ ];
60
+
61
+ export function collectRuntimeConfigAssignments(params: {
62
+ config: { channels?: Record<string, unknown> };
63
+ defaults?: SecretDefaults;
64
+ context: ResolverContext;
65
+ }): void {
66
+ const resolved = getChannelSurface(params.config, "matrix");
67
+ if (!resolved) {
68
+ return;
69
+ }
70
+ const { channel: matrix, surface } = resolved;
71
+ const envAccessTokenConfigured =
72
+ normalizeSecretStringValue(params.context.env.MATRIX_ACCESS_TOKEN).length > 0;
73
+ const defaultScopedAccessTokenConfigured =
74
+ normalizeSecretStringValue(
75
+ params.context.env[getMatrixScopedEnvVarNames("default").accessToken],
76
+ ).length > 0;
77
+ const defaultAccountAccessTokenConfigured = surface.accounts.some(
78
+ ({ accountId, account }) =>
79
+ normalizeAccountId(accountId) === DEFAULT_ACCOUNT_ID &&
80
+ hasConfiguredSecretInputValue(account.accessToken, params.defaults),
81
+ );
82
+ const baseAccessTokenConfigured = hasConfiguredSecretInputValue(
83
+ matrix.accessToken,
84
+ params.defaults,
85
+ );
86
+ collectSecretInputAssignment({
87
+ value: matrix.accessToken,
88
+ path: "channels.matrix.accessToken",
89
+ expected: "string",
90
+ defaults: params.defaults,
91
+ context: params.context,
92
+ active: surface.channelEnabled,
93
+ inactiveReason: "Matrix channel is disabled.",
94
+ apply: (value) => {
95
+ matrix.accessToken = value;
96
+ },
97
+ });
98
+ collectSecretInputAssignment({
99
+ value: matrix.password,
100
+ path: "channels.matrix.password",
101
+ expected: "string",
102
+ defaults: params.defaults,
103
+ context: params.context,
104
+ active:
105
+ surface.channelEnabled &&
106
+ !(
107
+ baseAccessTokenConfigured ||
108
+ envAccessTokenConfigured ||
109
+ defaultScopedAccessTokenConfigured ||
110
+ defaultAccountAccessTokenConfigured
111
+ ),
112
+ inactiveReason:
113
+ "Matrix channel is disabled or access-token auth is configured for the default Matrix account.",
114
+ apply: (value) => {
115
+ matrix.password = value;
116
+ },
117
+ });
118
+ if (!surface.hasExplicitAccounts) {
119
+ return;
120
+ }
121
+ for (const { accountId, account, enabled } of surface.accounts) {
122
+ if (hasOwnProperty(account, "accessToken")) {
123
+ collectSecretInputAssignment({
124
+ value: account.accessToken,
125
+ path: `channels.matrix.accounts.${accountId}.accessToken`,
126
+ expected: "string",
127
+ defaults: params.defaults,
128
+ context: params.context,
129
+ active: enabled,
130
+ inactiveReason: "Matrix account is disabled.",
131
+ apply: (value) => {
132
+ account.accessToken = value;
133
+ },
134
+ });
135
+ }
136
+ if (!hasOwnProperty(account, "password")) {
137
+ continue;
138
+ }
139
+ const accountAccessTokenConfigured = hasConfiguredSecretInputValue(
140
+ account.accessToken,
141
+ params.defaults,
142
+ );
143
+ const scopedEnvAccessTokenConfigured =
144
+ normalizeSecretStringValue(
145
+ params.context.env[getMatrixScopedEnvVarNames(accountId).accessToken],
146
+ ).length > 0;
147
+ const inheritedDefaultAccountAccessTokenConfigured =
148
+ normalizeAccountId(accountId) === DEFAULT_ACCOUNT_ID &&
149
+ (baseAccessTokenConfigured || envAccessTokenConfigured);
150
+ collectSecretInputAssignment({
151
+ value: account.password,
152
+ path: `channels.matrix.accounts.${accountId}.password`,
153
+ expected: "string",
154
+ defaults: params.defaults,
155
+ context: params.context,
156
+ active:
157
+ enabled &&
158
+ !(
159
+ accountAccessTokenConfigured ||
160
+ scopedEnvAccessTokenConfigured ||
161
+ inheritedDefaultAccountAccessTokenConfigured
162
+ ),
163
+ inactiveReason: "Matrix account is disabled or this account has an accessToken configured.",
164
+ apply: (value) => {
165
+ account.password = value;
166
+ },
167
+ });
168
+ }
169
+ }
170
+
171
+ export const channelSecrets = {
172
+ secretTargetRegistryEntries,
173
+ collectRuntimeConfigAssignments,
174
+ };
@@ -0,0 +1,126 @@
1
+ import { normalizeAccountId } from "autobot/plugin-sdk/account-id";
2
+ import {
3
+ buildChannelOutboundSessionRoute,
4
+ buildThreadAwareOutboundSessionRoute,
5
+ type ChannelOutboundSessionRouteParams,
6
+ } from "autobot/plugin-sdk/channel-core";
7
+ import { parseThreadSessionSuffix } from "autobot/plugin-sdk/routing";
8
+ import {
9
+ loadSessionStore,
10
+ resolveSessionStoreEntry,
11
+ resolveStorePath,
12
+ } from "autobot/plugin-sdk/session-store-runtime";
13
+ import { resolveMatrixAccountConfig } from "./matrix/account-config.js";
14
+ import { resolveDefaultMatrixAccountId } from "./matrix/accounts.js";
15
+ import { resolveMatrixStoredSessionMeta } from "./matrix/session-store-metadata.js";
16
+ import { resolveMatrixTargetIdentity } from "./matrix/target-ids.js";
17
+
18
+ function resolveEffectiveMatrixAccountId(
19
+ params: Pick<ChannelOutboundSessionRouteParams, "cfg" | "accountId">,
20
+ ): string {
21
+ return normalizeAccountId(params.accountId ?? resolveDefaultMatrixAccountId(params.cfg));
22
+ }
23
+
24
+ function resolveMatrixDmSessionScope(params: {
25
+ cfg: ChannelOutboundSessionRouteParams["cfg"];
26
+ accountId: string;
27
+ }): "per-user" | "per-room" {
28
+ return (
29
+ resolveMatrixAccountConfig({
30
+ cfg: params.cfg,
31
+ accountId: params.accountId,
32
+ }).dm?.sessionScope ?? "per-user"
33
+ );
34
+ }
35
+
36
+ function resolveMatrixCurrentDmRoomId(params: {
37
+ cfg: ChannelOutboundSessionRouteParams["cfg"];
38
+ agentId: string;
39
+ accountId: string;
40
+ currentSessionKey?: string;
41
+ targetUserId: string;
42
+ }): string | undefined {
43
+ const sessionKey =
44
+ parseThreadSessionSuffix(params.currentSessionKey).baseSessionKey ??
45
+ params.currentSessionKey?.trim();
46
+ if (!sessionKey) {
47
+ return undefined;
48
+ }
49
+ try {
50
+ const storePath = resolveStorePath(params.cfg.session?.store, {
51
+ agentId: params.agentId,
52
+ });
53
+ const store = loadSessionStore(storePath);
54
+ const existing = resolveSessionStoreEntry({
55
+ store,
56
+ sessionKey,
57
+ }).existing;
58
+ const currentSession = resolveMatrixStoredSessionMeta(existing);
59
+ if (!currentSession) {
60
+ return undefined;
61
+ }
62
+ if (currentSession.accountId && currentSession.accountId !== params.accountId) {
63
+ return undefined;
64
+ }
65
+ if (!currentSession.directUserId || currentSession.directUserId !== params.targetUserId) {
66
+ return undefined;
67
+ }
68
+ return currentSession.roomId;
69
+ } catch {
70
+ return undefined;
71
+ }
72
+ }
73
+
74
+ export function resolveMatrixOutboundSessionRoute(params: ChannelOutboundSessionRouteParams) {
75
+ const target =
76
+ resolveMatrixTargetIdentity(params.resolvedTarget?.to ?? params.target) ??
77
+ resolveMatrixTargetIdentity(params.target);
78
+ if (!target) {
79
+ return null;
80
+ }
81
+ const effectiveAccountId = resolveEffectiveMatrixAccountId(params);
82
+ const roomScopedDmId =
83
+ target.kind === "user" &&
84
+ resolveMatrixDmSessionScope({
85
+ cfg: params.cfg,
86
+ accountId: effectiveAccountId,
87
+ }) === "per-room"
88
+ ? resolveMatrixCurrentDmRoomId({
89
+ cfg: params.cfg,
90
+ agentId: params.agentId,
91
+ accountId: effectiveAccountId,
92
+ currentSessionKey: params.currentSessionKey,
93
+ targetUserId: target.id,
94
+ })
95
+ : undefined;
96
+ const peer =
97
+ roomScopedDmId !== undefined
98
+ ? { kind: "channel" as const, id: roomScopedDmId }
99
+ : {
100
+ kind: target.kind === "user" ? ("direct" as const) : ("channel" as const),
101
+ id: target.id,
102
+ };
103
+ const chatType = target.kind === "user" ? "direct" : "channel";
104
+ const from = target.kind === "user" ? `matrix:${target.id}` : `matrix:channel:${target.id}`;
105
+ const to = `room:${roomScopedDmId ?? target.id}`;
106
+
107
+ const baseRoute = buildChannelOutboundSessionRoute({
108
+ cfg: params.cfg,
109
+ agentId: params.agentId,
110
+ channel: "matrix",
111
+ accountId: effectiveAccountId,
112
+ peer,
113
+ chatType,
114
+ from,
115
+ to,
116
+ });
117
+ return buildThreadAwareOutboundSessionRoute({
118
+ route: baseRoute,
119
+ replyToId: params.replyToId,
120
+ threadId: params.threadId,
121
+ currentSessionKey: params.currentSessionKey,
122
+ normalizeThreadId: (threadId) => threadId,
123
+ canRecoverCurrentThread: ({ route }) =>
124
+ route.peer.kind !== "direct" || (params.cfg.session?.dmScope ?? "main") !== "main",
125
+ });
126
+ }
@@ -0,0 +1,102 @@
1
+ import { hasExplicitMatrixAccountConfig } from "./matrix/account-config.js";
2
+ import { resolveMatrixAccountConfig } from "./matrix/accounts.js";
3
+ import { bootstrapMatrixVerification } from "./matrix/actions/verification.js";
4
+ import { formatMatrixErrorMessage } from "./matrix/errors.js";
5
+ import type { RuntimeEnv } from "./runtime-api.js";
6
+ import type { CoreConfig } from "./types.js";
7
+
8
+ export type MatrixSetupVerificationBootstrapResult = {
9
+ attempted: boolean;
10
+ success: boolean;
11
+ recoveryKeyCreatedAt: string | null;
12
+ backupVersion: string | null;
13
+ error?: string;
14
+ };
15
+
16
+ export async function maybeBootstrapNewEncryptedMatrixAccount(params: {
17
+ previousCfg: CoreConfig;
18
+ cfg: CoreConfig;
19
+ accountId: string;
20
+ }): Promise<MatrixSetupVerificationBootstrapResult> {
21
+ const accountConfig = resolveMatrixAccountConfig({
22
+ cfg: params.cfg,
23
+ accountId: params.accountId,
24
+ });
25
+ const previousAccountConfig = resolveMatrixAccountConfig({
26
+ cfg: params.previousCfg,
27
+ accountId: params.accountId,
28
+ });
29
+
30
+ if (
31
+ accountConfig.encryption !== true ||
32
+ (hasExplicitMatrixAccountConfig(params.previousCfg, params.accountId) &&
33
+ previousAccountConfig.encryption === true)
34
+ ) {
35
+ return {
36
+ attempted: false,
37
+ success: false,
38
+ recoveryKeyCreatedAt: null,
39
+ backupVersion: null,
40
+ };
41
+ }
42
+
43
+ try {
44
+ const bootstrap = await bootstrapMatrixVerification({
45
+ accountId: params.accountId,
46
+ cfg: params.cfg,
47
+ });
48
+ return {
49
+ attempted: true,
50
+ success: bootstrap.success,
51
+ recoveryKeyCreatedAt: bootstrap.verification.recoveryKeyCreatedAt,
52
+ backupVersion: bootstrap.verification.backupVersion,
53
+ ...(bootstrap.success
54
+ ? {}
55
+ : { error: bootstrap.error ?? "Matrix verification bootstrap failed" }),
56
+ };
57
+ } catch (err) {
58
+ return {
59
+ attempted: true,
60
+ success: false,
61
+ recoveryKeyCreatedAt: null,
62
+ backupVersion: null,
63
+ error: formatMatrixErrorMessage(err),
64
+ };
65
+ }
66
+ }
67
+
68
+ export async function runMatrixSetupBootstrapAfterConfigWrite(params: {
69
+ previousCfg: CoreConfig;
70
+ cfg: CoreConfig;
71
+ accountId: string;
72
+ runtime: RuntimeEnv;
73
+ }): Promise<void> {
74
+ const nextAccountConfig = resolveMatrixAccountConfig({
75
+ cfg: params.cfg,
76
+ accountId: params.accountId,
77
+ });
78
+ if (nextAccountConfig.encryption !== true) {
79
+ return;
80
+ }
81
+
82
+ const bootstrap = await maybeBootstrapNewEncryptedMatrixAccount({
83
+ previousCfg: params.previousCfg,
84
+ cfg: params.cfg,
85
+ accountId: params.accountId,
86
+ });
87
+ if (!bootstrap.attempted) {
88
+ return;
89
+ }
90
+ if (bootstrap.success) {
91
+ params.runtime.log(`Matrix verification bootstrap: complete for "${params.accountId}".`);
92
+ if (bootstrap.backupVersion) {
93
+ params.runtime.log(
94
+ `Matrix backup version for "${params.accountId}": ${bootstrap.backupVersion}`,
95
+ );
96
+ }
97
+ return;
98
+ }
99
+ params.runtime.error(
100
+ `Matrix verification bootstrap warning for "${params.accountId}": ${bootstrap.error ?? "unknown bootstrap failure"}`,
101
+ );
102
+ }