mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
Doctor: fix non-interactive cron repair gating (#41386)
This commit is contained in:
@@ -155,4 +155,115 @@ describe("maybeRepairLegacyCronStore", () => {
|
||||
"Doctor warnings",
|
||||
);
|
||||
});
|
||||
|
||||
it("does not auto-repair in non-interactive mode without explicit repair approval", async () => {
|
||||
const storePath = await makeTempStorePath();
|
||||
await fs.mkdir(path.dirname(storePath), { recursive: true });
|
||||
await fs.writeFile(
|
||||
storePath,
|
||||
JSON.stringify(
|
||||
{
|
||||
version: 1,
|
||||
jobs: [
|
||||
{
|
||||
jobId: "legacy-job",
|
||||
name: "Legacy job",
|
||||
notify: true,
|
||||
createdAtMs: Date.parse("2026-02-01T00:00:00.000Z"),
|
||||
updatedAtMs: Date.parse("2026-02-02T00:00:00.000Z"),
|
||||
schedule: { kind: "cron", cron: "0 7 * * *", tz: "UTC" },
|
||||
payload: {
|
||||
kind: "systemEvent",
|
||||
text: "Morning brief",
|
||||
},
|
||||
state: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const noteSpy = vi.spyOn(noteModule, "note").mockImplementation(() => {});
|
||||
const prompter = makePrompter(false);
|
||||
|
||||
await maybeRepairLegacyCronStore({
|
||||
cfg: {
|
||||
cron: {
|
||||
store: storePath,
|
||||
webhook: "https://example.invalid/cron-finished",
|
||||
},
|
||||
},
|
||||
options: { nonInteractive: true },
|
||||
prompter,
|
||||
});
|
||||
|
||||
const persisted = JSON.parse(await fs.readFile(storePath, "utf-8")) as {
|
||||
jobs: Array<Record<string, unknown>>;
|
||||
};
|
||||
expect(prompter.confirm).toHaveBeenCalledWith({
|
||||
message: "Repair legacy cron jobs now?",
|
||||
initialValue: true,
|
||||
});
|
||||
expect(persisted.jobs[0]?.jobId).toBe("legacy-job");
|
||||
expect(persisted.jobs[0]?.notify).toBe(true);
|
||||
expect(noteSpy).not.toHaveBeenCalledWith(
|
||||
expect.stringContaining("Cron store normalized"),
|
||||
"Doctor changes",
|
||||
);
|
||||
});
|
||||
|
||||
it("migrates notify fallback none delivery jobs to cron.webhook", async () => {
|
||||
const storePath = await makeTempStorePath();
|
||||
await fs.mkdir(path.dirname(storePath), { recursive: true });
|
||||
await fs.writeFile(
|
||||
storePath,
|
||||
JSON.stringify(
|
||||
{
|
||||
version: 1,
|
||||
jobs: [
|
||||
{
|
||||
id: "notify-none",
|
||||
name: "Notify none",
|
||||
notify: true,
|
||||
createdAtMs: Date.parse("2026-02-01T00:00:00.000Z"),
|
||||
updatedAtMs: Date.parse("2026-02-02T00:00:00.000Z"),
|
||||
schedule: { kind: "every", everyMs: 60_000 },
|
||||
payload: {
|
||||
kind: "systemEvent",
|
||||
text: "Status",
|
||||
},
|
||||
delivery: { mode: "none", to: "123456789" },
|
||||
state: {},
|
||||
},
|
||||
],
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
await maybeRepairLegacyCronStore({
|
||||
cfg: {
|
||||
cron: {
|
||||
store: storePath,
|
||||
webhook: "https://example.invalid/cron-finished",
|
||||
},
|
||||
},
|
||||
options: {},
|
||||
prompter: makePrompter(true),
|
||||
});
|
||||
|
||||
const persisted = JSON.parse(await fs.readFile(storePath, "utf-8")) as {
|
||||
jobs: Array<Record<string, unknown>>;
|
||||
};
|
||||
expect(persisted.jobs[0]?.notify).toBeUndefined();
|
||||
expect(persisted.jobs[0]?.delivery).toMatchObject({
|
||||
mode: "webhook",
|
||||
to: "https://example.invalid/cron-finished",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -96,7 +96,7 @@ function migrateLegacyNotifyFallback(params: {
|
||||
raw.delivery = {
|
||||
...delivery,
|
||||
mode: "webhook",
|
||||
to: to ?? params.legacyWebhook,
|
||||
to: mode === "none" ? params.legacyWebhook : (to ?? params.legacyWebhook),
|
||||
};
|
||||
delete raw.notify;
|
||||
changed = true;
|
||||
@@ -152,13 +152,10 @@ export async function maybeRepairLegacyCronStore(params: {
|
||||
"Cron",
|
||||
);
|
||||
|
||||
const shouldRepair =
|
||||
params.options.nonInteractive === true
|
||||
? true
|
||||
: await params.prompter.confirm({
|
||||
message: "Repair legacy cron jobs now?",
|
||||
initialValue: true,
|
||||
});
|
||||
const shouldRepair = await params.prompter.confirm({
|
||||
message: "Repair legacy cron jobs now?",
|
||||
initialValue: true,
|
||||
});
|
||||
if (!shouldRepair) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user