import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup"; // Matrix plugin module implements setup core behavior. import { DEFAULT_ACCOUNT_ID, normalizeAccountId, prepareScopedSetupConfig, type ChannelSetupAdapter, type ChannelSetupWizardAdapter, } from "openclaw/plugin-sdk/setup"; import { applyMatrixSetupAccountConfig, validateMatrixSetupInput } from "./setup-config.js"; import { namedAccountPromotionKeys, resolveSingleAccountPromotionTarget, singleAccountKeysToMove, } from "./setup-contract.js"; import { createMatrixSetupDmPolicy } from "./setup-dm-policy.js"; import type { CoreConfig } from "./types.js"; const channel = "matrix" as const; type MatrixSetupWizardModule = { matrixSetupWizard: ChannelSetupWizardAdapter }; function resolveMatrixSetupAccountId(params: { accountId?: string; name?: string }): string { return normalizeAccountId(params.accountId?.trim() || params.name?.trim() || DEFAULT_ACCOUNT_ID); } export function createMatrixSetupWizardProxy( loadWizardModule: () => Promise, ): ChannelSetupWizardAdapter { let wizardPromise: Promise | null = null; const loadWizard = () => { wizardPromise ??= loadWizardModule().then((module) => module.matrixSetupWizard); return wizardPromise; }; return { channel, getStatus: async (ctx) => await (await loadWizard()).getStatus(ctx), configure: async (ctx) => await (await loadWizard()).configure(ctx), configureInteractive: async (ctx) => { const wizard = await loadWizard(); return await (wizard.configureInteractive ?? wizard.configure)(ctx); }, configureWhenConfigured: async (ctx) => { const wizard = await loadWizard(); return await ( wizard.configureWhenConfigured ?? wizard.configureInteractive ?? wizard.configure )(ctx); }, afterConfigWritten: async (ctx) => await (await loadWizard()).afterConfigWritten?.(ctx), dmPolicy: createMatrixSetupDmPolicy(async (params) => { const promptAllowFrom = (await loadWizard()).dmPolicy?.promptAllowFrom; return promptAllowFrom ? await promptAllowFrom(params) : params.cfg; }), disable: (cfg) => ({ ...(cfg as CoreConfig), channels: { ...(cfg as CoreConfig).channels, matrix: { ...(cfg as CoreConfig).channels?.matrix, enabled: false }, }, }), }; } export const matrixSetupAdapter: ChannelSetupAdapter = { singleAccountKeysToMove, namedAccountPromotionKeys, resolveSingleAccountPromotionTarget, resolveAccountId: ({ accountId, input }) => resolveMatrixSetupAccountId({ accountId, name: input?.name, }), resolveBindingAccountId: ({ accountId, agentId }) => resolveMatrixSetupAccountId({ accountId, name: agentId, }), applyAccountName: ({ cfg, accountId, name }) => prepareScopedSetupConfig({ cfg: cfg as CoreConfig, channelKey: channel, accountId, name, }) as CoreConfig, validateInput: ({ accountId, input }) => validateMatrixSetupInput({ accountId, input }), applyAccountConfig: ({ cfg, accountId, input }) => applyMatrixSetupAccountConfig({ cfg: cfg as CoreConfig, accountId, input, }), afterAccountConfigWritten: async ({ previousCfg, cfg, accountId, runtime }) => { const { runMatrixSetupBootstrapAfterConfigWrite } = await import("./setup-bootstrap.js"); await runMatrixSetupBootstrapAfterConfigWrite({ previousCfg: previousCfg as CoreConfig, cfg: cfg as CoreConfig, accountId, runtime, }); }, }; export const matrixSetupContract = defineChannelSetupContract({ fields: { homeserver: { kind: "string", cli: { flags: "--homeserver ", description: "Matrix homeserver URL" }, }, userId: { kind: "string", cli: { flags: "--user-id ", description: "Matrix user id" } }, accessToken: { kind: "string", sensitive: true, cli: { flags: "--access-token ", description: "Matrix access token" }, }, password: { kind: "string", sensitive: true, cli: { flags: "--password ", description: "Matrix password" }, }, deviceName: { kind: "string", cli: { flags: "--device-name ", description: "Matrix device name" }, }, avatarUrl: { kind: "string", cli: { flags: "--avatar-url ", description: "Matrix avatar URL" }, }, initialSyncLimit: { kind: "integer", cli: { flags: "--initial-sync-limit ", description: "Matrix initial sync room limit" }, }, proxy: { kind: "string", cli: { flags: "--proxy ", description: "Matrix proxy URL" } }, dangerouslyAllowPrivateNetwork: { kind: "boolean", cli: { flags: "--dangerously-allow-private-network", description: "Allow private-network Matrix homeservers", }, }, useEnv: { kind: "boolean", cli: { flags: "--use-env", description: "Use Matrix environment credentials" }, }, }, legacyAdapter: matrixSetupAdapter, });