@openclaw/matrix 2026.3.13 → 2026.5.10-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/dist/account-config-D2W-V1eQ.js +96 -0
  2. package/dist/account-selection-BWwIruri.js +158 -0
  3. package/dist/accounts-Bm90Rzvp.js +130 -0
  4. package/dist/active-client-uhlxdhEy.js +20 -0
  5. package/dist/allowlist-sTzpCn5d.js +68 -0
  6. package/dist/api.js +12 -0
  7. package/dist/approval-handler.runtime-DWTQfd4m.js +370 -0
  8. package/dist/approval-ids-DoC2z7tR.js +7 -0
  9. package/dist/approval-reaction-auth-DbcA1gGd.js +27 -0
  10. package/dist/approval-reactions-o2_tuH8D.js +162 -0
  11. package/dist/async-lock-uQfhfQIY.js +19 -0
  12. package/dist/auth-presence.js +26 -0
  13. package/dist/backup-health-Cabu_WQC.js +60 -0
  14. package/dist/channel-H_6lMgwf.js +1116 -0
  15. package/dist/channel-plugin-api.js +2 -0
  16. package/dist/channel.runtime-BnO9f0pR.js +246 -0
  17. package/dist/cli-CYZ9yVcB.js +1340 -0
  18. package/dist/cli-metadata-DPIHnoa6.js +22 -0
  19. package/dist/cli-metadata.js +2 -0
  20. package/dist/client-DkcXnm0X.js +25 -0
  21. package/dist/client-_hckQNGW.js +31 -0
  22. package/dist/client-bootstrap-Rb8oHvhH.js +114 -0
  23. package/dist/config--5-S2Akv.js +452 -0
  24. package/dist/config-paths-nsVaysCu.js +19 -0
  25. package/dist/config-schema-nPLpEgHl.js +200 -0
  26. package/dist/config-secret-input.runtime-DiKFehsE.js +2 -0
  27. package/dist/config-update-wZX-HLMn.js +143 -0
  28. package/dist/contract-api.js +9 -0
  29. package/dist/create-client-DCnqDaqd.js +64 -0
  30. package/dist/credentials-DV6fWXhC.js +56 -0
  31. package/dist/credentials-read-cmHgousK.js +112 -0
  32. package/dist/credentials-write.runtime-zniTq-Gr.js +17 -0
  33. package/dist/crypto-node.runtime-pihzdpY7.js +12 -0
  34. package/dist/crypto-runtime-ZI0zAtn3.js +1214 -0
  35. package/dist/deps-C6WqKY7m.js +235 -0
  36. package/dist/device-health-UVYpbA_W.js +16 -0
  37. package/dist/direct-management-DMMMgtTB.js +249 -0
  38. package/dist/direct-room-XkutHjES.js +76 -0
  39. package/dist/directory-live-DmOtMhyr.js +150 -0
  40. package/dist/doctor-C4__7c-U.js +153 -0
  41. package/dist/doctor-contract-D4-64QuJ.js +246 -0
  42. package/dist/doctor-contract-api.js +2 -0
  43. package/dist/draft-stream-BE2QevQQ.js +144 -0
  44. package/dist/encryption-guidance-BPi3A_m3.js +15 -0
  45. package/dist/env-auth-BJqGI8M6.js +63 -0
  46. package/dist/env-vars-C7uQCTKn.js +63 -0
  47. package/dist/errors-CTcpEDq-.js +17 -0
  48. package/dist/exec-approval-resolver-Bza9Dhlm.js +15 -0
  49. package/dist/exec-approvals-Crnh543m.js +196 -0
  50. package/dist/helper-api.js +4 -0
  51. package/dist/http-client-C7AeVJay.js +319 -0
  52. package/dist/index.js +46 -0
  53. package/dist/legacy-crypto-inspector-poDWldgy.js +41 -0
  54. package/dist/legacy-crypto-restore-Biw-w2ng.js +85 -0
  55. package/dist/logger-CnZRVrux.js +78 -0
  56. package/dist/logging-DZHSPP5N.js +99 -0
  57. package/dist/matrix-migration.runtime-WY6ffcrf.js +525 -0
  58. package/dist/media-text-DU6nWZuj.js +146 -0
  59. package/dist/messages-BpihMh82.js +140 -0
  60. package/dist/migration-snapshot-backup-DaCHTp8C.js +69 -0
  61. package/dist/migration-snapshot.runtime-CKHE3xF9.js +2 -0
  62. package/dist/monitor-BaRCKyLd.js +4175 -0
  63. package/dist/plugin-entry.handlers.runtime.js +51 -0
  64. package/dist/probe.runtime-BvAzYAIe.js +3 -0
  65. package/dist/profile-BlHu0wDX.js +111 -0
  66. package/dist/profile-update-DjeBNgIV.js +69 -0
  67. package/dist/reaction-common-ejrL19w-.js +71 -0
  68. package/dist/reaction-events-CiARZfjk.js +121 -0
  69. package/dist/record-shared-CHWJCTWf.js +2 -0
  70. package/dist/recovery-key-store-BTJ6jz5v.js +294 -0
  71. package/dist/resolve-targets-YtJnw1Tb.js +140 -0
  72. package/dist/resolver.runtime-D9piiGEl.js +5 -0
  73. package/dist/rolldown-runtime-DUslC3ob.js +14 -0
  74. package/dist/route-D6rg-iXN.js +161 -0
  75. package/dist/runtime-C6X4h_SJ.js +6 -0
  76. package/dist/runtime-Dog86njy.js +8 -0
  77. package/dist/runtime-api-DTKcXOhp.js +24 -0
  78. package/dist/runtime-api.js +25 -0
  79. package/dist/runtime-heavy-api.js +3 -0
  80. package/dist/runtime-setter-api.js +2 -0
  81. package/dist/sdk-B2vZA27-.js +1416 -0
  82. package/dist/secret-contract-DcrJWCQI.js +120 -0
  83. package/dist/secret-contract-api.js +2 -0
  84. package/dist/send-Bo0DU1ca.js +1200 -0
  85. package/dist/session-store-metadata-DQXjgNLt.js +77 -0
  86. package/dist/setup-bootstrap-ImenBsMt.js +62 -0
  87. package/dist/setup-core-CfZy05oW.js +116 -0
  88. package/dist/setup-dm-policy-2-r1FrQh.js +194 -0
  89. package/dist/setup-entry.js +19 -0
  90. package/dist/setup-plugin-api.js +44 -0
  91. package/dist/setup-surface-CqT_o61M.js +540 -0
  92. package/dist/shared-CpMoYKm1.js +195 -0
  93. package/dist/startup-abort-56edvmbM.js +32 -0
  94. package/dist/startup-verification-Demyp0bP.js +132 -0
  95. package/dist/storage-paths-BJLdnCjV.js +52 -0
  96. package/dist/storage-tC3ujLiW.js +281 -0
  97. package/dist/subagent-hooks-DQbyqq9V.js +149 -0
  98. package/dist/subagent-hooks-api.js +23 -0
  99. package/dist/sync-state-C_beeevA.js +12 -0
  100. package/dist/target-ids-80nQ2gql.js +77 -0
  101. package/dist/test-api.js +4 -0
  102. package/dist/thread-binding-api-Cq_E-E1K.js +17 -0
  103. package/dist/thread-binding-api.js +2 -0
  104. package/dist/thread-bindings-B9mesxXk.js +352 -0
  105. package/dist/thread-bindings-runtime.js +2 -0
  106. package/dist/thread-bindings-shared-DK-d-oYX.js +97 -0
  107. package/dist/timeout-abort-signal-CtaIaP1v.js +2 -0
  108. package/dist/tool-actions.runtime-ThYhfHtZ.js +532 -0
  109. package/dist/url-validation-DiK9j7jz.js +36 -0
  110. package/dist/verification-CZ2rDeHL.js +345 -0
  111. package/openclaw.plugin.json +796 -1
  112. package/package.json +82 -16
  113. package/CHANGELOG.md +0 -104
  114. package/index.ts +0 -22
  115. package/src/actions.ts +0 -195
  116. package/src/channel.directory.test.ts +0 -135
  117. package/src/channel.ts +0 -461
  118. package/src/config-schema.test.ts +0 -26
  119. package/src/config-schema.ts +0 -62
  120. package/src/directory-live.test.ts +0 -85
  121. package/src/directory-live.ts +0 -209
  122. package/src/group-mentions.ts +0 -52
  123. package/src/matrix/accounts.test.ts +0 -131
  124. package/src/matrix/accounts.ts +0 -114
  125. package/src/matrix/actions/client.ts +0 -47
  126. package/src/matrix/actions/limits.test.ts +0 -15
  127. package/src/matrix/actions/limits.ts +0 -6
  128. package/src/matrix/actions/messages.ts +0 -126
  129. package/src/matrix/actions/pins.test.ts +0 -74
  130. package/src/matrix/actions/pins.ts +0 -84
  131. package/src/matrix/actions/reactions.test.ts +0 -109
  132. package/src/matrix/actions/reactions.ts +0 -102
  133. package/src/matrix/actions/room.ts +0 -85
  134. package/src/matrix/actions/summary.ts +0 -75
  135. package/src/matrix/actions/types.ts +0 -85
  136. package/src/matrix/actions.ts +0 -15
  137. package/src/matrix/active-client.ts +0 -32
  138. package/src/matrix/client/config.ts +0 -245
  139. package/src/matrix/client/create-client.ts +0 -125
  140. package/src/matrix/client/logging.ts +0 -46
  141. package/src/matrix/client/runtime.ts +0 -4
  142. package/src/matrix/client/shared.test.ts +0 -85
  143. package/src/matrix/client/shared.ts +0 -210
  144. package/src/matrix/client/startup.test.ts +0 -49
  145. package/src/matrix/client/startup.ts +0 -29
  146. package/src/matrix/client/storage.ts +0 -131
  147. package/src/matrix/client/types.ts +0 -34
  148. package/src/matrix/client-bootstrap.ts +0 -47
  149. package/src/matrix/client.test.ts +0 -56
  150. package/src/matrix/client.ts +0 -14
  151. package/src/matrix/credentials.ts +0 -125
  152. package/src/matrix/deps.test.ts +0 -74
  153. package/src/matrix/deps.ts +0 -126
  154. package/src/matrix/format.test.ts +0 -33
  155. package/src/matrix/format.ts +0 -22
  156. package/src/matrix/index.ts +0 -11
  157. package/src/matrix/monitor/access-policy.ts +0 -126
  158. package/src/matrix/monitor/allowlist.test.ts +0 -45
  159. package/src/matrix/monitor/allowlist.ts +0 -94
  160. package/src/matrix/monitor/auto-join.ts +0 -72
  161. package/src/matrix/monitor/direct.test.ts +0 -396
  162. package/src/matrix/monitor/direct.ts +0 -152
  163. package/src/matrix/monitor/events.test.ts +0 -186
  164. package/src/matrix/monitor/events.ts +0 -168
  165. package/src/matrix/monitor/handler.body-for-agent.test.ts +0 -196
  166. package/src/matrix/monitor/handler.ts +0 -768
  167. package/src/matrix/monitor/inbound-body.test.ts +0 -73
  168. package/src/matrix/monitor/inbound-body.ts +0 -28
  169. package/src/matrix/monitor/index.test.ts +0 -18
  170. package/src/matrix/monitor/index.ts +0 -414
  171. package/src/matrix/monitor/location.ts +0 -100
  172. package/src/matrix/monitor/media.test.ts +0 -86
  173. package/src/matrix/monitor/media.ts +0 -118
  174. package/src/matrix/monitor/mentions.test.ts +0 -154
  175. package/src/matrix/monitor/mentions.ts +0 -62
  176. package/src/matrix/monitor/replies.test.ts +0 -184
  177. package/src/matrix/monitor/replies.ts +0 -124
  178. package/src/matrix/monitor/room-info.ts +0 -55
  179. package/src/matrix/monitor/rooms.test.ts +0 -124
  180. package/src/matrix/monitor/rooms.ts +0 -47
  181. package/src/matrix/monitor/threads.ts +0 -68
  182. package/src/matrix/monitor/types.ts +0 -39
  183. package/src/matrix/poll-types.test.ts +0 -21
  184. package/src/matrix/poll-types.ts +0 -167
  185. package/src/matrix/probe.ts +0 -69
  186. package/src/matrix/sdk-runtime.ts +0 -18
  187. package/src/matrix/send/client.ts +0 -99
  188. package/src/matrix/send/formatting.ts +0 -93
  189. package/src/matrix/send/media.ts +0 -230
  190. package/src/matrix/send/targets.test.ts +0 -98
  191. package/src/matrix/send/targets.ts +0 -150
  192. package/src/matrix/send/types.ts +0 -110
  193. package/src/matrix/send-queue.test.ts +0 -145
  194. package/src/matrix/send-queue.ts +0 -28
  195. package/src/matrix/send.test.ts +0 -319
  196. package/src/matrix/send.ts +0 -267
  197. package/src/onboarding.ts +0 -462
  198. package/src/outbound.test.ts +0 -159
  199. package/src/outbound.ts +0 -58
  200. package/src/resolve-targets.test.ts +0 -68
  201. package/src/resolve-targets.ts +0 -125
  202. package/src/runtime.ts +0 -6
  203. package/src/secret-input.ts +0 -13
  204. package/src/test-mocks.ts +0 -53
  205. package/src/tool-actions.ts +0 -164
  206. package/src/types.ts +0 -118
