fix(config): detect top-level heartbeat as invalid config path (#30894) (#32706)

Merged via squash.

Prepared head SHA: 1714ffe6fc
Co-authored-by: xiwan <931632+xiwan@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
wan.xi
2026-03-04 09:27:04 +08:00
committed by GitHub
parent b7589b32a8
commit caa748b969
8 changed files with 398 additions and 10 deletions

View File

@@ -600,6 +600,67 @@ describe("doctor config flow", () => {
expectGoogleChatDmAllowFromRepaired(result.cfg);
});
it("migrates top-level heartbeat into agents.defaults.heartbeat on repair", async () => {
const result = await runDoctorConfigWithInput({
repair: true,
config: {
heartbeat: {
model: "anthropic/claude-3-5-haiku-20241022",
every: "30m",
},
},
run: loadAndMaybeMigrateDoctorConfig,
});
const cfg = result.cfg as {
heartbeat?: unknown;
agents?: {
defaults?: {
heartbeat?: {
model?: string;
every?: string;
};
};
};
};
expect(cfg.heartbeat).toBeUndefined();
expect(cfg.agents?.defaults?.heartbeat).toMatchObject({
model: "anthropic/claude-3-5-haiku-20241022",
every: "30m",
});
});
it("migrates top-level heartbeat visibility into channels.defaults.heartbeat on repair", async () => {
const result = await runDoctorConfigWithInput({
repair: true,
config: {
heartbeat: {
showOk: true,
showAlerts: false,
},
},
run: loadAndMaybeMigrateDoctorConfig,
});
const cfg = result.cfg as {
heartbeat?: unknown;
channels?: {
defaults?: {
heartbeat?: {
showOk?: boolean;
showAlerts?: boolean;
useIndicator?: boolean;
};
};
};
};
expect(cfg.heartbeat).toBeUndefined();
expect(cfg.channels?.defaults?.heartbeat).toMatchObject({
showOk: true,
showAlerts: false,
});
});
it("repairs googlechat account dm.policy open by setting dm.allowFrom on repair", async () => {
const result = await runDoctorConfigWithInput({
repair: true,