@gakr-gakr/matrix 0.1.0 → 0.1.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 (301) hide show
  1. package/autobot.plugin.json +891 -3
  2. package/dist/account-selection-D4xDzY_1.js +158 -0
  3. package/dist/active-client-BXz0W1fG.js +20 -0
  4. package/dist/api.js +12 -0
  5. package/dist/approval-handler.runtime-XgtgHryy.js +377 -0
  6. package/dist/approval-ids-Bj1MSuK0.js +7 -0
  7. package/dist/approval-reaction-auth-CP8yUUiI.js +27 -0
  8. package/dist/approval-reactions-C7FrzFhD.js +162 -0
  9. package/dist/async-lock-SsmtFXtt.js +19 -0
  10. package/dist/auth-presence.js +26 -0
  11. package/dist/backup-health-3BHbHxyd.js +60 -0
  12. package/dist/channel-CVtvS1kS.js +1380 -0
  13. package/dist/channel-plugin-api.js +2 -0
  14. package/dist/channel.runtime-BCl9atvS.js +250 -0
  15. package/dist/cli-D1Fxo6zb.js +1338 -0
  16. package/dist/cli-metadata-lo35g_nH.js +22 -0
  17. package/dist/cli-metadata.js +2 -0
  18. package/dist/client-4JU3adE6.js +30 -0
  19. package/dist/client-DVbkO1fr.js +25 -0
  20. package/dist/client-bootstrap-mLJmDCv8.js +114 -0
  21. package/dist/config-paths-BRIwec9o.js +114 -0
  22. package/dist/config-schema-ON2KZjSH.js +308 -0
  23. package/dist/config-secret-input.runtime-BcE98Tab.js +2 -0
  24. package/dist/contract-api.js +8 -0
  25. package/dist/create-client-nSnXsRe0.js +64 -0
  26. package/dist/credentials-CLaeORZB.js +56 -0
  27. package/dist/credentials-read-lnekFDSy.js +112 -0
  28. package/dist/credentials-write.runtime-AcuXkIly.js +17 -0
  29. package/dist/crypto-node.runtime-D9qxgRPa.js +12 -0
  30. package/dist/crypto-runtime-D577JLjP.js +1214 -0
  31. package/dist/deps-CcgU6fF9.js +208 -0
  32. package/dist/device-health-BDJoK0GP.js +16 -0
  33. package/dist/directory-live-D5osmyPM.js +150 -0
  34. package/dist/doctor-contract-CRTZe22J.js +246 -0
  35. package/dist/doctor-contract-api.js +2 -0
  36. package/dist/doctor-k53ce7TR.js +153 -0
  37. package/dist/draft-stream-B81ki3aq.js +143 -0
  38. package/dist/encryption-guidance-C4UZO9P_.js +15 -0
  39. package/dist/env-auth-ZPNhil6w.js +63 -0
  40. package/dist/env-vars-Ch51id3Y.js +63 -0
  41. package/dist/errors-D8exgH7Z.js +17 -0
  42. package/dist/exec-approval-resolver-NR6hHp1P.js +15 -0
  43. package/dist/helper-api.js +4 -0
  44. package/dist/http-client-CLvnNzJZ.js +331 -0
  45. package/dist/index.js +46 -0
  46. package/dist/legacy-crypto-inspector-BXa-K6Qb.js +41 -0
  47. package/dist/legacy-crypto-restore-DmSdbVyW.js +85 -0
  48. package/dist/logging-BWx5aV5G.js +99 -0
  49. package/dist/matrix-migration.runtime-C5EAzuSF.js +525 -0
  50. package/dist/media-text-H2gCWr7p.js +146 -0
  51. package/dist/messages-BM8v2OhM.js +140 -0
  52. package/dist/migration-snapshot-backup-B4qRjmn2.js +69 -0
  53. package/dist/migration-snapshot.runtime-CEaEL8JK.js +2 -0
  54. package/dist/monitor-9_MYVUk0.js +4331 -0
  55. package/dist/plugin-entry.handlers.runtime.js +51 -0
  56. package/dist/probe.runtime-ARO_q_Zl.js +3 -0
  57. package/dist/profile-update-DgBXphvR.js +68 -0
  58. package/dist/reaction-common-Bx8mZPc9.js +71 -0
  59. package/dist/reaction-events-B2GhGktu.js +121 -0
  60. package/{src/record-shared.ts → dist/record-shared-D-PbvaZ7.js} +1 -2
  61. package/dist/resolve-targets-CFr6_x9K.js +140 -0
  62. package/dist/resolver.runtime-fPzzTZVJ.js +5 -0
  63. package/dist/rolldown-runtime-DUslC3ob.js +14 -0
  64. package/dist/route-m49kMiHx.js +161 -0
  65. package/dist/runtime-BfjP-NST.js +8 -0
  66. package/dist/runtime-api-D7plmCoC.js +24 -0
  67. package/dist/runtime-api.js +25 -0
  68. package/dist/runtime-heavy-api.js +3 -0
  69. package/dist/runtime-lwTSy9Yt.js +6 -0
  70. package/dist/runtime-setter-api.js +2 -0
  71. package/dist/sdk-CK0ON6Js.js +1704 -0
  72. package/dist/secret-contract-BKkC-9fa.js +120 -0
  73. package/dist/secret-contract-api.js +2 -0
  74. package/dist/send-CWOxcUMq.js +1517 -0
  75. package/dist/setup-bootstrap-VShXhiBJ.js +62 -0
  76. package/dist/setup-core-CmXNGvQt.js +677 -0
  77. package/dist/setup-entry.js +19 -0
  78. package/dist/setup-plugin-api.js +43 -0
  79. package/dist/setup-surface-zTLHNBns.js +537 -0
  80. package/dist/shared-BrKJkpx_.js +642 -0
  81. package/dist/startup-abort-D79WSeUh.js +109 -0
  82. package/dist/startup-verification-Dj34oWgb.js +132 -0
  83. package/dist/storage-DxbroIe0.js +281 -0
  84. package/dist/storage-paths-BcLg30GH.js +52 -0
  85. package/dist/subagent-hooks-api-CjHBfEoY.js +170 -0
  86. package/dist/subagent-hooks-api.js +2 -0
  87. package/dist/sync-state-Bx0gPaGA.js +12 -0
  88. package/dist/target-ids-iZwjCUZa.js +77 -0
  89. package/dist/test-api.js +4 -0
  90. package/dist/thread-binding-api-BWT96Ttd.js +17 -0
  91. package/dist/thread-binding-api.js +2 -0
  92. package/dist/thread-bindings-owbheXoV.js +352 -0
  93. package/dist/thread-bindings-runtime.js +2 -0
  94. package/dist/thread-bindings-shared-4nkBBftw.js +97 -0
  95. package/dist/timeout-abort-signal-CPD0PPNy.js +2 -0
  96. package/dist/tool-actions.runtime-DDh2EP6z.js +532 -0
  97. package/dist/url-validation-fQvf_pW_.js +36 -0
  98. package/dist/verification-BhMWyuAf.js +345 -0
  99. package/package.json +16 -4
  100. package/CHANGELOG.md +0 -285
  101. package/SPEC-SUPPORT.md +0 -116
  102. package/api.ts +0 -38
  103. package/auth-presence.ts +0 -56
  104. package/channel-plugin-api.ts +0 -3
  105. package/cli-metadata.ts +0 -11
  106. package/contract-api.ts +0 -17
  107. package/doctor-contract-api.ts +0 -1
  108. package/helper-api.ts +0 -3
  109. package/index.ts +0 -55
  110. package/plugin-entry.handlers.runtime.ts +0 -1
  111. package/runtime-api.ts +0 -72
  112. package/runtime-heavy-api.ts +0 -1
  113. package/runtime-setter-api.ts +0 -3
  114. package/secret-contract-api.ts +0 -5
  115. package/setup-entry.ts +0 -17
  116. package/setup-plugin-api.ts +0 -3
  117. package/src/account-selection.ts +0 -223
  118. package/src/actions.ts +0 -346
  119. package/src/approval-auth.ts +0 -25
  120. package/src/approval-handler.runtime.ts +0 -595
  121. package/src/approval-ids.ts +0 -6
  122. package/src/approval-native.ts +0 -348
  123. package/src/approval-reaction-auth.ts +0 -45
  124. package/src/approval-reactions.ts +0 -313
  125. package/src/auth-precedence.ts +0 -61
  126. package/src/channel-account-paths.ts +0 -97
  127. package/src/channel.runtime.ts +0 -17
  128. package/src/channel.setup.ts +0 -48
  129. package/src/channel.ts +0 -667
  130. package/src/cli-metadata.ts +0 -19
  131. package/src/cli.ts +0 -2298
  132. package/src/config-adapter.ts +0 -41
  133. package/src/config-schema.ts +0 -159
  134. package/src/config-ui-hints.ts +0 -56
  135. package/src/directory-live.ts +0 -238
  136. package/src/doctor-contract.ts +0 -287
  137. package/src/doctor.ts +0 -262
  138. package/src/env-vars.ts +0 -92
  139. package/src/exec-approval-resolver.ts +0 -23
  140. package/src/exec-approvals.ts +0 -293
  141. package/src/group-mentions.ts +0 -41
  142. package/src/legacy-crypto-inspector-availability.ts +0 -60
  143. package/src/legacy-crypto.ts +0 -531
  144. package/src/legacy-state.ts +0 -156
  145. package/src/matrix/account-config.ts +0 -175
  146. package/src/matrix/accounts.ts +0 -194
  147. package/src/matrix/actions/client.ts +0 -31
  148. package/src/matrix/actions/devices.ts +0 -34
  149. package/src/matrix/actions/limits.ts +0 -6
  150. package/src/matrix/actions/messages.ts +0 -129
  151. package/src/matrix/actions/pins.ts +0 -63
  152. package/src/matrix/actions/polls.ts +0 -109
  153. package/src/matrix/actions/profile.ts +0 -37
  154. package/src/matrix/actions/reactions.ts +0 -59
  155. package/src/matrix/actions/room.ts +0 -71
  156. package/src/matrix/actions/summary.ts +0 -88
  157. package/src/matrix/actions/types.ts +0 -63
  158. package/src/matrix/actions/verification.ts +0 -589
  159. package/src/matrix/actions.ts +0 -37
  160. package/src/matrix/active-client.ts +0 -26
  161. package/src/matrix/async-lock.ts +0 -18
  162. package/src/matrix/backup-health.ts +0 -124
  163. package/src/matrix/client/config-runtime-api.ts +0 -9
  164. package/src/matrix/client/config-secret-input.runtime.ts +0 -1
  165. package/src/matrix/client/config.ts +0 -853
  166. package/src/matrix/client/create-client.ts +0 -105
  167. package/src/matrix/client/env-auth.ts +0 -95
  168. package/src/matrix/client/file-sync-store.ts +0 -289
  169. package/src/matrix/client/logging.ts +0 -140
  170. package/src/matrix/client/migration-snapshot.runtime.ts +0 -1
  171. package/src/matrix/client/private-network-host.ts +0 -1
  172. package/src/matrix/client/runtime.ts +0 -4
  173. package/src/matrix/client/shared.ts +0 -316
  174. package/src/matrix/client/storage.ts +0 -543
  175. package/src/matrix/client/types.ts +0 -50
  176. package/src/matrix/client/url-validation.ts +0 -76
  177. package/src/matrix/client-bootstrap.ts +0 -173
  178. package/src/matrix/client.ts +0 -23
  179. package/src/matrix/config-paths.ts +0 -31
  180. package/src/matrix/config-update.ts +0 -292
  181. package/src/matrix/credentials-read.ts +0 -207
  182. package/src/matrix/credentials-write.runtime.ts +0 -35
  183. package/src/matrix/credentials.ts +0 -95
  184. package/src/matrix/deps.ts +0 -309
  185. package/src/matrix/device-health.ts +0 -31
  186. package/src/matrix/direct-management.ts +0 -349
  187. package/src/matrix/direct-room.ts +0 -128
  188. package/src/matrix/draft-stream.ts +0 -225
  189. package/src/matrix/encryption-guidance.ts +0 -24
  190. package/src/matrix/errors.ts +0 -21
  191. package/src/matrix/format.ts +0 -426
  192. package/src/matrix/legacy-crypto-inspector.ts +0 -95
  193. package/src/matrix/media-errors.ts +0 -20
  194. package/src/matrix/media-text.ts +0 -162
  195. package/src/matrix/monitor/access-state.ts +0 -145
  196. package/src/matrix/monitor/ack-config.ts +0 -27
  197. package/src/matrix/monitor/allowlist.ts +0 -92
  198. package/src/matrix/monitor/auto-join.ts +0 -86
  199. package/src/matrix/monitor/config.ts +0 -569
  200. package/src/matrix/monitor/context-summary.ts +0 -43
  201. package/src/matrix/monitor/direct.ts +0 -296
  202. package/src/matrix/monitor/events.ts +0 -397
  203. package/src/matrix/monitor/handler.ts +0 -2271
  204. package/src/matrix/monitor/inbound-dedupe.ts +0 -267
  205. package/src/matrix/monitor/index.ts +0 -540
  206. package/src/matrix/monitor/legacy-crypto-restore.ts +0 -139
  207. package/src/matrix/monitor/location.ts +0 -108
  208. package/src/matrix/monitor/media.ts +0 -119
  209. package/src/matrix/monitor/mentions.ts +0 -256
  210. package/src/matrix/monitor/reaction-events.ts +0 -197
  211. package/src/matrix/monitor/recent-invite.ts +0 -30
  212. package/src/matrix/monitor/replies.ts +0 -136
  213. package/src/matrix/monitor/reply-context.ts +0 -92
  214. package/src/matrix/monitor/room-history.ts +0 -301
  215. package/src/matrix/monitor/room-info.ts +0 -126
  216. package/src/matrix/monitor/rooms.ts +0 -52
  217. package/src/matrix/monitor/route.ts +0 -179
  218. package/src/matrix/monitor/runtime-api.ts +0 -28
  219. package/src/matrix/monitor/startup-verification.ts +0 -237
  220. package/src/matrix/monitor/startup.ts +0 -218
  221. package/src/matrix/monitor/status.ts +0 -120
  222. package/src/matrix/monitor/sync-lifecycle.ts +0 -91
  223. package/src/matrix/monitor/task-runner.ts +0 -38
  224. package/src/matrix/monitor/test-events.ts +0 -21
  225. package/src/matrix/monitor/thread-context.ts +0 -108
  226. package/src/matrix/monitor/threads.ts +0 -85
  227. package/src/matrix/monitor/types.ts +0 -30
  228. package/src/matrix/monitor/verification-events.ts +0 -643
  229. package/src/matrix/monitor/verification-utils.ts +0 -46
  230. package/src/matrix/outbound-media-runtime.ts +0 -1
  231. package/src/matrix/poll-summary.ts +0 -110
  232. package/src/matrix/poll-types.ts +0 -429
  233. package/src/matrix/probe.runtime.ts +0 -4
  234. package/src/matrix/probe.ts +0 -97
  235. package/src/matrix/profile.ts +0 -184
  236. package/src/matrix/reaction-common.ts +0 -147
  237. package/src/matrix/sdk/crypto-bootstrap.ts +0 -438
  238. package/src/matrix/sdk/crypto-facade.ts +0 -242
  239. package/src/matrix/sdk/crypto-node.runtime.ts +0 -17
  240. package/src/matrix/sdk/crypto-runtime.ts +0 -14
  241. package/src/matrix/sdk/decrypt-bridge.ts +0 -410
  242. package/src/matrix/sdk/event-helpers.ts +0 -83
  243. package/src/matrix/sdk/http-client.ts +0 -87
  244. package/src/matrix/sdk/idb-persistence-lock.ts +0 -51
  245. package/src/matrix/sdk/idb-persistence.ts +0 -286
  246. package/src/matrix/sdk/logger.ts +0 -108
  247. package/src/matrix/sdk/read-response-with-limit.ts +0 -19
  248. package/src/matrix/sdk/recovery-key-store.ts +0 -453
  249. package/src/matrix/sdk/timeout-abort-signal.ts +0 -1
  250. package/src/matrix/sdk/transport-runtime-api.ts +0 -18
  251. package/src/matrix/sdk/transport.ts +0 -352
  252. package/src/matrix/sdk/types.ts +0 -245
  253. package/src/matrix/sdk/verification-manager.ts +0 -795
  254. package/src/matrix/sdk/verification-status.ts +0 -23
  255. package/src/matrix/sdk.ts +0 -2152
  256. package/src/matrix/send/client.ts +0 -93
  257. package/src/matrix/send/formatting.ts +0 -189
  258. package/src/matrix/send/media.ts +0 -244
  259. package/src/matrix/send/targets.ts +0 -104
  260. package/src/matrix/send/types.ts +0 -131
  261. package/src/matrix/send.ts +0 -660
  262. package/src/matrix/session-store-metadata.ts +0 -108
  263. package/src/matrix/startup-abort.ts +0 -44
  264. package/src/matrix/subagent-hooks.ts +0 -308
  265. package/src/matrix/sync-state.ts +0 -27
  266. package/src/matrix/target-ids.ts +0 -79
  267. package/src/matrix/thread-bindings-shared.ts +0 -206
  268. package/src/matrix/thread-bindings.ts +0 -580
  269. package/src/matrix-migration.runtime.ts +0 -9
  270. package/src/migration-config.ts +0 -243
  271. package/src/migration-snapshot-backup.ts +0 -116
  272. package/src/migration-snapshot.ts +0 -53
  273. package/src/onboarding.ts +0 -775
  274. package/src/outbound.ts +0 -248
  275. package/src/plugin-entry.runtime.js +0 -115
  276. package/src/plugin-entry.runtime.ts +0 -70
  277. package/src/profile-update.ts +0 -71
  278. package/src/resolve-targets.ts +0 -175
  279. package/src/resolver.runtime.ts +0 -5
  280. package/src/resolver.ts +0 -21
  281. package/src/runtime-api.ts +0 -106
  282. package/src/runtime.ts +0 -13
  283. package/src/secret-contract.ts +0 -174
  284. package/src/session-route.ts +0 -126
  285. package/src/setup-bootstrap.ts +0 -102
  286. package/src/setup-config.ts +0 -222
  287. package/src/setup-contract.ts +0 -90
  288. package/src/setup-core.ts +0 -146
  289. package/src/setup-dm-policy.ts +0 -15
  290. package/src/setup-surface.ts +0 -4
  291. package/src/startup-maintenance.ts +0 -114
  292. package/src/storage-paths.ts +0 -92
  293. package/src/thread-binding-api.ts +0 -23
  294. package/src/tool-actions.runtime.ts +0 -1
  295. package/src/tool-actions.ts +0 -498
  296. package/src/types.ts +0 -257
  297. package/subagent-hooks-api.ts +0 -31
  298. package/test-api.ts +0 -21
  299. package/thread-binding-api.ts +0 -4
  300. package/thread-bindings-runtime.ts +0 -4
  301. package/tsconfig.json +0 -16
