if (!params.legacyWebhook) {
warnings.push(
`Cron job "${jobName}" still uses legacy notify fallback, but cron.webhook is unset so doctor cannot migrate it automatically.`,
); continue;
}
warnings.push(
`Cron job "${jobName}" uses legacy notify fallback alongside delivery mode "${mode}". Migrate it manually so webhook delivery does not replace existing announce behavior.`,
);
}
return { changed, warnings };
}
export async function maybeRepairLegacyCronStore(params: {
cfg: OpenClawConfig;
options: DoctorOptions;
prompter: Pick<DoctorPrompter, "confirm">;
}) { const storePath = resolveCronStorePath(params.cfg.cron?.store); const store = await loadCronStore(storePath); const rawJobs = (store.jobs ?? []) as unknown as Array<Record<string, unknown>>; if (rawJobs.length === 0) { return;
}
const normalized = normalizeStoredCronJobs(rawJobs); const legacyWebhook = normalizeOptionalString(params.cfg.cron?.webhook); const notifyCount = rawJobs.filter((job) => job.notify === true).length; const dreamingStaleCount = countStaleDreamingJobs(rawJobs); const previewLines = formatLegacyIssuePreview(normalized.issues); if (notifyCount > 0) {
previewLines.push(
`- ${pluralize(notifyCount, "job")} still uses legacy \`notify: true\` webhook fallback`,
);
} if (dreamingStaleCount > 0) {
previewLines.push(
`- ${pluralize(dreamingStaleCount, "managed dreaming job")} still has the legacy heartbeat-coupled shape`,
);
} if (previewLines.length === 0) { return;
}
note(
[
`Legacy cron job storage detected at ${shortenHomePath(storePath)}.`,
...previewLines,
`Repair with ${formatCliCommand("openclaw doctor --fix")} to normalize the store before the next scheduler run.`,
].join("\n"), "Cron",
);
const shouldRepair = await params.prompter.confirm({
message: "Repair legacy cron jobs now?",
initialValue: true,
}); if (!shouldRepair) { return;
}
if (changed) {
await saveCronStore(storePath, {
version: 1,
jobs: rawJobs as unknown as CronJob[],
});
note(`Cron store normalized at ${shortenHomePath(storePath)}.`, "Doctor changes"); if (dreamingMigration.rewrittenCount > 0) {
note(
`Rewrote ${pluralize(dreamingMigration.rewrittenCount, "managed dreaming job")} to run as an isolated agent turn so dreaming no longer requires heartbeat.`, "Doctor changes",
);
}
}
if (notifyMigration.warnings.length > 0) {
note(notifyMigration.warnings.join("\n"), "Doctor warnings");
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.