@@ -1,74 +0,0 @@
1
- import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
- import { describe, expect, it, vi } from "vitest";
3
- import { listMatrixPins, pinMatrixMessage, unpinMatrixMessage } from "./pins.js";
4
-
5
- function createPinsClient(seedPinned: string[], knownBodies: Record<string, string> = {}) {
6
- let pinned = [...seedPinned];
7
- const getRoomStateEvent = vi.fn(async () => ({ pinned: [...pinned] }));
8
- const sendStateEvent = vi.fn(
9
- async (_roomId: string, _type: string, _key: string, payload: any) => {
10
- pinned = [...payload.pinned];
11
- },
12
- );
13
- const getEvent = vi.fn(async (_roomId: string, eventId: string) => {
14
- const body = knownBodies[eventId];
15
- if (!body) {
16
- throw new Error("missing");
17
- }
18
- return {
19
- event_id: eventId,
20
- sender: "@alice:example.org",
21
- type: "m.room.message",
22
- origin_server_ts: 123,
23
- content: { msgtype: "m.text", body },
24
- };
25
- });
26
-
27
- return {
28
- client: {
29
- getRoomStateEvent,
30
- sendStateEvent,
31
- getEvent,
32
- stop: vi.fn(),
33
- } as unknown as MatrixClient,
34
- getPinned: () => pinned,
35
- sendStateEvent,
36
- };
37
- }
38
-
39
- describe("matrix pins actions", () => {
40
- it("pins a message once even when asked twice", async () => {
41
- const { client, getPinned, sendStateEvent } = createPinsClient(["$a"]);
42
-
43
- const first = await pinMatrixMessage("!room:example.org", "$b", { client });
44
- const second = await pinMatrixMessage("!room:example.org", "$b", { client });
45
-
46
- expect(first.pinned).toEqual(["$a", "$b"]);
47
- expect(second.pinned).toEqual(["$a", "$b"]);
48
- expect(getPinned()).toEqual(["$a", "$b"]);
49
- expect(sendStateEvent).toHaveBeenCalledTimes(2);
50
- });
51
-
52
- it("unpinds only the selected message id", async () => {
53
- const { client, getPinned } = createPinsClient(["$a", "$b", "$c"]);
54
-
55
- const result = await unpinMatrixMessage("!room:example.org", "$b", { client });
56
-
57
- expect(result.pinned).toEqual(["$a", "$c"]);
58
- expect(getPinned()).toEqual(["$a", "$c"]);
59
- });
60
-
61
- it("lists pinned ids and summarizes only resolvable events", async () => {
62
- const { client } = createPinsClient(["$a", "$missing"], { $a: "hello" });
63
-
64
- const result = await listMatrixPins("!room:example.org", { client });
65
-
66
- expect(result.pinned).toEqual(["$a", "$missing"]);
67
- expect(result.events).toEqual([
68
- expect.objectContaining({
69
- eventId: "$a",
70
- body: "hello",
71
- }),
72
- ]);
73
- });
74
- });
@@ -1,84 +0,0 @@
1
- import { resolveMatrixRoomId } from "../send.js";
2
- import { resolveActionClient } from "./client.js";
3
- import { fetchEventSummary, readPinnedEvents } from "./summary.js";
4
- import {
5
- EventType,
6
- type MatrixActionClientOpts,
7
- type MatrixActionClient,
8
- type MatrixMessageSummary,
9
- type RoomPinnedEventsEventContent,
10
- } from "./types.js";
11
-
12
- type ActionClient = MatrixActionClient["client"];
13
-
14
- async function withResolvedPinRoom<T>(
15
- roomId: string,
16
- opts: MatrixActionClientOpts,
17
- run: (client: ActionClient, resolvedRoom: string) => Promise<T>,
18
- ): Promise<T> {
19
- const { client, stopOnDone } = await resolveActionClient(opts);
20
- try {
21
- const resolvedRoom = await resolveMatrixRoomId(client, roomId);
22
- return await run(client, resolvedRoom);
23
- } finally {
24
- if (stopOnDone) {
25
- client.stop();
26
- }
27
- }
28
- }
29
-
30
- async function updateMatrixPins(
31
- roomId: string,
32
- messageId: string,
33
- opts: MatrixActionClientOpts,
34
- update: (current: string[]) => string[],
35
- ): Promise<{ pinned: string[] }> {
36
- return await withResolvedPinRoom(roomId, opts, async (client, resolvedRoom) => {
37
- const current = await readPinnedEvents(client, resolvedRoom);
38
- const next = update(current);
39
- const payload: RoomPinnedEventsEventContent = { pinned: next };
40
- await client.sendStateEvent(resolvedRoom, EventType.RoomPinnedEvents, "", payload);
41
- return { pinned: next };
42
- });
43
- }
44
-
45
- export async function pinMatrixMessage(
46
- roomId: string,
47
- messageId: string,
48
- opts: MatrixActionClientOpts = {},
49
- ): Promise<{ pinned: string[] }> {
50
- return await updateMatrixPins(roomId, messageId, opts, (current) =>
51
- current.includes(messageId) ? current : [...current, messageId],
52
- );
53
- }
54
-
55
- export async function unpinMatrixMessage(
56
- roomId: string,
57
- messageId: string,
58
- opts: MatrixActionClientOpts = {},
59
- ): Promise<{ pinned: string[] }> {
60
- return await updateMatrixPins(roomId, messageId, opts, (current) =>
61
- current.filter((id) => id !== messageId),
62
- );
63
- }
64
-
65
- export async function listMatrixPins(
66
- roomId: string,
67
- opts: MatrixActionClientOpts = {},
68
- ): Promise<{ pinned: string[]; events: MatrixMessageSummary[] }> {
69
- return await withResolvedPinRoom(roomId, opts, async (client, resolvedRoom) => {
70
- const pinned = await readPinnedEvents(client, resolvedRoom);
71
- const events = (
72
- await Promise.all(
73
- pinned.map(async (eventId) => {
74
- try {
75
- return await fetchEventSummary(client, resolvedRoom, eventId);
76
- } catch {
77
- return null;
78
- }
79
- }),
80
- )
81
- ).filter((event): event is MatrixMessageSummary => Boolean(event));
82
- return { pinned, events };
83
- });
84
- }
@@ -1,109 +0,0 @@
1
- import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
- import { describe, expect, it, vi } from "vitest";
3
- import { listMatrixReactions, removeMatrixReactions } from "./reactions.js";
4
-
5
- function createReactionsClient(params: {
6
- chunk: Array<{
7
- event_id?: string;
8
- sender?: string;
9
- key?: string;
10
- }>;
11
- userId?: string | null;
12
- }) {
13
- const doRequest = vi.fn(async (_method: string, _path: string, _query: any) => ({
14
- chunk: params.chunk.map((item) => ({
15
- event_id: item.event_id ?? "",
16
- sender: item.sender ?? "",
17
- content: item.key
18
- ? {
19
- "m.relates_to": {
20
- rel_type: "m.annotation",
21
- event_id: "$target",
22
- key: item.key,
23
- },
24
- }
25
- : {},
26
- })),
27
- }));
28
- const getUserId = vi.fn(async () => params.userId ?? null);
29
- const redactEvent = vi.fn(async () => undefined);
30
-
31
- return {
32
- client: {
33
- doRequest,
34
- getUserId,
35
- redactEvent,
36
- stop: vi.fn(),
37
- } as unknown as MatrixClient,
38
- doRequest,
39
- redactEvent,
40
- };
41
- }
42
-
43
- describe("matrix reaction actions", () => {
44
- it("aggregates reactions by key and unique sender", async () => {
45
- const { client, doRequest } = createReactionsClient({
46
- chunk: [
47
- { event_id: "$1", sender: "@alice:example.org", key: "👍" },
48
- { event_id: "$2", sender: "@bob:example.org", key: "👍" },
49
- { event_id: "$3", sender: "@alice:example.org", key: "👎" },
50
- { event_id: "$4", sender: "@bot:example.org" },
51
- ],
52
- userId: "@bot:example.org",
53
- });
54
-
55
- const result = await listMatrixReactions("!room:example.org", "$msg", { client, limit: 2.9 });
56
-
57
- expect(doRequest).toHaveBeenCalledWith(
58
- "GET",
59
- expect.stringContaining("/rooms/!room%3Aexample.org/relations/%24msg/"),
60
- expect.objectContaining({ limit: 2 }),
61
- );
62
- expect(result).toEqual(
63
- expect.arrayContaining([
64
- expect.objectContaining({
65
- key: "👍",
66
- count: 2,
67
- users: expect.arrayContaining(["@alice:example.org", "@bob:example.org"]),
68
- }),
69
- expect.objectContaining({
70
- key: "👎",
71
- count: 1,
72
- users: ["@alice:example.org"],
73
- }),
74
- ]),
75
- );
76
- });
77
-
78
- it("removes only current-user reactions matching emoji filter", async () => {
79
- const { client, redactEvent } = createReactionsClient({
80
- chunk: [
81
- { event_id: "$1", sender: "@me:example.org", key: "👍" },
82
- { event_id: "$2", sender: "@me:example.org", key: "👎" },
83
- { event_id: "$3", sender: "@other:example.org", key: "👍" },
84
- ],
85
- userId: "@me:example.org",
86
- });
87
-
88
- const result = await removeMatrixReactions("!room:example.org", "$msg", {
89
- client,
90
- emoji: "👍",
91
- });
92
-
93
- expect(result).toEqual({ removed: 1 });
94
- expect(redactEvent).toHaveBeenCalledTimes(1);
95
- expect(redactEvent).toHaveBeenCalledWith("!room:example.org", "$1");
96
- });
97
-
98
- it("returns removed=0 when current user id is unavailable", async () => {
99
- const { client, redactEvent } = createReactionsClient({
100
- chunk: [{ event_id: "$1", sender: "@me:example.org", key: "👍" }],
101
- userId: null,
102
- });
103
-
104
- const result = await removeMatrixReactions("!room:example.org", "$msg", { client });
105
-
106
- expect(result).toEqual({ removed: 0 });
107
- expect(redactEvent).not.toHaveBeenCalled();
108
- });
109
- });
@@ -1,102 +0,0 @@
1
- import { resolveMatrixRoomId } from "../send.js";
2
- import { resolveActionClient } from "./client.js";
3
- import { resolveMatrixActionLimit } from "./limits.js";
4
- import {
5
- EventType,
6
- RelationType,
7
- type MatrixActionClientOpts,
8
- type MatrixRawEvent,
9
- type MatrixReactionSummary,
10
- type ReactionEventContent,
11
- } from "./types.js";
12
-
13
- function getReactionsPath(roomId: string, messageId: string): string {
14
- return `/_matrix/client/v1/rooms/${encodeURIComponent(roomId)}/relations/${encodeURIComponent(messageId)}/${RelationType.Annotation}/${EventType.Reaction}`;
15
- }
16
-
17
- async function listReactionEvents(
18
- client: NonNullable<MatrixActionClientOpts["client"]>,
19
- roomId: string,
20
- messageId: string,
21
- limit: number,
22
- ): Promise<MatrixRawEvent[]> {
23
- const res = (await client.doRequest("GET", getReactionsPath(roomId, messageId), {
24
- dir: "b",
25
- limit,
26
- })) as { chunk: MatrixRawEvent[] };
27
- return res.chunk;
28
- }
29
-
30
- export async function listMatrixReactions(
31
- roomId: string,
32
- messageId: string,
33
- opts: MatrixActionClientOpts & { limit?: number } = {},
34
- ): Promise<MatrixReactionSummary[]> {
35
- const { client, stopOnDone } = await resolveActionClient(opts);
36
- try {
37
- const resolvedRoom = await resolveMatrixRoomId(client, roomId);
38
- const limit = resolveMatrixActionLimit(opts.limit, 100);
39
- const chunk = await listReactionEvents(client, resolvedRoom, messageId, limit);
40
- const summaries = new Map<string, MatrixReactionSummary>();
41
- for (const event of chunk) {
42
- const content = event.content as ReactionEventContent;
43
- const key = content["m.relates_to"]?.key;
44
- if (!key) {
45
- continue;
46
- }
47
- const sender = event.sender ?? "";
48
- const entry: MatrixReactionSummary = summaries.get(key) ?? {
49
- key,
50
- count: 0,
51
- users: [],
52
- };
53
- entry.count += 1;
54
- if (sender && !entry.users.includes(sender)) {
55
- entry.users.push(sender);
56
- }
57
- summaries.set(key, entry);
58
- }
59
- return Array.from(summaries.values());
60
- } finally {
61
- if (stopOnDone) {
62
- client.stop();
63
- }
64
- }
65
- }
66
-
67
- export async function removeMatrixReactions(
68
- roomId: string,
69
- messageId: string,
70
- opts: MatrixActionClientOpts & { emoji?: string } = {},
71
- ): Promise<{ removed: number }> {
72
- const { client, stopOnDone } = await resolveActionClient(opts);
73
- try {
74
- const resolvedRoom = await resolveMatrixRoomId(client, roomId);
75
- const chunk = await listReactionEvents(client, resolvedRoom, messageId, 200);
76
- const userId = await client.getUserId();
77
- if (!userId) {
78
- return { removed: 0 };
79
- }
80
- const targetEmoji = opts.emoji?.trim();
81
- const toRemove = chunk
82
- .filter((event) => event.sender === userId)
83
- .filter((event) => {
84
- if (!targetEmoji) {
85
- return true;
86
- }
87
- const content = event.content as ReactionEventContent;
88
- return content["m.relates_to"]?.key === targetEmoji;
89
- })
90
- .map((event) => event.event_id)
91
- .filter((id): id is string => Boolean(id));
92
- if (toRemove.length === 0) {
93
- return { removed: 0 };
94
- }
95
- await Promise.all(toRemove.map((id) => client.redactEvent(resolvedRoom, id)));
96
- return { removed: toRemove.length };
97
- } finally {
98
- if (stopOnDone) {
99
- client.stop();
100
- }
101
- }
102
- }
@@ -1,85 +0,0 @@
1
- import { resolveMatrixRoomId } from "../send.js";
2
- import { resolveActionClient } from "./client.js";
3
- import { EventType, type MatrixActionClientOpts } from "./types.js";
4
-
5
- export async function getMatrixMemberInfo(
6
- userId: string,
7
- opts: MatrixActionClientOpts & { roomId?: string } = {},
8
- ) {
9
- const { client, stopOnDone } = await resolveActionClient(opts);
10
- try {
11
- const roomId = opts.roomId ? await resolveMatrixRoomId(client, opts.roomId) : undefined;
12
- // @vector-im/matrix-bot-sdk uses getUserProfile
13
- const profile = await client.getUserProfile(userId);
14
- // Note: @vector-im/matrix-bot-sdk doesn't have getRoom().getMember() like matrix-js-sdk
15
- // We'd need to fetch room state separately if needed
16
- return {
17
- userId,
18
- profile: {
19
- displayName: profile?.displayname ?? null,
20
- avatarUrl: profile?.avatar_url ?? null,
21
- },
22
- membership: null, // Would need separate room state query
23
- powerLevel: null, // Would need separate power levels state query
24
- displayName: profile?.displayname ?? null,
25
- roomId: roomId ?? null,
26
- };
27
- } finally {
28
- if (stopOnDone) {
29
- client.stop();
30
- }
31
- }
32
- }
33
-
34
- export async function getMatrixRoomInfo(roomId: string, opts: MatrixActionClientOpts = {}) {
35
- const { client, stopOnDone } = await resolveActionClient(opts);
36
- try {
37
- const resolvedRoom = await resolveMatrixRoomId(client, roomId);
38
- // @vector-im/matrix-bot-sdk uses getRoomState for state events
39
- let name: string | null = null;
40
- let topic: string | null = null;
41
- let canonicalAlias: string | null = null;
42
- let memberCount: number | null = null;
43
-
44
- try {
45
- const nameState = await client.getRoomStateEvent(resolvedRoom, "m.room.name", "");
46
- name = nameState?.name ?? null;
47
- } catch {
48
- // ignore
49
- }
50
-
51
- try {
52
- const topicState = await client.getRoomStateEvent(resolvedRoom, EventType.RoomTopic, "");
53
- topic = topicState?.topic ?? null;
54
- } catch {
55
- // ignore
56
- }
57
-
58
- try {
59
- const aliasState = await client.getRoomStateEvent(resolvedRoom, "m.room.canonical_alias", "");
60
- canonicalAlias = aliasState?.alias ?? null;
61
- } catch {
62
- // ignore
63
- }
64
-
65
- try {
66
- const members = await client.getJoinedRoomMembers(resolvedRoom);
67
- memberCount = members.length;
68
- } catch {
69
- // ignore
70
- }
71
-
72
- return {
73
- roomId: resolvedRoom,
74
- name,
75
- topic,
76
- canonicalAlias,
77
- altAliases: [], // Would need separate query
78
- memberCount,
79
- };
80
- } finally {
81
- if (stopOnDone) {
82
- client.stop();
83
- }
84
- }
85
- }
@@ -1,75 +0,0 @@
1
- import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
- import {
3
- EventType,
4
- type MatrixMessageSummary,
5
- type MatrixRawEvent,
6
- type RoomMessageEventContent,
7
- type RoomPinnedEventsEventContent,
8
- } from "./types.js";
9
-
10
- export function summarizeMatrixRawEvent(event: MatrixRawEvent): MatrixMessageSummary {
11
- const content = event.content as RoomMessageEventContent;
12
- const relates = content["m.relates_to"];
13
- let relType: string | undefined;
14
- let eventId: string | undefined;
15
- if (relates) {
16
- if ("rel_type" in relates) {
17
- relType = relates.rel_type;
18
- eventId = relates.event_id;
19
- } else if ("m.in_reply_to" in relates) {
20
- eventId = relates["m.in_reply_to"]?.event_id;
21
- }
22
- }
23
- const relatesTo =
24
- relType || eventId
25
- ? {
26
- relType,
27
- eventId,
28
- }
29
- : undefined;
30
- return {
31
- eventId: event.event_id,
32
- sender: event.sender,
33
- body: content.body,
34
- msgtype: content.msgtype,
35
- timestamp: event.origin_server_ts,
36
- relatesTo,
37
- };
38
- }
39
-
40
- export async function readPinnedEvents(client: MatrixClient, roomId: string): Promise<string[]> {
41
- try {
42
- const content = (await client.getRoomStateEvent(
43
- roomId,
44
- EventType.RoomPinnedEvents,
45
- "",
46
- )) as RoomPinnedEventsEventContent;
47
- const pinned = content.pinned;
48
- return pinned.filter((id) => id.trim().length > 0);
49
- } catch (err: unknown) {
50
- const errObj = err as { statusCode?: number; body?: { errcode?: string } };
51
- const httpStatus = errObj.statusCode;
52
- const errcode = errObj.body?.errcode;
53
- if (httpStatus === 404 || errcode === "M_NOT_FOUND") {
54
- return [];
55
- }
56
- throw err;
57
- }
58
- }
59
-
60
- export async function fetchEventSummary(
61
- client: MatrixClient,
62
- roomId: string,
63
- eventId: string,
64
- ): Promise<MatrixMessageSummary | null> {
65
- try {
66
- const raw = (await client.getEvent(roomId, eventId)) as unknown as MatrixRawEvent;
67
- if (raw.unsigned?.redacted_because) {
68
- return null;
69
- }
70
- return summarizeMatrixRawEvent(raw);
71
- } catch {
72
- // Event not found, redacted, or inaccessible - return null
73
- return null;
74
- }
75
- }
@@ -1,85 +0,0 @@
1
- import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
-
3
- export const MsgType = {
4
- Text: "m.text",
5
- } as const;
6
-
7
- export const RelationType = {
8
- Replace: "m.replace",
9
- Annotation: "m.annotation",
10
- } as const;
11
-
12
- export const EventType = {
13
- RoomMessage: "m.room.message",
14
- RoomPinnedEvents: "m.room.pinned_events",
15
- RoomTopic: "m.room.topic",
16
- Reaction: "m.reaction",
17
- } as const;
18
-
19
- export type RoomMessageEventContent = {
20
- msgtype: string;
21
- body: string;
22
- "m.new_content"?: RoomMessageEventContent;
23
- "m.relates_to"?: {
24
- rel_type?: string;
25
- event_id?: string;
26
- "m.in_reply_to"?: { event_id?: string };
27
- };
28
- };
29
-
30
- export type ReactionEventContent = {
31
- "m.relates_to": {
32
- rel_type: string;
33
- event_id: string;
34
- key: string;
35
- };
36
- };
37
-
38
- export type RoomPinnedEventsEventContent = {
39
- pinned: string[];
40
- };
41
-
42
- export type RoomTopicEventContent = {
43
- topic?: string;
44
- };
45
-
46
- export type MatrixRawEvent = {
47
- event_id: string;
48
- sender: string;
49
- type: string;
50
- origin_server_ts: number;
51
- content: Record<string, unknown>;
52
- unsigned?: {
53
- redacted_because?: unknown;
54
- };
55
- };
56
-
57
- export type MatrixActionClientOpts = {
58
- client?: MatrixClient;
59
- timeoutMs?: number;
60
- accountId?: string | null;
61
- };
62
-
63
- export type MatrixMessageSummary = {
64
- eventId?: string;
65
- sender?: string;
66
- body?: string;
67
- msgtype?: string;
68
- timestamp?: number;
69
- relatesTo?: {
70
- relType?: string;
71
- eventId?: string;
72
- key?: string;
73
- };
74
- };
75
-
76
- export type MatrixReactionSummary = {
77
- key: string;
78
- count: number;
79
- users: string[];
80
- };
81
-
82
- export type MatrixActionClient = {
83
- client: MatrixClient;
84
- stopOnDone: boolean;
85
- };
@@ -1,15 +0,0 @@
1
- export type {
2
- MatrixActionClientOpts,
3
- MatrixMessageSummary,
4
- MatrixReactionSummary,
5
- } from "./actions/types.js";
6
- export {
7
- sendMatrixMessage,
8
- editMatrixMessage,
9
- deleteMatrixMessage,
10
- readMatrixMessages,
11
- } from "./actions/messages.js";
12
- export { listMatrixReactions, removeMatrixReactions } from "./actions/reactions.js";
13
- export { pinMatrixMessage, unpinMatrixMessage, listMatrixPins } from "./actions/pins.js";
14
- export { getMatrixMemberInfo, getMatrixRoomInfo } from "./actions/room.js";
15
- export { reactMatrixMessage } from "./send.js";
@@ -1,32 +0,0 @@
1
- import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
- import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
-
4
- // Support multiple active clients for multi-account
5
- const activeClients = new Map<string, MatrixClient>();
6
-
7
- export function setActiveMatrixClient(
8
- client: MatrixClient | null,
9
- accountId?: string | null,
10
- ): void {
11
- const key = normalizeAccountId(accountId);
12
- if (client) {
13
- activeClients.set(key, client);
14
- } else {
15
- activeClients.delete(key);
16
- }
17
- }
18
-
19
- export function getActiveMatrixClient(accountId?: string | null): MatrixClient | null {
20
- const key = normalizeAccountId(accountId);
21
- return activeClients.get(key) ?? null;
22
- }
23
-
24
- export function getAnyActiveMatrixClient(): MatrixClient | null {
25
- // Return any available client (for backward compatibility)
26
- const first = activeClients.values().next();
27
- return first.done ? null : first.value;
28
- }
29
-
30
- export function clearAllActiveMatrixClients(): void {
31
- activeClients.clear();
32
- }