@@ -1,531 +0,0 @@
1
- import fs from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
5
- import {
6
- loadJsonFile,
7
- writeJsonFileAtomically as writeJsonFileAtomicallyImpl,
8
- } from "autobot/plugin-sdk/json-store";
9
- import { resolveStateDir } from "autobot/plugin-sdk/state-paths";
10
- import { resolveConfiguredMatrixAccountIds } from "./account-selection.js";
11
- import { isMatrixLegacyCryptoInspectorAvailable } from "./legacy-crypto-inspector-availability.js";
12
- import { formatMatrixErrorMessage } from "./matrix/errors.js";
13
- import {
14
- resolveLegacyMatrixFlatStoreTarget,
15
- resolveMatrixMigrationAccountTarget,
16
- } from "./migration-config.js";
17
- import { resolveMatrixLegacyFlatStoragePaths } from "./storage-paths.js";
18
-
19
- const MATRIX_LEGACY_CRYPTO_INSPECTOR_UNAVAILABLE_MESSAGE =
20
- "Legacy Matrix encrypted state was detected, but the Matrix crypto inspector is unavailable.";
21
-
22
- type MatrixLegacyCryptoCounts = {
23
- total: number;
24
- backedUp: number;
25
- };
26
-
27
- type MatrixLegacyCryptoSummary = {
28
- deviceId: string | null;
29
- roomKeyCounts: MatrixLegacyCryptoCounts | null;
30
- backupVersion: string | null;
31
- decryptionKeyBase64: string | null;
32
- };
33
-
34
- type MatrixLegacyCryptoMigrationState = {
35
- version: 1;
36
- source: "matrix-bot-sdk-rust";
37
- accountId: string;
38
- deviceId: string | null;
39
- roomKeyCounts: MatrixLegacyCryptoCounts | null;
40
- backupVersion: string | null;
41
- decryptionKeyImported: boolean;
42
- restoreStatus: "pending" | "completed" | "manual-action-required";
43
- detectedAt: string;
44
- restoredAt?: string;
45
- importedCount?: number;
46
- totalCount?: number;
47
- lastError?: string | null;
48
- };
49
-
50
- type MatrixLegacyCryptoPlan = {
51
- accountId: string;
52
- rootDir: string;
53
- recoveryKeyPath: string;
54
- statePath: string;
55
- legacyCryptoPath: string;
56
- homeserver: string;
57
- userId: string;
58
- accessToken: string;
59
- deviceId: string | null;
60
- };
61
-
62
- type MatrixLegacyCryptoDetection = {
63
- inspectorAvailable: boolean;
64
- plans: MatrixLegacyCryptoPlan[];
65
- warnings: string[];
66
- };
67
-
68
- type MatrixLegacyCryptoPreparationResult = {
69
- migrated: boolean;
70
- changes: string[];
71
- warnings: string[];
72
- };
73
-
74
- type MatrixLegacyCryptoPrepareDeps = {
75
- inspectLegacyStore: MatrixLegacyCryptoInspector;
76
- writeJsonFileAtomically: typeof writeJsonFileAtomicallyImpl;
77
- };
78
-
79
- type MatrixLegacyCryptoInspectorParams = {
80
- cryptoRootDir: string;
81
- userId: string;
82
- deviceId: string;
83
- log?: (message: string) => void;
84
- };
85
-
86
- type MatrixLegacyCryptoInspectorResult = {
87
- deviceId: string | null;
88
- roomKeyCounts: {
89
- total: number;
90
- backedUp: number;
91
- } | null;
92
- backupVersion: string | null;
93
- decryptionKeyBase64: string | null;
94
- };
95
-
96
- type MatrixLegacyCryptoInspector = (
97
- params: MatrixLegacyCryptoInspectorParams,
98
- ) => Promise<MatrixLegacyCryptoInspectorResult>;
99
-
100
- type MatrixLegacyBotSdkMetadata = {
101
- deviceId: string | null;
102
- };
103
-
104
- type MatrixStoredRecoveryKey = {
105
- version: 1;
106
- createdAt: string;
107
- keyId?: string | null;
108
- encodedPrivateKey?: string;
109
- privateKeyBase64: string;
110
- keyInfo?: {
111
- passphrase?: unknown;
112
- name?: string;
113
- };
114
- };
115
-
116
- async function loadMatrixLegacyCryptoInspector(): Promise<MatrixLegacyCryptoInspector> {
117
- const module = await import("./matrix/legacy-crypto-inspector.js");
118
- return module.inspectLegacyMatrixCryptoStore as MatrixLegacyCryptoInspector;
119
- }
120
-
121
- function detectLegacyBotSdkCryptoStore(cryptoRootDir: string): {
122
- detected: boolean;
123
- warning?: string;
124
- } {
125
- try {
126
- const stat = fs.statSync(cryptoRootDir);
127
- if (!stat.isDirectory()) {
128
- return {
129
- detected: false,
130
- warning:
131
- `Legacy Matrix encrypted state path exists but is not a directory: ${cryptoRootDir}. ` +
132
- "AutoBot skipped automatic crypto migration for that path.",
133
- };
134
- }
135
- } catch (err) {
136
- return {
137
- detected: false,
138
- warning:
139
- `Failed reading legacy Matrix encrypted state path (${cryptoRootDir}): ${String(err)}. ` +
140
- "AutoBot skipped automatic crypto migration for that path.",
141
- };
142
- }
143
-
144
- try {
145
- return {
146
- detected:
147
- fs.existsSync(path.join(cryptoRootDir, "bot-sdk.json")) ||
148
- fs.existsSync(path.join(cryptoRootDir, "matrix-sdk-crypto.sqlite3")) ||
149
- fs
150
- .readdirSync(cryptoRootDir, { withFileTypes: true })
151
- .some(
152
- (entry) =>
153
- entry.isDirectory() &&
154
- fs.existsSync(path.join(cryptoRootDir, entry.name, "matrix-sdk-crypto.sqlite3")),
155
- ),
156
- };
157
- } catch (err) {
158
- return {
159
- detected: false,
160
- warning:
161
- `Failed scanning legacy Matrix encrypted state path (${cryptoRootDir}): ${String(err)}. ` +
162
- "AutoBot skipped automatic crypto migration for that path.",
163
- };
164
- }
165
- }
166
-
167
- function resolveMatrixAccountIds(cfg: AutoBotConfig): string[] {
168
- return resolveConfiguredMatrixAccountIds(cfg);
169
- }
170
-
171
- function resolveLegacyMatrixFlatStorePlan(params: {
172
- cfg: AutoBotConfig;
173
- env: NodeJS.ProcessEnv;
174
- }): MatrixLegacyCryptoPlan | { warning: string } | null {
175
- const legacy = resolveMatrixLegacyFlatStoragePaths(resolveStateDir(params.env, os.homedir));
176
- if (!fs.existsSync(legacy.cryptoPath)) {
177
- return null;
178
- }
179
- const legacyStore = detectLegacyBotSdkCryptoStore(legacy.cryptoPath);
180
- if (legacyStore.warning) {
181
- return { warning: legacyStore.warning };
182
- }
183
- if (!legacyStore.detected) {
184
- return null;
185
- }
186
-
187
- const target = resolveLegacyMatrixFlatStoreTarget({
188
- cfg: params.cfg,
189
- env: params.env,
190
- detectedPath: legacy.cryptoPath,
191
- detectedKind: "encrypted state",
192
- });
193
- if ("warning" in target) {
194
- return target;
195
- }
196
-
197
- const metadata = loadLegacyBotSdkMetadata(legacy.cryptoPath);
198
- return {
199
- accountId: target.accountId,
200
- rootDir: target.rootDir,
201
- recoveryKeyPath: path.join(target.rootDir, "recovery-key.json"),
202
- statePath: path.join(target.rootDir, "legacy-crypto-migration.json"),
203
- legacyCryptoPath: legacy.cryptoPath,
204
- homeserver: target.homeserver,
205
- userId: target.userId,
206
- accessToken: target.accessToken,
207
- deviceId: metadata.deviceId ?? target.storedDeviceId,
208
- };
209
- }
210
-
211
- function loadLegacyBotSdkMetadata(cryptoRootDir: string): MatrixLegacyBotSdkMetadata {
212
- const metadataPath = path.join(cryptoRootDir, "bot-sdk.json");
213
- const fallback: MatrixLegacyBotSdkMetadata = { deviceId: null };
214
- const parsed = loadJsonFile<{ deviceId?: unknown }>(metadataPath);
215
- return {
216
- deviceId:
217
- typeof parsed?.deviceId === "string" && parsed.deviceId.trim()
218
- ? parsed.deviceId
219
- : fallback.deviceId,
220
- };
221
- }
222
-
223
- function resolveMatrixLegacyCryptoPlans(params: {
224
- cfg: AutoBotConfig;
225
- env: NodeJS.ProcessEnv;
226
- }): Omit<MatrixLegacyCryptoDetection, "inspectorAvailable"> {
227
- const warnings: string[] = [];
228
- const plans: MatrixLegacyCryptoPlan[] = [];
229
-
230
- const flatPlan = resolveLegacyMatrixFlatStorePlan(params);
231
- if (flatPlan) {
232
- if ("warning" in flatPlan) {
233
- warnings.push(flatPlan.warning);
234
- } else {
235
- plans.push(flatPlan);
236
- }
237
- }
238
-
239
- for (const accountId of resolveMatrixAccountIds(params.cfg)) {
240
- const target = resolveMatrixMigrationAccountTarget({
241
- cfg: params.cfg,
242
- env: params.env,
243
- accountId,
244
- });
245
- if (!target) {
246
- continue;
247
- }
248
- const legacyCryptoPath = path.join(target.rootDir, "crypto");
249
- if (!fs.existsSync(legacyCryptoPath)) {
250
- continue;
251
- }
252
- const detectedStore = detectLegacyBotSdkCryptoStore(legacyCryptoPath);
253
- if (detectedStore.warning) {
254
- warnings.push(detectedStore.warning);
255
- continue;
256
- }
257
- if (!detectedStore.detected) {
258
- continue;
259
- }
260
- if (
261
- plans.some(
262
- (plan) =>
263
- plan.accountId === accountId &&
264
- path.resolve(plan.legacyCryptoPath) === path.resolve(legacyCryptoPath),
265
- )
266
- ) {
267
- continue;
268
- }
269
- const metadata = loadLegacyBotSdkMetadata(legacyCryptoPath);
270
- plans.push({
271
- accountId: target.accountId,
272
- rootDir: target.rootDir,
273
- recoveryKeyPath: path.join(target.rootDir, "recovery-key.json"),
274
- statePath: path.join(target.rootDir, "legacy-crypto-migration.json"),
275
- legacyCryptoPath,
276
- homeserver: target.homeserver,
277
- userId: target.userId,
278
- accessToken: target.accessToken,
279
- deviceId: metadata.deviceId ?? target.storedDeviceId,
280
- });
281
- }
282
-
283
- return { plans, warnings };
284
- }
285
-
286
- function loadStoredRecoveryKey(filePath: string): MatrixStoredRecoveryKey | null {
287
- return loadJsonFile<MatrixStoredRecoveryKey>(filePath) ?? null;
288
- }
289
-
290
- function loadLegacyCryptoMigrationState(filePath: string): MatrixLegacyCryptoMigrationState | null {
291
- return loadJsonFile<MatrixLegacyCryptoMigrationState>(filePath) ?? null;
292
- }
293
-
294
- async function persistLegacyMigrationState(params: {
295
- filePath: string;
296
- state: MatrixLegacyCryptoMigrationState;
297
- writeJsonFileAtomically: typeof writeJsonFileAtomicallyImpl;
298
- }): Promise<void> {
299
- await params.writeJsonFileAtomically(params.filePath, params.state);
300
- }
301
-
302
- export function detectLegacyMatrixCrypto(params: {
303
- cfg: AutoBotConfig;
304
- env?: NodeJS.ProcessEnv;
305
- }): MatrixLegacyCryptoDetection {
306
- const detection = resolveMatrixLegacyCryptoPlans({
307
- cfg: params.cfg,
308
- env: params.env ?? process.env,
309
- });
310
- const inspectorAvailable =
311
- detection.plans.length === 0 || isMatrixLegacyCryptoInspectorAvailable();
312
- if (!inspectorAvailable && detection.plans.length > 0) {
313
- return {
314
- inspectorAvailable,
315
- plans: detection.plans,
316
- warnings: [...detection.warnings, MATRIX_LEGACY_CRYPTO_INSPECTOR_UNAVAILABLE_MESSAGE],
317
- };
318
- }
319
- return {
320
- inspectorAvailable,
321
- plans: detection.plans,
322
- warnings: detection.warnings,
323
- };
324
- }
325
-
326
- export async function autoPrepareLegacyMatrixCrypto(params: {
327
- cfg: AutoBotConfig;
328
- env?: NodeJS.ProcessEnv;
329
- log?: { info?: (message: string) => void; warn?: (message: string) => void };
330
- deps?: Partial<MatrixLegacyCryptoPrepareDeps>;
331
- }): Promise<MatrixLegacyCryptoPreparationResult> {
332
- const env = params.env ?? process.env;
333
- const detection = params.deps?.inspectLegacyStore
334
- ? resolveMatrixLegacyCryptoPlans({ cfg: params.cfg, env })
335
- : detectLegacyMatrixCrypto({ cfg: params.cfg, env });
336
- const inspectorAvailable =
337
- "inspectorAvailable" in detection ? detection.inspectorAvailable : true;
338
- const warnings = [...detection.warnings];
339
- const changes: string[] = [];
340
- const writeJsonFileAtomically =
341
- params.deps?.writeJsonFileAtomically ?? writeJsonFileAtomicallyImpl;
342
- if (detection.plans.length === 0) {
343
- if (warnings.length > 0) {
344
- params.log?.warn?.(
345
- `matrix: legacy encrypted-state warnings:\n${warnings.map((entry) => `- ${entry}`).join("\n")}`,
346
- );
347
- }
348
- return {
349
- migrated: false,
350
- changes,
351
- warnings,
352
- };
353
- }
354
- if (!params.deps?.inspectLegacyStore && !inspectorAvailable) {
355
- if (warnings.length > 0) {
356
- params.log?.warn?.(
357
- `matrix: legacy encrypted-state warnings:\n${warnings.map((entry) => `- ${entry}`).join("\n")}`,
358
- );
359
- }
360
- return {
361
- migrated: false,
362
- changes,
363
- warnings,
364
- };
365
- }
366
-
367
- let inspectLegacyStore = params.deps?.inspectLegacyStore;
368
- if (!inspectLegacyStore) {
369
- try {
370
- inspectLegacyStore = await loadMatrixLegacyCryptoInspector();
371
- } catch (err) {
372
- const message = formatMatrixErrorMessage(err);
373
- if (!warnings.includes(message)) {
374
- warnings.push(message);
375
- }
376
- if (warnings.length > 0) {
377
- params.log?.warn?.(
378
- `matrix: legacy encrypted-state warnings:\n${warnings.map((entry) => `- ${entry}`).join("\n")}`,
379
- );
380
- }
381
- return {
382
- migrated: false,
383
- changes,
384
- warnings,
385
- };
386
- }
387
- }
388
- if (!inspectLegacyStore) {
389
- return {
390
- migrated: false,
391
- changes,
392
- warnings,
393
- };
394
- }
395
-
396
- for (const plan of detection.plans) {
397
- const existingState = loadLegacyCryptoMigrationState(plan.statePath);
398
- if (existingState?.version === 1) {
399
- continue;
400
- }
401
- if (!plan.deviceId) {
402
- warnings.push(
403
- `Legacy Matrix encrypted state detected at ${plan.legacyCryptoPath}, but no device ID was found for account "${plan.accountId}". ` +
404
- `AutoBot will continue, but old encrypted history cannot be recovered automatically.`,
405
- );
406
- continue;
407
- }
408
-
409
- let summary: MatrixLegacyCryptoSummary;
410
- try {
411
- summary = await inspectLegacyStore({
412
- cryptoRootDir: plan.legacyCryptoPath,
413
- userId: plan.userId,
414
- deviceId: plan.deviceId,
415
- log: params.log?.info,
416
- });
417
- } catch (err) {
418
- warnings.push(
419
- `Failed inspecting legacy Matrix encrypted state for account "${plan.accountId}" (${plan.legacyCryptoPath}): ${String(err)}`,
420
- );
421
- continue;
422
- }
423
-
424
- let decryptionKeyImported = false;
425
- if (summary.decryptionKeyBase64) {
426
- const existingRecoveryKey = loadStoredRecoveryKey(plan.recoveryKeyPath);
427
- if (
428
- existingRecoveryKey?.privateKeyBase64 &&
429
- existingRecoveryKey.privateKeyBase64 !== summary.decryptionKeyBase64
430
- ) {
431
- warnings.push(
432
- `Legacy Matrix backup key was found for account "${plan.accountId}", but ${plan.recoveryKeyPath} already contains a different recovery key. Leaving the existing file unchanged.`,
433
- );
434
- } else if (!existingRecoveryKey?.privateKeyBase64) {
435
- const payload: MatrixStoredRecoveryKey = {
436
- version: 1,
437
- createdAt: new Date().toISOString(),
438
- keyId: null,
439
- privateKeyBase64: summary.decryptionKeyBase64,
440
- };
441
- try {
442
- await writeJsonFileAtomically(plan.recoveryKeyPath, payload);
443
- changes.push(
444
- `Imported Matrix legacy backup key for account "${plan.accountId}": ${plan.recoveryKeyPath}`,
445
- );
446
- decryptionKeyImported = true;
447
- } catch (err) {
448
- warnings.push(
449
- `Failed writing Matrix recovery key for account "${plan.accountId}" (${plan.recoveryKeyPath}): ${String(err)}`,
450
- );
451
- }
452
- } else {
453
- decryptionKeyImported = true;
454
- }
455
- }
456
-
457
- const localOnlyKeys =
458
- summary.roomKeyCounts && summary.roomKeyCounts.total > summary.roomKeyCounts.backedUp
459
- ? summary.roomKeyCounts.total - summary.roomKeyCounts.backedUp
460
- : 0;
461
- if (localOnlyKeys > 0) {
462
- warnings.push(
463
- `Legacy Matrix encrypted state for account "${plan.accountId}" contains ${localOnlyKeys} room key(s) that were never backed up. ` +
464
- "Backed-up keys can be restored automatically, but local-only encrypted history may remain unavailable after upgrade.",
465
- );
466
- }
467
- if (!summary.decryptionKeyBase64 && (summary.roomKeyCounts?.backedUp ?? 0) > 0) {
468
- warnings.push(
469
- `Legacy Matrix encrypted state for account "${plan.accountId}" has backed-up room keys, but no local backup decryption key was found. ` +
470
- `Ask the operator to run "autobot matrix verify backup restore --recovery-key <key>" after upgrade if they have the recovery key.`,
471
- );
472
- }
473
- if (!summary.decryptionKeyBase64 && (summary.roomKeyCounts?.total ?? 0) > 0) {
474
- warnings.push(
475
- `Legacy Matrix encrypted state for account "${plan.accountId}" cannot be fully converted automatically because the old rust crypto store does not expose all local room keys for export.`,
476
- );
477
- }
478
- // If recovery-key persistence failed, leave the migration state absent so the next startup can retry.
479
- if (
480
- summary.decryptionKeyBase64 &&
481
- !decryptionKeyImported &&
482
- !loadStoredRecoveryKey(plan.recoveryKeyPath)
483
- ) {
484
- continue;
485
- }
486
-
487
- const state: MatrixLegacyCryptoMigrationState = {
488
- version: 1,
489
- source: "matrix-bot-sdk-rust",
490
- accountId: plan.accountId,
491
- deviceId: summary.deviceId,
492
- roomKeyCounts: summary.roomKeyCounts,
493
- backupVersion: summary.backupVersion,
494
- decryptionKeyImported,
495
- restoreStatus: decryptionKeyImported ? "pending" : "manual-action-required",
496
- detectedAt: new Date().toISOString(),
497
- lastError: null,
498
- };
499
- try {
500
- await persistLegacyMigrationState({
501
- filePath: plan.statePath,
502
- state,
503
- writeJsonFileAtomically,
504
- });
505
- changes.push(
506
- `Prepared Matrix legacy encrypted-state migration for account "${plan.accountId}": ${plan.statePath}`,
507
- );
508
- } catch (err) {
509
- warnings.push(
510
- `Failed writing Matrix legacy encrypted-state migration record for account "${plan.accountId}" (${plan.statePath}): ${String(err)}`,
511
- );
512
- }
513
- }
514
-
515
- if (changes.length > 0) {
516
- params.log?.info?.(
517
- `matrix: prepared encrypted-state upgrade.\n${changes.map((entry) => `- ${entry}`).join("\n")}`,
518
- );
519
- }
520
- if (warnings.length > 0) {
521
- params.log?.warn?.(
522
- `matrix: legacy encrypted-state warnings:\n${warnings.map((entry) => `- ${entry}`).join("\n")}`,
523
- );
524
- }
525
-
526
- return {
527
- migrated: changes.length > 0,
528
- changes,
529
- warnings,
530
- };
531
- }
@@ -1,156 +0,0 @@
1
- import fs from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- import type { AutoBotConfig } from "autobot/plugin-sdk/config-contracts";
5
- import { resolveStateDir } from "autobot/plugin-sdk/state-paths";
6
- import { resolveLegacyMatrixFlatStoreTarget } from "./migration-config.js";
7
- import { resolveMatrixLegacyFlatStoragePaths } from "./storage-paths.js";
8
-
9
- type MatrixLegacyStateMigrationResult = {
10
- migrated: boolean;
11
- changes: string[];
12
- warnings: string[];
13
- };
14
-
15
- type MatrixLegacyStatePlan = {
16
- accountId: string;
17
- legacyStoragePath: string;
18
- legacyCryptoPath: string;
19
- targetRootDir: string;
20
- targetStoragePath: string;
21
- targetCryptoPath: string;
22
- selectionNote?: string;
23
- };
24
-
25
- function resolveLegacyMatrixPaths(env: NodeJS.ProcessEnv): {
26
- rootDir: string;
27
- storagePath: string;
28
- cryptoPath: string;
29
- } {
30
- const stateDir = resolveStateDir(env, os.homedir);
31
- return resolveMatrixLegacyFlatStoragePaths(stateDir);
32
- }
33
-
34
- function resolveMatrixMigrationPlan(params: {
35
- cfg: AutoBotConfig;
36
- env: NodeJS.ProcessEnv;
37
- }): MatrixLegacyStatePlan | { warning: string } | null {
38
- const legacy = resolveLegacyMatrixPaths(params.env);
39
- if (!fs.existsSync(legacy.storagePath) && !fs.existsSync(legacy.cryptoPath)) {
40
- return null;
41
- }
42
-
43
- const target = resolveLegacyMatrixFlatStoreTarget({
44
- cfg: params.cfg,
45
- env: params.env,
46
- detectedPath: legacy.rootDir,
47
- detectedKind: "state",
48
- });
49
- if ("warning" in target) {
50
- return target;
51
- }
52
-
53
- return {
54
- accountId: target.accountId,
55
- legacyStoragePath: legacy.storagePath,
56
- legacyCryptoPath: legacy.cryptoPath,
57
- targetRootDir: target.rootDir,
58
- targetStoragePath: path.join(target.rootDir, "bot-storage.json"),
59
- targetCryptoPath: path.join(target.rootDir, "crypto"),
60
- selectionNote: target.selectionNote,
61
- };
62
- }
63
-
64
- export function detectLegacyMatrixState(params: {
65
- cfg: AutoBotConfig;
66
- env?: NodeJS.ProcessEnv;
67
- }): MatrixLegacyStatePlan | { warning: string } | null {
68
- return resolveMatrixMigrationPlan({
69
- cfg: params.cfg,
70
- env: params.env ?? process.env,
71
- });
72
- }
73
-
74
- function moveLegacyPath(params: {
75
- sourcePath: string;
76
- targetPath: string;
77
- label: string;
78
- changes: string[];
79
- warnings: string[];
80
- }): void {
81
- if (!fs.existsSync(params.sourcePath)) {
82
- return;
83
- }
84
- if (fs.existsSync(params.targetPath)) {
85
- params.warnings.push(
86
- `Matrix legacy ${params.label} not migrated because the target already exists (${params.targetPath}).`,
87
- );
88
- return;
89
- }
90
- try {
91
- fs.mkdirSync(path.dirname(params.targetPath), { recursive: true });
92
- fs.renameSync(params.sourcePath, params.targetPath);
93
- params.changes.push(
94
- `Migrated Matrix legacy ${params.label}: ${params.sourcePath} -> ${params.targetPath}`,
95
- );
96
- } catch (err) {
97
- params.warnings.push(
98
- `Failed migrating Matrix legacy ${params.label} (${params.sourcePath} -> ${params.targetPath}): ${String(err)}`,
99
- );
100
- }
101
- }
102
-
103
- export async function autoMigrateLegacyMatrixState(params: {
104
- cfg: AutoBotConfig;
105
- env?: NodeJS.ProcessEnv;
106
- log?: { info?: (message: string) => void; warn?: (message: string) => void };
107
- }): Promise<MatrixLegacyStateMigrationResult> {
108
- const env = params.env ?? process.env;
109
- const detection = detectLegacyMatrixState({ cfg: params.cfg, env });
110
- if (!detection) {
111
- return { migrated: false, changes: [], warnings: [] };
112
- }
113
- if ("warning" in detection) {
114
- params.log?.warn?.(`matrix: ${detection.warning}`);
115
- return { migrated: false, changes: [], warnings: [detection.warning] };
116
- }
117
-
118
- const changes: string[] = [];
119
- const warnings: string[] = [];
120
- moveLegacyPath({
121
- sourcePath: detection.legacyStoragePath,
122
- targetPath: detection.targetStoragePath,
123
- label: "sync store",
124
- changes,
125
- warnings,
126
- });
127
- moveLegacyPath({
128
- sourcePath: detection.legacyCryptoPath,
129
- targetPath: detection.targetCryptoPath,
130
- label: "crypto store",
131
- changes,
132
- warnings,
133
- });
134
-
135
- if (changes.length > 0) {
136
- const details = [
137
- ...changes.map((entry) => `- ${entry}`),
138
- ...(detection.selectionNote ? [`- ${detection.selectionNote}`] : []),
139
- "- No user action required.",
140
- ];
141
- params.log?.info?.(
142
- `matrix: plugin upgraded in place for account "${detection.accountId}".\n${details.join("\n")}`,
143
- );
144
- }
145
- if (warnings.length > 0) {
146
- params.log?.warn?.(
147
- `matrix: legacy state migration warnings:\n${warnings.map((entry) => `- ${entry}`).join("\n")}`,
148
- );
149
- }
150
-
151
- return {
152
- migrated: changes.length > 0,
153
- changes,
154
- warnings,
155
- };
156
- }