Add scheduled task automation skill with worker execution pipeline.
Memind CI / Test, build, and release guards (push) Failing after 18s

Introduce scheduled-task-automation for H5 and WeChat, persist tasks in h5_scheduled_tasks, and run due jobs via a dedicated worker that executes agent tasks and delivers results.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-31 08:02:49 +08:00
parent 4186522c72
commit 81e63c16d3
27 changed files with 1736 additions and 2 deletions
+50
View File
@@ -113,6 +113,56 @@ export function zonedTimeToEpochMs(parts, timezone = DEFAULT_TIMEZONE) {
return guess;
}
export function nextWeeklyRunAt({
weekday,
hour,
minute = 0,
timezone = DEFAULT_TIMEZONE,
now = Date.now(),
} = {}) {
const tz = normalizeTimezone(timezone);
const safeWeekday = Number(weekday);
if (!Number.isInteger(safeWeekday) || safeWeekday < 0 || safeWeekday > 6) {
throw new Error('weekly 任务需要 weekday0=周日 … 6=周六)');
}
const todayStart = startOfLocalDay(now, tz);
const todayParts = getLocalParts(todayStart, tz);
const todayWeekday = new Date(
Date.UTC(todayParts.year, todayParts.month - 1, todayParts.day),
).getUTCDay();
const dayOffset = (safeWeekday - todayWeekday + 7) % 7;
let candidateDayStart = addLocalDays(todayStart, dayOffset, tz);
let parts = getLocalParts(candidateDayStart, tz);
let runAt = zonedTimeToEpochMs(
{
year: parts.year,
month: parts.month,
day: parts.day,
hour: Number(hour),
minute: Number(minute),
second: 0,
},
tz,
);
if (runAt <= now) {
candidateDayStart = addLocalDays(candidateDayStart, 7, tz);
parts = getLocalParts(candidateDayStart, tz);
runAt = zonedTimeToEpochMs(
{
year: parts.year,
month: parts.month,
day: parts.day,
hour: Number(hour),
minute: Number(minute),
second: 0,
},
tz,
);
}
return runAt;
}
export function nextDailyRunAt({ hour, minute = 0, timezone = DEFAULT_TIMEZONE, now = Date.now() }) {
const tz = normalizeTimezone(timezone);
const todayStart = startOfLocalDay(now, tz);