refactor(doctor): extract matrix sequencing (#52056)

This commit is contained in:
Vincent Koc 2026-03-21 21:10:48 -07:00 committed by GitHub
parent 4c9f411f6d
commit 60f559e217
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 90 additions and 42 deletions

View File

@ -2,19 +2,12 @@ import { formatCliCommand } from "../cli/command-format.js";
import type { OpenClawConfig } from "../config/config.js";
import { CONFIG_PATH } from "../config/config.js";
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
import { detectLegacyMatrixCrypto } from "../infra/matrix-legacy-crypto.js";
import { detectLegacyMatrixState } from "../infra/matrix-legacy-state.js";
import { note } from "../terminal/note.js";
import { noteOpencodeProviderOverrides } from "./doctor-config-analysis.js";
import { runDoctorConfigPreflight } from "./doctor-config-preflight.js";
import { normalizeCompatibilityConfigValues } from "./doctor-legacy-config.js";
import type { DoctorOptions } from "./doctor-prompter.js";
import {
applyMatrixDoctorRepair,
collectMatrixInstallPathWarnings,
formatMatrixLegacyCryptoPreview,
formatMatrixLegacyStatePreview,
} from "./doctor/providers/matrix.js";
import { runMatrixDoctorSequence } from "./doctor/providers/matrix.js";
import { runDoctorRepairSequence } from "./doctor/repair-sequencing.js";
import {
applyLegacyCompatibilityStep,
@ -82,44 +75,16 @@ export async function loadAndMaybeMigrateDoctorConfig(params: {
}));
}
const matrixLegacyState = detectLegacyMatrixState({
const matrixSequence = await runMatrixDoctorSequence({
cfg: candidate,
env: process.env,
shouldRepair,
});
const matrixLegacyCrypto = detectLegacyMatrixCrypto({
cfg: candidate,
env: process.env,
});
if (shouldRepair) {
const matrixRepair = await applyMatrixDoctorRepair({
cfg: candidate,
env: process.env,
});
for (const change of matrixRepair.changes) {
note(change, "Doctor changes");
}
for (const warning of matrixRepair.warnings) {
note(warning, "Doctor warnings");
}
} else if (matrixLegacyState) {
if ("warning" in matrixLegacyState) {
note(`- ${matrixLegacyState.warning}`, "Doctor warnings");
} else {
note(formatMatrixLegacyStatePreview(matrixLegacyState), "Doctor warnings");
}
for (const change of matrixSequence.changeNotes) {
note(change, "Doctor changes");
}
if (
!shouldRepair &&
(matrixLegacyCrypto.warnings.length > 0 || matrixLegacyCrypto.plans.length > 0)
) {
for (const preview of formatMatrixLegacyCryptoPreview(matrixLegacyCrypto)) {
note(preview, "Doctor warnings");
}
}
const matrixInstallWarnings = await collectMatrixInstallPathWarnings(candidate);
if (matrixInstallWarnings.length > 0) {
note(matrixInstallWarnings.join("\n"), "Doctor warnings");
for (const warning of matrixSequence.warningNotes) {
note(warning, "Doctor warnings");
}
const missingDefaultAccountBindingWarnings =

View File

@ -7,6 +7,7 @@ import {
collectMatrixInstallPathWarnings,
formatMatrixLegacyCryptoPreview,
formatMatrixLegacyStatePreview,
runMatrixDoctorSequence,
} from "./matrix.js";
vi.mock("../../../infra/matrix-migration-snapshot.js", () => ({
@ -137,4 +138,40 @@ describe("doctor matrix provider helpers", () => {
]);
expect(result.warnings).toEqual([]);
});
it("collects matrix preview and install warnings through the provider sequence", async () => {
const matrixStateModule = await import("../../../infra/matrix-legacy-state.js");
const matrixCryptoModule = await import("../../../infra/matrix-legacy-crypto.js");
const stateSpy = vi.spyOn(matrixStateModule, "detectLegacyMatrixState").mockReturnValue({
accountId: "default",
legacyStoragePath: "/tmp/legacy-sync.json",
targetStoragePath: "/tmp/new-sync.json",
legacyCryptoPath: "/tmp/legacy-crypto.json",
targetCryptoPath: "/tmp/new-crypto.json",
selectionNote: "Picked the newest account.",
targetRootDir: "/tmp/account-root",
});
const cryptoSpy = vi.spyOn(matrixCryptoModule, "detectLegacyMatrixCrypto").mockReturnValue({
warnings: ["matrix warning"],
plans: [],
});
try {
const result = await runMatrixDoctorSequence({
cfg: {},
env: process.env,
shouldRepair: false,
});
expect(result.changeNotes).toEqual([]);
expect(result.warningNotes).toEqual([
expect.stringContaining("Matrix plugin upgraded in place."),
"- matrix warning",
]);
} finally {
stateSpy.mockRestore();
cryptoSpy.mockRestore();
}
});
});

View File

@ -145,3 +145,49 @@ export async function applyMatrixDoctorRepair(params: {
return { changes, warnings };
}
export async function runMatrixDoctorSequence(params: {
cfg: OpenClawConfig;
env: NodeJS.ProcessEnv;
shouldRepair: boolean;
}): Promise<{ changeNotes: string[]; warningNotes: string[] }> {
const matrixLegacyState = detectLegacyMatrixState({
cfg: params.cfg,
env: params.env,
});
const matrixLegacyCrypto = detectLegacyMatrixCrypto({
cfg: params.cfg,
env: params.env,
});
const warningNotes: string[] = [];
const changeNotes: string[] = [];
if (params.shouldRepair) {
const matrixRepair = await applyMatrixDoctorRepair({
cfg: params.cfg,
env: params.env,
});
changeNotes.push(...matrixRepair.changes);
warningNotes.push(...matrixRepair.warnings);
} else if (matrixLegacyState) {
if ("warning" in matrixLegacyState) {
warningNotes.push(`- ${matrixLegacyState.warning}`);
} else {
warningNotes.push(formatMatrixLegacyStatePreview(matrixLegacyState));
}
}
if (
!params.shouldRepair &&
(matrixLegacyCrypto.warnings.length > 0 || matrixLegacyCrypto.plans.length > 0)
) {
warningNotes.push(...formatMatrixLegacyCryptoPreview(matrixLegacyCrypto));
}
const matrixInstallWarnings = await collectMatrixInstallPathWarnings(params.cfg);
if (matrixInstallWarnings.length > 0) {
warningNotes.push(matrixInstallWarnings.join("\n"));
}
return { changeNotes, warningNotes };
}