UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

171 lines (170 loc) 7.41 kB
import { c as isRecord } from "./utils-CCC-BEJH.js"; import { n as formatPluginInstallPathIssue, t as detectPluginInstallPathIssue } from "./plugin-install-path-warnings-DeqCJ89b.js"; import { s as removePluginFromConfig } from "./uninstall-e8GjmqkO.js"; import "./runtime-doctor-Bf2V8rFY.js"; import "./record-shared-BXlUig5f.js"; import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-pj2qdle9.js"; import { i as autoPrepareLegacyMatrixCrypto, o as autoMigrateLegacyMatrixState, r as resolveMatrixMigrationStatus } from "./matrix-migration.runtime.js"; import { t as maybeCreateMatrixMigrationSnapshot } from "./migration-snapshot-backup-B3kTguEe.js"; //#region extensions/matrix/src/doctor.ts function hasConfiguredMatrixChannel(cfg) { const channels = cfg.channels; return isRecord(channels?.matrix); } function hasConfiguredMatrixPluginSurface(cfg) { return Boolean(cfg.plugins?.installs?.matrix || cfg.plugins?.entries?.matrix || cfg.plugins?.allow?.includes("matrix") || cfg.plugins?.deny?.includes("matrix")); } function hasConfiguredMatrixEnv(env) { return Object.entries(env).some(([key, value]) => key.startsWith("MATRIX_") && typeof value === "string" && value.trim()); } function configMayNeedMatrixDoctorSequence(cfg, env) { return hasConfiguredMatrixChannel(cfg) || hasConfiguredMatrixPluginSurface(cfg) || hasConfiguredMatrixEnv(env); } function formatMatrixLegacyStatePreview(detection) { return [ "- Matrix plugin upgraded in place.", `- Legacy sync store: ${detection.legacyStoragePath} -> ${detection.targetStoragePath}`, `- Legacy crypto store: ${detection.legacyCryptoPath} -> ${detection.targetCryptoPath}`, ...detection.selectionNote ? [`- ${detection.selectionNote}`] : [], "- Run \"openclaw doctor --fix\" to migrate this Matrix state now." ].join("\n"); } function formatMatrixLegacyCryptoPreview(detection) { const notes = []; for (const warning of detection.warnings) notes.push(`- ${warning}`); for (const plan of detection.plans) notes.push([ `- Matrix encrypted-state migration is pending for account "${plan.accountId}".`, `- Legacy crypto store: ${plan.legacyCryptoPath}`, `- Recovery key state: Matrix SQLite state (imports ${plan.recoveryKeyPath} if present)`, `- Migration state: Matrix SQLite state (imports ${plan.statePath} if present)`, "- Run \"openclaw doctor --fix\" to extract any saved backup key now. Backed-up room keys will restore automatically on next gateway start." ].join("\n")); return notes; } async function collectMatrixInstallPathWarnings(cfg) { const issue = await detectPluginInstallPathIssue({ pluginId: "matrix", install: cfg.plugins?.installs?.matrix }); if (!issue) return []; return formatPluginInstallPathIssue({ issue, pluginLabel: "Matrix", defaultInstallCommand: "openclaw plugins install @openclaw/matrix" }).map((entry) => `- ${entry}`); } async function cleanStaleMatrixPluginConfig(cfg) { const issue = await detectPluginInstallPathIssue({ pluginId: "matrix", install: cfg.plugins?.installs?.matrix }); if (!issue || issue.kind !== "missing-path") return { config: cfg, changes: [] }; const { config, actions } = removePluginFromConfig(cfg, "matrix"); const removed = []; if (actions.install) removed.push("install record"); if (actions.loadPath) removed.push("load path"); if (actions.entry) removed.push("plugin entry"); if (actions.allowlist) removed.push("allowlist entry"); if (removed.length === 0) return { config: cfg, changes: [] }; return { config, changes: [`Removed stale Matrix plugin references (${removed.join(", ")}). The previous install path no longer exists: ${issue.path}`] }; } async function applyMatrixDoctorRepair(params) { const changes = []; const warnings = []; const migrationStatus = resolveMatrixMigrationStatus({ cfg: params.cfg, env: params.env }); let matrixSnapshotReady = true; if (migrationStatus.actionable) try { const snapshot = await maybeCreateMatrixMigrationSnapshot({ trigger: "doctor-fix", env: params.env }); changes.push(`Matrix migration snapshot ${snapshot.created ? "created" : "reused"} before applying Matrix upgrades.\n- ${snapshot.archivePath}`); } catch (error) { matrixSnapshotReady = false; warnings.push(`- Failed creating a Matrix migration snapshot before repair: ${String(error)}`); warnings.push("- Skipping Matrix migration changes for now. Resolve the snapshot failure, then rerun \"openclaw doctor --fix\"."); } else if (migrationStatus.pending) warnings.push("- Matrix migration warnings are present, but no on-disk Matrix mutation is actionable yet. No pre-migration snapshot was needed."); if (!matrixSnapshotReady) return { changes, warnings }; const matrixStateRepair = await autoMigrateLegacyMatrixState({ cfg: params.cfg, env: params.env }); if (matrixStateRepair.changes.length > 0) changes.push([ "Matrix plugin upgraded in place.", ...matrixStateRepair.changes.map((entry) => `- ${entry}`), "- No user action required." ].join("\n")); if (matrixStateRepair.warnings.length > 0) warnings.push(matrixStateRepair.warnings.map((entry) => `- ${entry}`).join("\n")); const matrixCryptoRepair = await autoPrepareLegacyMatrixCrypto({ cfg: params.cfg, env: params.env }); if (matrixCryptoRepair.changes.length > 0) changes.push(["Matrix encrypted-state migration prepared.", ...matrixCryptoRepair.changes.map((entry) => `- ${entry}`)].join("\n")); if (matrixCryptoRepair.warnings.length > 0) warnings.push(matrixCryptoRepair.warnings.map((entry) => `- ${entry}`).join("\n")); return { changes, warnings }; } async function runMatrixDoctorSequence(params) { const warningNotes = []; const changeNotes = []; const installWarnings = await collectMatrixInstallPathWarnings(params.cfg); if (installWarnings.length > 0) warningNotes.push(installWarnings.join("\n")); if (!configMayNeedMatrixDoctorSequence(params.cfg, params.env)) return { changeNotes, warningNotes }; if (params.shouldRepair) { const repair = await applyMatrixDoctorRepair({ cfg: params.cfg, env: params.env }); changeNotes.push(...repair.changes); warningNotes.push(...repair.warnings); } else { const migrationStatus = resolveMatrixMigrationStatus({ cfg: params.cfg, env: params.env }); if (migrationStatus.legacyState) if ("warning" in migrationStatus.legacyState) warningNotes.push(`- ${migrationStatus.legacyState.warning}`); else warningNotes.push(formatMatrixLegacyStatePreview(migrationStatus.legacyState)); if (migrationStatus.legacyCrypto.warnings.length > 0 || migrationStatus.legacyCrypto.plans.length > 0) warningNotes.push(...formatMatrixLegacyCryptoPreview(migrationStatus.legacyCrypto)); } return { changeNotes, warningNotes }; } const matrixDoctor = { dmAllowFromMode: "nestedOnly", groupModel: "sender", groupAllowFromFallbackToAllowFrom: false, warnOnEmptyGroupSenderAllowlist: true, legacyConfigRules, normalizeCompatibilityConfig, runConfigSequence: async ({ cfg, env, shouldRepair }) => await runMatrixDoctorSequence({ cfg, env, shouldRepair }), cleanStaleConfig: async ({ cfg }) => await cleanStaleMatrixPluginConfig(cfg) }; //#endregion export { applyMatrixDoctorRepair, cleanStaleMatrixPluginConfig, collectMatrixInstallPathWarnings, formatMatrixLegacyCryptoPreview, formatMatrixLegacyStatePreview, matrixDoctor, runMatrixDoctorSequence };