@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
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "@gakr-gakr/matrix",
3
+ "version": "0.1.0",
4
+ "description": "AutoBot Matrix channel plugin",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/autobot/autobot"
8
+ },
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@matrix-org/matrix-sdk-crypto-nodejs": "0.5.1",
12
+ "@matrix-org/matrix-sdk-crypto-wasm": "18.3.0",
13
+ "fake-indexeddb": "6.2.5",
14
+ "markdown-it": "14.1.1",
15
+ "matrix-js-sdk": "41.5.0",
16
+ "music-metadata": "11.12.3",
17
+ "typebox": "1.1.38",
18
+ "zod": "4.4.3"
19
+ },
20
+ "devDependencies": {
21
+ "@gakr-gakr/plugin-sdk": "workspace:*",
22
+ "@gakr-gakr/autobot": "workspace:*",
23
+ "autobot": "workspace:@gakr-gakr/autobot@*"
24
+ },
25
+ "peerDependencies": {
26
+ "@gakr-gakr/autobot": ">=0.1.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "@gakr-gakr/autobot": {
30
+ "optional": true
31
+ }
32
+ },
33
+ "autobot": {
34
+ "extensions": [
35
+ "./index.ts"
36
+ ],
37
+ "setupEntry": "./setup-entry.ts",
38
+ "setupFeatures": {
39
+ "configPromotion": true
40
+ },
41
+ "channel": {
42
+ "id": "matrix",
43
+ "label": "Matrix",
44
+ "selectionLabel": "Matrix (plugin)",
45
+ "docsPath": "/channels/matrix",
46
+ "docsLabel": "matrix",
47
+ "blurb": "open protocol; install the plugin to enable.",
48
+ "order": 70,
49
+ "quickstartAllowFrom": true,
50
+ "doctorCapabilities": {
51
+ "dmAllowFromMode": "nestedOnly",
52
+ "groupModel": "sender",
53
+ "groupAllowFromFallbackToAllowFrom": false,
54
+ "warnOnEmptyGroupSenderAllowlist": true
55
+ },
56
+ "cliAddOptions": [
57
+ {
58
+ "flags": "--homeserver <url>",
59
+ "description": "Matrix homeserver URL"
60
+ },
61
+ {
62
+ "flags": "--user-id <id>",
63
+ "description": "Matrix user ID"
64
+ },
65
+ {
66
+ "flags": "--access-token <token>",
67
+ "description": "Matrix access token"
68
+ },
69
+ {
70
+ "flags": "--device-name <name>",
71
+ "description": "Matrix device name"
72
+ },
73
+ {
74
+ "flags": "--initial-sync-limit <n>",
75
+ "description": "Matrix initial sync limit"
76
+ }
77
+ ],
78
+ "persistedAuthState": {
79
+ "specifier": "./auth-presence",
80
+ "exportName": "hasAnyMatrixAuth"
81
+ }
82
+ },
83
+ "install": {
84
+ "clawhubSpec": "clawhub:@gakr-gakr/matrix",
85
+ "npmSpec": "@gakr-gakr/matrix",
86
+ "defaultChoice": "clawhub",
87
+ "minHostVersion": ">=2026.4.10",
88
+ "allowInvalidConfigRecovery": true
89
+ },
90
+ "compat": {
91
+ "pluginApi": ">=2026.5.19"
92
+ },
93
+ "build": {
94
+ "autobotVersion": "2026.5.19"
95
+ },
96
+ "release": {
97
+ "publishToClawHub": true,
98
+ "publishToNpm": true
99
+ }
100
+ }
101
+ }
@@ -0,0 +1 @@
1
+ export * from "./src/plugin-entry.runtime.ts";
package/runtime-api.ts ADDED
@@ -0,0 +1,72 @@
1
+ export {
2
+ type MatrixResolvedStringField,
3
+ type MatrixResolvedStringValues,
4
+ resolveMatrixAccountStringValues,
5
+ } from "./src/auth-precedence.js";
6
+ export {
7
+ requiresExplicitMatrixDefaultAccount,
8
+ resolveMatrixDefaultOrOnlyAccountId,
9
+ } from "./src/account-selection.js";
10
+ export {
11
+ findMatrixAccountEntry,
12
+ resolveConfiguredMatrixAccountIds,
13
+ resolveMatrixChannelConfig,
14
+ } from "./src/account-selection.js";
15
+ export {
16
+ getMatrixScopedEnvVarNames,
17
+ listMatrixEnvAccountIds,
18
+ resolveMatrixEnvAccountToken,
19
+ } from "./src/env-vars.js";
20
+ export {
21
+ hashMatrixAccessToken,
22
+ resolveMatrixAccountStorageRoot,
23
+ resolveMatrixCredentialsDir,
24
+ resolveMatrixCredentialsFilename,
25
+ resolveMatrixCredentialsPath,
26
+ resolveMatrixHomeserverKey,
27
+ resolveMatrixLegacyFlatStoragePaths,
28
+ resolveMatrixLegacyFlatStoreRoot,
29
+ sanitizeMatrixPathSegment,
30
+ } from "./src/storage-paths.js";
31
+ export { ensureMatrixSdkInstalled, isMatrixSdkAvailable } from "./src/matrix/deps.js";
32
+ export {
33
+ assertHttpUrlTargetsPrivateNetwork,
34
+ closeDispatcher,
35
+ createPinnedDispatcher,
36
+ resolvePinnedHostnameWithPolicy,
37
+ ssrfPolicyFromDangerouslyAllowPrivateNetwork,
38
+ ssrfPolicyFromAllowPrivateNetwork,
39
+ type LookupFn,
40
+ type SsrFPolicy,
41
+ } from "autobot/plugin-sdk/ssrf-runtime";
42
+ export {
43
+ setMatrixThreadBindingIdleTimeoutBySessionKey,
44
+ setMatrixThreadBindingMaxAgeBySessionKey,
45
+ } from "./src/matrix/thread-bindings-shared.js";
46
+ export { setMatrixRuntime } from "./src/runtime.js";
47
+ export { writeJsonFileAtomically } from "autobot/plugin-sdk/json-store";
48
+ export type {
49
+ ChannelDirectoryEntry,
50
+ ChannelMessageActionContext,
51
+ } from "autobot/plugin-sdk/channel-contract";
52
+ export type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
53
+ export { formatZonedTimestamp } from "autobot/plugin-sdk/time-runtime";
54
+ export type { PluginRuntime, RuntimeLogger } from "autobot/plugin-sdk/plugin-runtime";
55
+ export type { RuntimeEnv } from "autobot/plugin-sdk/runtime-env";
56
+ export type { WizardPrompter } from "autobot/plugin-sdk/setup";
57
+
58
+ export function chunkTextForOutbound(text: string, limit: number): string[] {
59
+ const chunks: string[] = [];
60
+ let remaining = text;
61
+ while (remaining.length > limit) {
62
+ const window = remaining.slice(0, limit);
63
+ const splitAt = Math.max(window.lastIndexOf("\n"), window.lastIndexOf(" "));
64
+ const breakAt = splitAt > 0 ? splitAt : limit;
65
+ chunks.push(remaining.slice(0, breakAt).trimEnd());
66
+ remaining = remaining.slice(breakAt).trimStart();
67
+ }
68
+ if (remaining.length > 0 || text.length === 0) {
69
+ chunks.push(remaining);
70
+ }
71
+ return chunks;
72
+ }
@@ -0,0 +1 @@
1
+ export * from "./src/matrix-migration.runtime.js";
@@ -0,0 +1,3 @@
1
+ // Narrow entry point for setMatrixRuntime. The full runtime-api barrel is kept
2
+ // for external/runtime callers, but bundled plugin register only needs this.
3
+ export { setMatrixRuntime } from "./src/runtime.js";
@@ -0,0 +1,5 @@
1
+ export {
2
+ channelSecrets,
3
+ collectRuntimeConfigAssignments,
4
+ secretTargetRegistryEntries,
5
+ } from "./src/secret-contract.js";
package/setup-entry.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { defineBundledChannelSetupEntry } from "autobot/plugin-sdk/channel-entry-contract";
2
+
3
+ export default defineBundledChannelSetupEntry({
4
+ importMetaUrl: import.meta.url,
5
+ plugin: {
6
+ specifier: "./setup-plugin-api.js",
7
+ exportName: "matrixSetupPlugin",
8
+ },
9
+ secrets: {
10
+ specifier: "./secret-contract-api.js",
11
+ exportName: "channelSecrets",
12
+ },
13
+ runtime: {
14
+ specifier: "./runtime-setter-api.js",
15
+ exportName: "setMatrixRuntime",
16
+ },
17
+ });
@@ -0,0 +1,3 @@
1
+ // Keep bundled setup entry imports narrow so setup loads do not pull the
2
+ // broader Matrix runtime plugin surface.
3
+ export { matrixSetupPlugin } from "./src/channel.setup.js";
@@ -0,0 +1,223 @@
1
+ import {
2
+ listCombinedAccountIds,
3
+ listConfiguredAccountIds,
4
+ resolveListedDefaultAccountId,
5
+ resolveNormalizedAccountEntry,
6
+ } from "autobot/plugin-sdk/account-core";
7
+ import {
8
+ DEFAULT_ACCOUNT_ID,
9
+ normalizeAccountId,
10
+ normalizeOptionalAccountId,
11
+ } from "autobot/plugin-sdk/account-id";
12
+ import type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
13
+ import { hasConfiguredSecretInput } from "autobot/plugin-sdk/secret-input-runtime";
14
+ import { normalizeOptionalString } from "autobot/plugin-sdk/string-coerce-runtime";
15
+ import {
16
+ resolveMatrixAccountStringValues,
17
+ type MatrixResolvedStringField,
18
+ } from "./auth-precedence.js";
19
+ import { getMatrixScopedEnvVarNames, listMatrixEnvAccountIds } from "./env-vars.js";
20
+ import { isRecord } from "./record-shared.js";
21
+
22
+ type MatrixTopologyStringSources = Partial<Record<MatrixResolvedStringField, string>>;
23
+
24
+ function readConfiguredMatrixString(value: unknown): string {
25
+ return normalizeOptionalString(value) ?? "";
26
+ }
27
+
28
+ function readConfiguredMatrixSecretSource(value: unknown): string {
29
+ return hasConfiguredSecretInput(value) ? "configured" : "";
30
+ }
31
+
32
+ function resolveMatrixChannelStringSources(
33
+ entry: Record<string, unknown> | null,
34
+ ): MatrixTopologyStringSources {
35
+ if (!entry) {
36
+ return {};
37
+ }
38
+ return {
39
+ homeserver: readConfiguredMatrixString(entry.homeserver),
40
+ userId: readConfiguredMatrixString(entry.userId),
41
+ accessToken: readConfiguredMatrixSecretSource(entry.accessToken),
42
+ password: readConfiguredMatrixSecretSource(entry.password),
43
+ deviceId: readConfiguredMatrixString(entry.deviceId),
44
+ deviceName: readConfiguredMatrixString(entry.deviceName),
45
+ };
46
+ }
47
+
48
+ function readEnvMatrixString(env: NodeJS.ProcessEnv, key: string): string {
49
+ return normalizeOptionalString(env[key]) ?? "";
50
+ }
51
+
52
+ function resolveScopedMatrixEnvStringSources(
53
+ accountId: string,
54
+ env: NodeJS.ProcessEnv,
55
+ ): MatrixTopologyStringSources {
56
+ const keys = getMatrixScopedEnvVarNames(accountId);
57
+ return {
58
+ homeserver: readEnvMatrixString(env, keys.homeserver),
59
+ userId: readEnvMatrixString(env, keys.userId),
60
+ accessToken: readEnvMatrixString(env, keys.accessToken),
61
+ password: readEnvMatrixString(env, keys.password),
62
+ deviceId: readEnvMatrixString(env, keys.deviceId),
63
+ deviceName: readEnvMatrixString(env, keys.deviceName),
64
+ };
65
+ }
66
+
67
+ function resolveGlobalMatrixEnvStringSources(env: NodeJS.ProcessEnv): MatrixTopologyStringSources {
68
+ return {
69
+ homeserver: readEnvMatrixString(env, "MATRIX_HOMESERVER"),
70
+ userId: readEnvMatrixString(env, "MATRIX_USER_ID"),
71
+ accessToken: readEnvMatrixString(env, "MATRIX_ACCESS_TOKEN"),
72
+ password: readEnvMatrixString(env, "MATRIX_PASSWORD"),
73
+ deviceId: readEnvMatrixString(env, "MATRIX_DEVICE_ID"),
74
+ deviceName: readEnvMatrixString(env, "MATRIX_DEVICE_NAME"),
75
+ };
76
+ }
77
+
78
+ function hasUsableResolvedMatrixAuth(values: {
79
+ homeserver: string;
80
+ userId: string;
81
+ accessToken: string;
82
+ }): boolean {
83
+ // Account discovery must keep homeserver+userId shapes because auth can still
84
+ // resolve through cached Matrix credentials even when no fresh token/password
85
+ // is present in config or env.
86
+ return Boolean(values.homeserver && (values.accessToken || values.userId));
87
+ }
88
+
89
+ function hasFreshResolvedMatrixAuth(values: {
90
+ homeserver: string;
91
+ userId: string;
92
+ accessToken: string;
93
+ password: string;
94
+ }): boolean {
95
+ return Boolean(values.homeserver && (values.accessToken || (values.userId && values.password)));
96
+ }
97
+
98
+ function resolveEffectiveMatrixAccountSources(params: {
99
+ channel: Record<string, unknown> | null;
100
+ accountId: string;
101
+ env: NodeJS.ProcessEnv;
102
+ }): ReturnType<typeof resolveMatrixAccountStringValues> {
103
+ const normalizedAccountId = normalizeAccountId(params.accountId);
104
+ return resolveMatrixAccountStringValues({
105
+ accountId: normalizedAccountId,
106
+ scopedEnv: resolveScopedMatrixEnvStringSources(normalizedAccountId, params.env),
107
+ channel: resolveMatrixChannelStringSources(params.channel),
108
+ globalEnv: resolveGlobalMatrixEnvStringSources(params.env),
109
+ });
110
+ }
111
+
112
+ function hasUsableEffectiveMatrixAccountSource(params: {
113
+ channel: Record<string, unknown> | null;
114
+ accountId: string;
115
+ env: NodeJS.ProcessEnv;
116
+ }): boolean {
117
+ return hasUsableResolvedMatrixAuth(resolveEffectiveMatrixAccountSources(params));
118
+ }
119
+
120
+ function hasFreshEffectiveMatrixAccountSource(params: {
121
+ channel: Record<string, unknown> | null;
122
+ accountId: string;
123
+ env: NodeJS.ProcessEnv;
124
+ }): boolean {
125
+ return hasFreshResolvedMatrixAuth(resolveEffectiveMatrixAccountSources(params));
126
+ }
127
+
128
+ function hasConfiguredDefaultMatrixAccountSource(params: {
129
+ channel: Record<string, unknown> | null;
130
+ env: NodeJS.ProcessEnv;
131
+ }): boolean {
132
+ return hasFreshEffectiveMatrixAccountSource({
133
+ channel: params.channel,
134
+ accountId: DEFAULT_ACCOUNT_ID,
135
+ env: params.env,
136
+ });
137
+ }
138
+
139
+ export function resolveMatrixChannelConfig(cfg: AutoBotConfig): Record<string, unknown> | null {
140
+ return isRecord(cfg.channels?.matrix) ? cfg.channels.matrix : null;
141
+ }
142
+
143
+ export function findMatrixAccountEntry(
144
+ cfg: AutoBotConfig,
145
+ accountId: string,
146
+ ): Record<string, unknown> | null {
147
+ const channel = resolveMatrixChannelConfig(cfg);
148
+ if (!channel) {
149
+ return null;
150
+ }
151
+
152
+ const accounts = isRecord(channel.accounts) ? channel.accounts : null;
153
+ if (!accounts) {
154
+ return null;
155
+ }
156
+ const entry = resolveNormalizedAccountEntry(accounts, accountId, normalizeAccountId);
157
+ return isRecord(entry) ? entry : null;
158
+ }
159
+
160
+ export function resolveConfiguredMatrixAccountIds(
161
+ cfg: AutoBotConfig,
162
+ env: NodeJS.ProcessEnv = process.env,
163
+ ): string[] {
164
+ const channel = resolveMatrixChannelConfig(cfg);
165
+ const configuredAccountIds = listConfiguredAccountIds({
166
+ accounts: channel && isRecord(channel.accounts) ? channel.accounts : undefined,
167
+ normalizeAccountId,
168
+ });
169
+ if (hasConfiguredDefaultMatrixAccountSource({ channel, env })) {
170
+ configuredAccountIds.push(DEFAULT_ACCOUNT_ID);
171
+ }
172
+ const readyEnvAccountIds = listMatrixEnvAccountIds(env).filter((accountId) =>
173
+ normalizeAccountId(accountId) === DEFAULT_ACCOUNT_ID
174
+ ? hasConfiguredDefaultMatrixAccountSource({ channel, env })
175
+ : hasUsableEffectiveMatrixAccountSource({ channel, accountId, env }),
176
+ );
177
+ return listCombinedAccountIds({
178
+ configuredAccountIds,
179
+ additionalAccountIds: readyEnvAccountIds,
180
+ fallbackAccountIdWhenEmpty: channel ? DEFAULT_ACCOUNT_ID : undefined,
181
+ });
182
+ }
183
+
184
+ export function resolveMatrixDefaultOrOnlyAccountId(
185
+ cfg: AutoBotConfig,
186
+ env: NodeJS.ProcessEnv = process.env,
187
+ ): string {
188
+ const channel = resolveMatrixChannelConfig(cfg);
189
+ if (!channel) {
190
+ return DEFAULT_ACCOUNT_ID;
191
+ }
192
+
193
+ const configuredDefault = normalizeOptionalAccountId(
194
+ typeof channel.defaultAccount === "string" ? channel.defaultAccount : undefined,
195
+ );
196
+ const configuredAccountIds = resolveConfiguredMatrixAccountIds(cfg, env);
197
+ return resolveListedDefaultAccountId({
198
+ accountIds: configuredAccountIds,
199
+ configuredDefaultAccountId: configuredDefault,
200
+ ambiguousFallbackAccountId: DEFAULT_ACCOUNT_ID,
201
+ });
202
+ }
203
+
204
+ export function requiresExplicitMatrixDefaultAccount(
205
+ cfg: AutoBotConfig,
206
+ env: NodeJS.ProcessEnv = process.env,
207
+ ): boolean {
208
+ const channel = resolveMatrixChannelConfig(cfg);
209
+ if (!channel) {
210
+ return false;
211
+ }
212
+ const configuredAccountIds = resolveConfiguredMatrixAccountIds(cfg, env);
213
+ if (configuredAccountIds.length <= 1) {
214
+ return false;
215
+ }
216
+ if (configuredAccountIds.includes(DEFAULT_ACCOUNT_ID)) {
217
+ return false;
218
+ }
219
+ const configuredDefault = normalizeOptionalAccountId(
220
+ typeof channel.defaultAccount === "string" ? channel.defaultAccount : undefined,
221
+ );
222
+ return !(configuredDefault && configuredAccountIds.includes(configuredDefault));
223
+ }