From 3c52124ca70391c21ac8d211cfa205bc57c23a10 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Wed, 25 Feb 2026 17:22:09 -0500 Subject: [PATCH] Matrix-js: fix pnpm check typing regressions --- .../matrix-js/scripts/live-read-room.ts | 12 +---- .../src/matrix/actions/client.test.ts | 8 +-- .../matrix-js/src/matrix/actions/client.ts | 2 +- .../matrix-js/src/matrix/actions/types.ts | 3 +- .../matrix-js/src/matrix/client.test.ts | 7 ++- .../matrix-js/src/matrix/client/config.ts | 2 +- .../src/matrix/client/register-mode.test.ts | 3 +- .../src/matrix/client/register-mode.ts | 2 +- .../matrix-js/src/matrix/client/shared.ts | 2 +- .../src/matrix/monitor/events.test.ts | 18 ++++--- .../matrix-js/src/matrix/monitor/events.ts | 17 +++--- .../matrix-js/src/matrix/monitor/handler.ts | 54 ++++++------------- .../matrix-js/src/matrix/monitor/index.ts | 1 - .../matrix-js/src/matrix/monitor/media.ts | 9 ++-- .../matrix-js/src/matrix/monitor/mentions.ts | 4 +- .../matrix-js/src/matrix/monitor/room-info.ts | 18 +++++-- .../matrix-js/src/matrix/monitor/threads.ts | 2 - .../matrix-js/src/matrix/monitor/types.ts | 3 +- extensions/matrix-js/src/matrix/sdk.test.ts | 17 +++--- extensions/matrix-js/src/matrix/sdk.ts | 9 ++-- .../src/matrix/sdk/crypto-bootstrap.test.ts | 20 ++++--- .../src/matrix/sdk/recovery-key-store.ts | 2 +- .../matrix-js/src/matrix/send/client.ts | 19 +++++-- .../matrix-js/src/matrix/send/targets.ts | 6 ++- 24 files changed, 123 insertions(+), 117 deletions(-) diff --git a/extensions/matrix-js/scripts/live-read-room.ts b/extensions/matrix-js/scripts/live-read-room.ts index 23612895aaa..27607fc9412 100644 --- a/extensions/matrix-js/scripts/live-read-room.ts +++ b/extensions/matrix-js/scripts/live-read-room.ts @@ -2,14 +2,6 @@ import { readMatrixMessages } from "../src/matrix/actions.js"; import { createMatrixClient, resolveMatrixAuth } from "../src/matrix/client.js"; import { installLiveHarnessRuntime, resolveLiveHarnessConfig } from "./live-common.js"; -function toMessageText(msg: { - text: string | null; - body?: string | null; - fallbackBody?: string | null; -}): string { - return msg.text ?? msg.body ?? msg.fallbackBody ?? ""; -} - async function main() { const roomId = process.argv[2]?.trim(); if (!roomId) { @@ -34,10 +26,10 @@ async function main() { try { const result = await readMatrixMessages(roomId, { client, limit }); const compact = result.messages.map((msg) => ({ - id: msg.id, + id: msg.eventId, sender: msg.sender, ts: msg.timestamp, - text: toMessageText(msg), + text: msg.body ?? "", })); process.stdout.write( diff --git a/extensions/matrix-js/src/matrix/actions/client.test.ts b/extensions/matrix-js/src/matrix/actions/client.test.ts index b486e89cf29..8e25cad8fbc 100644 --- a/extensions/matrix-js/src/matrix/actions/client.test.ts +++ b/extensions/matrix-js/src/matrix/actions/client.test.ts @@ -10,19 +10,19 @@ const resolveMatrixAuthMock = vi.fn(); vi.mock("../../runtime.js", () => ({ getMatrixRuntime: () => ({ config: { - loadConfig: (...args: unknown[]) => loadConfigMock(...args), + loadConfig: loadConfigMock, }, }), })); vi.mock("../active-client.js", () => ({ - getActiveMatrixClient: (...args: unknown[]) => getActiveMatrixClientMock(...args), + getActiveMatrixClient: getActiveMatrixClientMock, })); vi.mock("../client.js", () => ({ - createMatrixClient: (...args: unknown[]) => createMatrixClientMock(...args), + createMatrixClient: createMatrixClientMock, isBunRuntime: () => isBunRuntimeMock(), - resolveMatrixAuth: (...args: unknown[]) => resolveMatrixAuthMock(...args), + resolveMatrixAuth: resolveMatrixAuthMock, })); let resolveActionClient: typeof import("./client.js").resolveActionClient; diff --git a/extensions/matrix-js/src/matrix/actions/client.ts b/extensions/matrix-js/src/matrix/actions/client.ts index 2550f0bdfee..a4597f65431 100644 --- a/extensions/matrix-js/src/matrix/actions/client.ts +++ b/extensions/matrix-js/src/matrix/actions/client.ts @@ -1,7 +1,7 @@ import { getMatrixRuntime } from "../../runtime.js"; +import type { CoreConfig } from "../../types.js"; import { getActiveMatrixClient } from "../active-client.js"; import { createMatrixClient, isBunRuntime, resolveMatrixAuth } from "../client.js"; -import type { CoreConfig } from "../types.js"; import type { MatrixActionClient, MatrixActionClientOpts } from "./types.js"; export function ensureNodeRuntime() { diff --git a/extensions/matrix-js/src/matrix/actions/types.ts b/extensions/matrix-js/src/matrix/actions/types.ts index 8d49c060784..f6f94481c3a 100644 --- a/extensions/matrix-js/src/matrix/actions/types.ts +++ b/extensions/matrix-js/src/matrix/actions/types.ts @@ -1,4 +1,5 @@ -import type { MatrixClient, MatrixRawEvent, MessageEventContent } from "../sdk.js"; +import type { MatrixClient, MessageEventContent } from "../sdk.js"; +export type { MatrixRawEvent } from "../sdk.js"; export const MsgType = { Text: "m.text", diff --git a/extensions/matrix-js/src/matrix/client.test.ts b/extensions/matrix-js/src/matrix/client.test.ts index 27989345feb..4f354312e48 100644 --- a/extensions/matrix-js/src/matrix/client.test.ts +++ b/extensions/matrix-js/src/matrix/client.test.ts @@ -10,15 +10,14 @@ const finalizeMatrixRegisterConfigAfterSuccessMock = vi.fn(async () => false); vi.mock("./credentials.js", () => ({ loadMatrixCredentials: vi.fn(() => null), - saveMatrixCredentials: (...args: unknown[]) => saveMatrixCredentialsMock(...args), + saveMatrixCredentials: saveMatrixCredentialsMock, credentialsMatchConfig: vi.fn(() => false), touchMatrixCredentials: vi.fn(), })); vi.mock("./client/register-mode.js", () => ({ - prepareMatrixRegisterMode: (...args: unknown[]) => prepareMatrixRegisterModeMock(...args), - finalizeMatrixRegisterConfigAfterSuccess: (...args: unknown[]) => - finalizeMatrixRegisterConfigAfterSuccessMock(...args), + prepareMatrixRegisterMode: prepareMatrixRegisterModeMock, + finalizeMatrixRegisterConfigAfterSuccess: finalizeMatrixRegisterConfigAfterSuccessMock, resetPreparedMatrixRegisterModesForTests: vi.fn(), })); diff --git a/extensions/matrix-js/src/matrix/client/config.ts b/extensions/matrix-js/src/matrix/client/config.ts index 444211f9359..a98fa043cc9 100644 --- a/extensions/matrix-js/src/matrix/client/config.ts +++ b/extensions/matrix-js/src/matrix/client/config.ts @@ -1,7 +1,7 @@ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id"; import { getMatrixRuntime } from "../../runtime.js"; +import type { CoreConfig } from "../../types.js"; import { MatrixClient } from "../sdk.js"; -import type { CoreConfig } from "../types.js"; import { ensureMatrixSdkLoggingConfigured } from "./logging.js"; import { finalizeMatrixRegisterConfigAfterSuccess, diff --git a/extensions/matrix-js/src/matrix/client/register-mode.test.ts b/extensions/matrix-js/src/matrix/client/register-mode.test.ts index bc82877556d..7106ac3209a 100644 --- a/extensions/matrix-js/src/matrix/client/register-mode.test.ts +++ b/extensions/matrix-js/src/matrix/client/register-mode.test.ts @@ -91,7 +91,8 @@ describe("matrix register mode helpers", () => { }), }), ); - const written = writeConfigFile.mock.calls[0]?.[0] as CoreConfig; + const firstCall = (writeConfigFile.mock.calls as unknown[][])[0]; + const written = (firstCall?.[0] ?? {}) as CoreConfig; expect(written.channels?.["matrix-js"]?.accessToken).toBeUndefined(); }); }); diff --git a/extensions/matrix-js/src/matrix/client/register-mode.ts b/extensions/matrix-js/src/matrix/client/register-mode.ts index 10672f7fbe0..4475ffb3cc6 100644 --- a/extensions/matrix-js/src/matrix/client/register-mode.ts +++ b/extensions/matrix-js/src/matrix/client/register-mode.ts @@ -112,7 +112,7 @@ export async function finalizeMatrixRegisterConfigAfterSuccess(params: { ...cfg, channels: { ...(cfg.channels ?? {}), - "matrix-js": nextMatrix as CoreConfig["channels"]["matrix-js"], + "matrix-js": nextMatrix as NonNullable["matrix-js"], }, }; diff --git a/extensions/matrix-js/src/matrix/client/shared.ts b/extensions/matrix-js/src/matrix/client/shared.ts index ecf121b3dbe..6a90449bfa1 100644 --- a/extensions/matrix-js/src/matrix/client/shared.ts +++ b/extensions/matrix-js/src/matrix/client/shared.ts @@ -1,6 +1,6 @@ +import type { CoreConfig } from "../../types.js"; import type { MatrixClient } from "../sdk.js"; import { LogService } from "../sdk/logger.js"; -import type { CoreConfig } from "../types.js"; import { resolveMatrixAuth } from "./config.js"; import { createMatrixClient } from "./create-client.js"; import { DEFAULT_ACCOUNT_KEY } from "./storage.js"; diff --git a/extensions/matrix-js/src/matrix/monitor/events.test.ts b/extensions/matrix-js/src/matrix/monitor/events.test.ts index 45b4877806c..cbfc3311187 100644 --- a/extensions/matrix-js/src/matrix/monitor/events.test.ts +++ b/extensions/matrix-js/src/matrix/monitor/events.test.ts @@ -7,6 +7,12 @@ import { EventType } from "./types.js"; type RoomEventListener = (roomId: string, event: MatrixRawEvent) => void; +function getSentNoticeBody(sendMessage: ReturnType, index = 0): string { + const calls = sendMessage.mock.calls as unknown[][]; + const payload = (calls[index]?.[1] ?? {}) as { body?: string }; + return payload.body ?? ""; +} + function createHarness(params?: { verifications?: Array<{ id: string; @@ -43,7 +49,7 @@ function createHarness(params?: { logVerboseMessage: vi.fn(), warnedEncryptedRooms: new Set(), warnedCryptoMissingRooms: new Set(), - logger: { warn: vi.fn() }, + logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() }, formatNativeDependencyHint: vi.fn(() => "install hint"), onRoomMessage, }); @@ -83,7 +89,7 @@ describe("registerMatrixMonitorEvents verification routing", () => { expect(sendMessage).toHaveBeenCalledTimes(1); }); expect(onRoomMessage).not.toHaveBeenCalled(); - const body = (sendMessage.mock.calls[0]?.[1] as { body?: string } | undefined)?.body ?? ""; + const body = getSentNoticeBody(sendMessage, 0); expect(body).toContain("Matrix verification request received from @alice:example.org."); expect(body).toContain('Open "Verify by emoji"'); }); @@ -103,7 +109,7 @@ describe("registerMatrixMonitorEvents verification routing", () => { await vi.waitFor(() => { expect(sendMessage).toHaveBeenCalledTimes(1); }); - const body = (sendMessage.mock.calls[0]?.[1] as { body?: string } | undefined)?.body ?? ""; + const body = getSentNoticeBody(sendMessage, 0); expect(body).toContain("Matrix verification is ready with @alice:example.org."); expect(body).toContain('Choose "Verify by emoji"'); }); @@ -140,8 +146,8 @@ describe("registerMatrixMonitorEvents verification routing", () => { }); await vi.waitFor(() => { - const bodies = sendMessage.mock.calls.map((call) => - ((call[1] as { body?: string } | undefined)?.body ?? "").toString(), + const bodies = (sendMessage.mock.calls as unknown[][]).map((call) => + String((call[1] as { body?: string } | undefined)?.body ?? ""), ); expect(bodies.some((body) => body.includes("SAS emoji:"))).toBe(true); expect(bodies.some((body) => body.includes("SAS decimal: 6158 1986 3513"))).toBe(true); @@ -193,7 +199,7 @@ describe("registerMatrixMonitorEvents verification routing", () => { await new Promise((resolve) => setTimeout(resolve, 20)); const sasBodies = sendMessage.mock.calls - .map((call) => ((call[1] as { body?: string } | undefined)?.body ?? "").toString()) + .map((call) => String(((call as unknown[])[1] as { body?: string } | undefined)?.body ?? "")) .filter((body) => body.includes("SAS emoji:")); expect(sasBodies).toHaveLength(1); }); diff --git a/extensions/matrix-js/src/matrix/monitor/events.ts b/extensions/matrix-js/src/matrix/monitor/events.ts index 4a1f18486e2..443798f8081 100644 --- a/extensions/matrix-js/src/matrix/monitor/events.ts +++ b/extensions/matrix-js/src/matrix/monitor/events.ts @@ -1,4 +1,4 @@ -import type { PluginRuntime } from "openclaw/plugin-sdk"; +import type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk"; import type { MatrixAuth } from "../client.js"; import type { MatrixClient } from "../sdk.js"; import type { MatrixRawEvent } from "./types.js"; @@ -240,7 +240,7 @@ export function registerMatrixMonitorEvents(params: { logVerboseMessage: (message: string) => void; warnedEncryptedRooms: Set; warnedCryptoMissingRooms: Set; - logger: { warn: (meta: Record, message: string) => void }; + logger: RuntimeLogger; formatNativeDependencyHint: PluginRuntime["system"]["formatNativeDependencyHint"]; onRoomMessage: (roomId: string, event: MatrixRawEvent) => void | Promise; }): void { @@ -334,10 +334,11 @@ export function registerMatrixMonitorEvents(params: { client.on( "room.failed_decryption", async (roomId: string, event: MatrixRawEvent, error: Error) => { - logger.warn( - { roomId, eventId: event.event_id, error: error.message }, - "Failed to decrypt message", - ); + logger.warn("Failed to decrypt message", { + roomId, + eventId: event.event_id, + error: error.message, + }); logVerboseMessage( `matrix: failed decrypt room=${roomId} id=${event.event_id ?? "unknown"} error=${error.message}`, ); @@ -368,7 +369,7 @@ export function registerMatrixMonitorEvents(params: { warnedEncryptedRooms.add(roomId); const warning = "matrix: encrypted event received without encryption enabled; set channels.matrix-js.encryption=true and verify the device to decrypt"; - logger.warn({ roomId }, warning); + logger.warn(warning, { roomId }); } if (auth.encryption === true && !client.crypto && !warnedCryptoMissingRooms.has(roomId)) { warnedCryptoMissingRooms.add(roomId); @@ -378,7 +379,7 @@ export function registerMatrixMonitorEvents(params: { downloadCommand: "node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js", }); const warning = `matrix: encryption enabled but crypto is unavailable; ${hint}`; - logger.warn({ roomId }, warning); + logger.warn(warning, { roomId }); } return; } diff --git a/extensions/matrix-js/src/matrix/monitor/handler.ts b/extensions/matrix-js/src/matrix/monitor/handler.ts index 875018671df..2045f28a006 100644 --- a/extensions/matrix-js/src/matrix/monitor/handler.ts +++ b/extensions/matrix-js/src/matrix/monitor/handler.ts @@ -5,9 +5,12 @@ import { logInboundDrop, logTypingFailure, resolveControlCommandGate, + type PluginRuntime, + type ReplyPayload, type RuntimeEnv, + type RuntimeLogger, } from "openclaw/plugin-sdk"; -import type { CoreConfig, ReplyToMode } from "../../types.js"; +import type { CoreConfig, MatrixRoomConfig, ReplyToMode } from "../../types.js"; import { formatPollAsText, isPollStartType, @@ -38,34 +41,14 @@ import { isMatrixVerificationRoomMessage } from "./verification-utils.js"; export type MatrixMonitorHandlerParams = { client: MatrixClient; - core: { - logging: { - shouldLogVerbose: () => boolean; - }; - channel: (typeof import("openclaw/plugin-sdk"))["channel"]; - system: { - enqueueSystemEvent: ( - text: string, - meta: { sessionKey?: string | null; contextKey?: string | null }, - ) => void; - }; - }; + core: PluginRuntime; cfg: CoreConfig; runtime: RuntimeEnv; - logger: { - info: (message: string | Record, ...meta: unknown[]) => void; - warn: (meta: Record, message: string) => void; - }; + logger: RuntimeLogger; logVerboseMessage: (message: string) => void; allowFrom: string[]; - roomsConfig: CoreConfig["channels"] extends { matrix?: infer MatrixConfig } - ? MatrixConfig extends { groups?: infer Groups } - ? Groups - : Record | undefined - : Record | undefined; - mentionRegexes: ReturnType< - (typeof import("openclaw/plugin-sdk"))["channel"]["mentions"]["buildMentionRegexes"] - >; + roomsConfig?: Record; + mentionRegexes: ReturnType; groupPolicy: "open" | "allowlist" | "disabled"; replyToMode: ReplyToMode; threadReplies: "off" | "inbound" | "always"; @@ -447,7 +430,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam hasControlCommandInMessage; const canDetectMention = mentionRegexes.length > 0 || hasExplicitMention; if (isRoom && shouldRequireMention && !wasMentioned && !shouldBypassMention) { - logger.info({ roomId, reason: "no-mention" }, "skipping room message"); + logger.info("skipping room message", { roomId, reason: "no-mention" }); return; } @@ -465,7 +448,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam cfg, channel: "matrix-js", peer: { - kind: isDirectMessage ? "dm" : "channel", + kind: isDirectMessage ? "direct" : "channel", id: isDirectMessage ? senderId : roomId, }, }); @@ -535,14 +518,11 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam } : undefined, onRecordError: (err) => { - logger.warn( - { - error: String(err), - storePath, - sessionKey: ctxPayload.SessionKey ?? route.sessionKey, - }, - "failed updating session meta", - ); + logger.warn("failed updating session meta", { + error: String(err), + storePath, + sessionKey: ctxPayload.SessionKey ?? route.sessionKey, + }); }, }); @@ -623,7 +603,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam core.channel.reply.createReplyDispatcherWithTyping({ ...prefixOptions, humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, route.agentId), - deliver: async (payload) => { + deliver: async (payload: ReplyPayload) => { await deliverMatrixReplies({ replies: [payload], roomId, @@ -637,7 +617,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam }); didSendReply = true; }, - onError: (err, info) => { + onError: (err: unknown, info: { kind: "tool" | "block" | "final" }) => { runtime.error?.(`matrix ${info.kind} reply failed: ${String(err)}`); }, onReplyStart: typingCallbacks.onReplyStart, diff --git a/extensions/matrix-js/src/matrix/monitor/index.ts b/extensions/matrix-js/src/matrix/monitor/index.ts index 64e9fcd4a33..ccc78d83d9e 100644 --- a/extensions/matrix-js/src/matrix/monitor/index.ts +++ b/extensions/matrix-js/src/matrix/monitor/index.ts @@ -304,7 +304,6 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi directTracker, getRoomInfo, getMemberDisplayName, - accountId: opts.accountId, }); registerMatrixMonitorEvents({ diff --git a/extensions/matrix-js/src/matrix/monitor/media.ts b/extensions/matrix-js/src/matrix/monitor/media.ts index 56210f833c5..bfd31b51138 100644 --- a/extensions/matrix-js/src/matrix/monitor/media.ts +++ b/extensions/matrix-js/src/matrix/monitor/media.ts @@ -20,7 +20,7 @@ async function fetchMatrixMediaBuffer(params: { client: MatrixClient; mxcUrl: string; maxBytes: number; -}): Promise<{ buffer: Buffer; headerType?: string } | null> { +}): Promise<{ buffer: Buffer } | null> { // The client wrapper exposes mxcToHttp for Matrix media URIs. const url = params.client.mxcToHttp(params.mxcUrl); if (!url) { @@ -29,14 +29,13 @@ async function fetchMatrixMediaBuffer(params: { // Use the client's download method which handles auth try { - const result = await params.client.downloadContent(params.mxcUrl); - const raw = result.data ?? result; + const raw = await params.client.downloadContent(params.mxcUrl); const buffer = Buffer.isBuffer(raw) ? raw : Buffer.from(raw); if (buffer.byteLength > params.maxBytes) { throw new Error("Matrix media exceeds configured size limit"); } - return { buffer, headerType: result.contentType }; + return { buffer }; } catch (err) { throw new Error(`Matrix media download failed: ${String(err)}`, { cause: err }); } @@ -103,7 +102,7 @@ export async function downloadMatrixMedia(params: { if (!fetched) { return null; } - const headerType = fetched.headerType ?? params.contentType ?? undefined; + const headerType = params.contentType ?? undefined; const saved = await getMatrixRuntime().channel.media.saveMediaBuffer( fetched.buffer, headerType, diff --git a/extensions/matrix-js/src/matrix/monitor/mentions.ts b/extensions/matrix-js/src/matrix/monitor/mentions.ts index 232e495c88d..7d3a52c9baa 100644 --- a/extensions/matrix-js/src/matrix/monitor/mentions.ts +++ b/extensions/matrix-js/src/matrix/monitor/mentions.ts @@ -1,14 +1,12 @@ import { getMatrixRuntime } from "../../runtime.js"; -// Type for room message content with mentions type MessageContentWithMentions = { - msgtype: string; - body: string; formatted_body?: string; "m.mentions"?: { user_ids?: string[]; room?: boolean; }; + [key: string]: unknown; }; /** diff --git a/extensions/matrix-js/src/matrix/monitor/room-info.ts b/extensions/matrix-js/src/matrix/monitor/room-info.ts index 4a7624d7c10..095f1dc307a 100644 --- a/extensions/matrix-js/src/matrix/monitor/room-info.ts +++ b/extensions/matrix-js/src/matrix/monitor/room-info.ts @@ -19,7 +19,9 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) { let altAliases: string[] = []; try { const nameState = await client.getRoomStateEvent(roomId, "m.room.name", "").catch(() => null); - name = nameState?.name; + if (nameState && typeof nameState.name === "string") { + name = nameState.name; + } } catch { // ignore } @@ -27,8 +29,13 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) { const aliasState = await client .getRoomStateEvent(roomId, "m.room.canonical_alias", "") .catch(() => null); - canonicalAlias = aliasState?.alias; - altAliases = aliasState?.alt_aliases ?? []; + if (aliasState && typeof aliasState.alias === "string") { + canonicalAlias = aliasState.alias; + } + const rawAliases = aliasState?.alt_aliases; + if (Array.isArray(rawAliases)) { + altAliases = rawAliases.filter((entry): entry is string => typeof entry === "string"); + } } catch { // ignore } @@ -42,7 +49,10 @@ export function createMatrixRoomInfoResolver(client: MatrixClient) { const memberState = await client .getRoomStateEvent(roomId, "m.room.member", userId) .catch(() => null); - return memberState?.displayname ?? userId; + if (memberState && typeof memberState.displayname === "string") { + return memberState.displayname; + } + return userId; } catch { return userId; } diff --git a/extensions/matrix-js/src/matrix/monitor/threads.ts b/extensions/matrix-js/src/matrix/monitor/threads.ts index 1a2f260f243..c2ab69218a6 100644 --- a/extensions/matrix-js/src/matrix/monitor/threads.ts +++ b/extensions/matrix-js/src/matrix/monitor/threads.ts @@ -8,8 +8,6 @@ type MatrixRawEvent = { }; type RoomMessageEventContent = { - msgtype: string; - body: string; "m.relates_to"?: { rel_type?: string; event_id?: string; diff --git a/extensions/matrix-js/src/matrix/monitor/types.ts b/extensions/matrix-js/src/matrix/monitor/types.ts index 5d578868f3a..f54d7735819 100644 --- a/extensions/matrix-js/src/matrix/monitor/types.ts +++ b/extensions/matrix-js/src/matrix/monitor/types.ts @@ -1,4 +1,5 @@ -import type { EncryptedFile, MatrixRawEvent, MessageEventContent } from "../sdk.js"; +import type { EncryptedFile, MessageEventContent } from "../sdk.js"; +export type { MatrixRawEvent } from "../sdk.js"; export const EventType = { RoomMessage: "m.room.message", diff --git a/extensions/matrix-js/src/matrix/sdk.test.ts b/extensions/matrix-js/src/matrix/sdk.test.ts index daee09782c7..01945313241 100644 --- a/extensions/matrix-js/src/matrix/sdk.test.ts +++ b/extensions/matrix-js/src/matrix/sdk.test.ts @@ -549,11 +549,11 @@ describe("MatrixClient event bridge", () => { }, }); - let releaseRetry: (() => void) | null = null; + const releaseRetryRef: { current?: () => void } = {}; matrixJsClient.decryptEventIfNeeded = vi.fn( async () => await new Promise((resolve) => { - releaseRetry = () => { + releaseRetryRef.current = () => { encrypted.emit("decrypted", decrypted); resolve(); }; @@ -571,7 +571,7 @@ describe("MatrixClient event bridge", () => { await Promise.resolve(); expect(matrixJsClient.decryptEventIfNeeded).toHaveBeenCalledTimes(1); - releaseRetry?.(); + releaseRetryRef.current?.(); await Promise.resolve(); expect(delivered).toEqual(["m.room.message"]); }); @@ -1227,11 +1227,12 @@ describe("MatrixClient crypto bootstrapping", () => { expect(result.success).toBe(true); expect(result.verification.backupVersion).toBe("9"); - expect( - bootstrapSecretStorage.mock.calls.some(([opts]) => - Boolean((opts as { setupNewKeyBackup?: boolean } | undefined)?.setupNewKeyBackup), - ), - ).toBe(false); + const bootstrapSecretStorageCalls = bootstrapSecretStorage.mock.calls as Array< + [{ setupNewKeyBackup?: boolean }?] + >; + expect(bootstrapSecretStorageCalls.some((call) => Boolean(call[0]?.setupNewKeyBackup))).toBe( + false, + ); }); it("does not report bootstrap errors when final verification state is healthy", async () => { diff --git a/extensions/matrix-js/src/matrix/sdk.ts b/extensions/matrix-js/src/matrix/sdk.ts index b4415e8a602..497a61e533d 100644 --- a/extensions/matrix-js/src/matrix/sdk.ts +++ b/extensions/matrix-js/src/matrix/sdk.ts @@ -38,6 +38,7 @@ export type { export type { EncryptedFile, LocationMessageEventContent, + MatrixRawEvent, MessageEventContent, TextualMessageEventContent, } from "./sdk/types.js"; @@ -187,7 +188,7 @@ export class MatrixClient { deviceId: opts.deviceId, logger: createMatrixJsSdkClientLogger("MatrixClient"), localTimeoutMs: this.localTimeoutMs, - cryptoCallbacks, + cryptoCallbacks: cryptoCallbacks as never, verificationMethods: [ VerificationMethod.Sas, VerificationMethod.ShowQrCode, @@ -421,7 +422,7 @@ export class MatrixClient { } async getAccountData(eventType: string): Promise | undefined> { - const event = this.client.getAccountData(eventType); + const event = this.client.getAccountData(eventType as never); return (event?.getContent() as Record | undefined) ?? undefined; } @@ -529,7 +530,7 @@ export class MatrixClient { } async uploadContent(file: Buffer, contentType?: string, filename?: string): Promise { - const uploaded = await this.client.uploadContent(file, { + const uploaded = await this.client.uploadContent(new Uint8Array(file), { type: contentType || "application/octet-stream", name: filename, includeFilename: Boolean(filename), @@ -1053,8 +1054,8 @@ export class MatrixClient { return; } const raw: MatrixRawEvent = { + event_id: `$membership-${roomId}-${Date.now()}`, type: "m.room.member", - room_id: roomId, sender: selfUserId, state_key: selfUserId, content: { membership }, diff --git a/extensions/matrix-js/src/matrix/sdk/crypto-bootstrap.test.ts b/extensions/matrix-js/src/matrix/sdk/crypto-bootstrap.test.ts index 761fb4d3ccc..7b15d3b4d56 100644 --- a/extensions/matrix-js/src/matrix/sdk/crypto-bootstrap.test.ts +++ b/extensions/matrix-js/src/matrix/sdk/crypto-bootstrap.test.ts @@ -135,15 +135,21 @@ describe("MatrixCryptoBootstrapper", () => { await bootstrapper.bootstrap(crypto); - const firstCall = bootstrapCrossSigning.mock.calls[0]?.[0] as { - authUploadDeviceSigningKeys?: ( - makeRequest: (authData: Record | null) => Promise, - ) => Promise; - }; - expect(firstCall.authUploadDeviceSigningKeys).toBeTypeOf("function"); + const bootstrapCrossSigningCalls = bootstrapCrossSigning.mock.calls as Array< + [ + { + authUploadDeviceSigningKeys?: ( + makeRequest: (authData: Record | null) => Promise, + ) => Promise; + }?, + ] + >; + const authUploadDeviceSigningKeys = + bootstrapCrossSigningCalls[0]?.[0]?.authUploadDeviceSigningKeys; + expect(authUploadDeviceSigningKeys).toBeTypeOf("function"); const seenAuthStages: Array | null> = []; - const result = await firstCall.authUploadDeviceSigningKeys?.(async (authData) => { + const result = await authUploadDeviceSigningKeys?.(async (authData) => { seenAuthStages.push(authData); if (authData === null) { throw new Error("need auth"); diff --git a/extensions/matrix-js/src/matrix/sdk/recovery-key-store.ts b/extensions/matrix-js/src/matrix/sdk/recovery-key-store.ts index e41dbbafd01..dab24e4075e 100644 --- a/extensions/matrix-js/src/matrix/sdk/recovery-key-store.ts +++ b/extensions/matrix-js/src/matrix/sdk/recovery-key-store.ts @@ -145,7 +145,7 @@ export class MatrixRecoveryKeyStore { ); let generatedRecoveryKey = false; const storedRecovery = this.loadStoredRecoveryKey(); - let recoveryKey = storedRecovery + let recoveryKey: MatrixGeneratedSecretStorageKey | null = storedRecovery ? { keyInfo: storedRecovery.keyInfo, privateKey: new Uint8Array(Buffer.from(storedRecovery.privateKeyBase64, "base64")), diff --git a/extensions/matrix-js/src/matrix/send/client.ts b/extensions/matrix-js/src/matrix/send/client.ts index 5a5cf71a391..de311aebfca 100644 --- a/extensions/matrix-js/src/matrix/send/client.ts +++ b/extensions/matrix-js/src/matrix/send/client.ts @@ -1,8 +1,9 @@ +import { normalizeAccountId } from "openclaw/plugin-sdk/account-id"; import { getMatrixRuntime } from "../../runtime.js"; +import type { CoreConfig } from "../../types.js"; import { getActiveMatrixClient } from "../active-client.js"; import { createMatrixClient, isBunRuntime, resolveMatrixAuth } from "../client.js"; import type { MatrixClient } from "../sdk.js"; -import type { CoreConfig } from "../types.js"; const getCore = () => getMatrixRuntime(); @@ -12,10 +13,20 @@ export function ensureNodeRuntime() { } } -export function resolveMediaMaxBytes(): number | undefined { +export function resolveMediaMaxBytes(accountId?: string | null): number | undefined { const cfg = getCore().config.loadConfig() as CoreConfig; - if (typeof cfg.channels?.["matrix-js"]?.mediaMaxMb === "number") { - return cfg.channels["matrix-js"].mediaMaxMb * 1024 * 1024; + const matrixCfg = cfg.channels?.["matrix-js"]; + const accountCfg = accountId + ? (matrixCfg?.accounts?.[accountId] ?? matrixCfg?.accounts?.[normalizeAccountId(accountId)]) + : undefined; + const mediaMaxMb = + typeof accountCfg?.mediaMaxMb === "number" + ? accountCfg.mediaMaxMb + : typeof matrixCfg?.mediaMaxMb === "number" + ? matrixCfg.mediaMaxMb + : undefined; + if (typeof mediaMaxMb === "number") { + return mediaMaxMb * 1024 * 1024; } return undefined; } diff --git a/extensions/matrix-js/src/matrix/send/targets.ts b/extensions/matrix-js/src/matrix/send/targets.ts index d0eb736a9b8..8d358ecf825 100644 --- a/extensions/matrix-js/src/matrix/send/targets.ts +++ b/extensions/matrix-js/src/matrix/send/targets.ts @@ -35,9 +35,11 @@ async function persistDirectRoom( userId: string, roomId: string, ): Promise { - let directContent: MatrixDirectAccountData | null = null; + let directContent: MatrixDirectAccountData | undefined; try { - directContent = await client.getAccountData(EventType.Direct); + directContent = (await client.getAccountData(EventType.Direct)) as + | MatrixDirectAccountData + | undefined; } catch { // Ignore fetch errors and fall back to an empty map. }