@cronwatch/sdk 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/bugsnag.cjs +11 -1
  2. package/dist/bugsnag.cjs.map +1 -1
  3. package/dist/bugsnag.js +11 -1
  4. package/dist/bugsnag.js.map +1 -1
  5. package/dist/datadog.cjs +11 -1
  6. package/dist/datadog.cjs.map +1 -1
  7. package/dist/datadog.js +11 -1
  8. package/dist/datadog.js.map +1 -1
  9. package/dist/discord.cjs +13 -1
  10. package/dist/discord.cjs.map +1 -1
  11. package/dist/discord.js +13 -1
  12. package/dist/discord.js.map +1 -1
  13. package/dist/honeybadger.cjs +11 -1
  14. package/dist/honeybadger.cjs.map +1 -1
  15. package/dist/honeybadger.js +11 -1
  16. package/dist/honeybadger.js.map +1 -1
  17. package/dist/index.cjs +776 -134
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.js +776 -134
  20. package/dist/index.js.map +1 -1
  21. package/dist/mailgun.cjs +11 -1
  22. package/dist/mailgun.cjs.map +1 -1
  23. package/dist/mailgun.js +11 -1
  24. package/dist/mailgun.js.map +1 -1
  25. package/dist/newrelic.cjs +11 -1
  26. package/dist/newrelic.cjs.map +1 -1
  27. package/dist/newrelic.js +11 -1
  28. package/dist/newrelic.js.map +1 -1
  29. package/dist/postmark.cjs +11 -1
  30. package/dist/postmark.cjs.map +1 -1
  31. package/dist/postmark.js +11 -1
  32. package/dist/postmark.js.map +1 -1
  33. package/dist/resend.cjs +11 -1
  34. package/dist/resend.cjs.map +1 -1
  35. package/dist/resend.js +11 -1
  36. package/dist/resend.js.map +1 -1
  37. package/dist/rollbar.cjs +11 -1
  38. package/dist/rollbar.cjs.map +1 -1
  39. package/dist/rollbar.js +11 -1
  40. package/dist/rollbar.js.map +1 -1
  41. package/dist/sendgrid.cjs +11 -1
  42. package/dist/sendgrid.cjs.map +1 -1
  43. package/dist/sendgrid.js +11 -1
  44. package/dist/sendgrid.js.map +1 -1
  45. package/dist/sentry.cjs +11 -1
  46. package/dist/sentry.cjs.map +1 -1
  47. package/dist/sentry.js +11 -1
  48. package/dist/sentry.js.map +1 -1
  49. package/dist/ses.cjs +11 -1
  50. package/dist/ses.cjs.map +1 -1
  51. package/dist/ses.js +11 -1
  52. package/dist/ses.js.map +1 -1
  53. package/dist/slack.cjs +13 -1
  54. package/dist/slack.cjs.map +1 -1
  55. package/dist/slack.js +13 -1
  56. package/dist/slack.js.map +1 -1
  57. package/dist/twilio.cjs +11 -1
  58. package/dist/twilio.cjs.map +1 -1
  59. package/dist/twilio.js +11 -1
  60. package/dist/twilio.js.map +1 -1
  61. package/dist/webhook.cjs +13 -1
  62. package/dist/webhook.cjs.map +1 -1
  63. package/dist/webhook.js +13 -1
  64. package/dist/webhook.js.map +1 -1
  65. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/duration.ts","../src/env.ts","../src/schedule.ts","../src/stats.ts","../src/evaluate.ts","../src/format.ts","../src/http.ts","../src/output.ts","../src/job.ts","../src/serialize.ts","../src/routes/html.ts","../src/routes/index.ts","../src/stores/memory.ts","../src/client.ts","../src/index.ts"],"names":["Cron","graceMs","tail"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Duration } from \"./types.js\";\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\n/**\n * \"15m\" -> 900000. Accepts a plain number of milliseconds, and compound\n * strings such as \"1h30m\". Whitespace between parts is fine.\n */\nexport function parseDuration(value: Duration, label = \"duration\"): number {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value) || value < 0) throw new Error(`${label} must be a non-negative number of milliseconds`);\n return value;\n }\n const text = value.trim().toLowerCase();\n if (text === \"\") throw new Error(`${label} is empty`);\n const re = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g;\n let total = 0;\n let consumed = \"\";\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n total += parseFloat(match[1]!) * UNIT_MS[match[2]!]!;\n consumed += match[0];\n }\n if (consumed.replace(/\\s+/g, \"\") !== text.replace(/\\s+/g, \"\")) {\n throw new Error(`${label} \"${value}\" is not a duration like \"15m\", \"1h30m\" or \"90s\"`);\n }\n return Math.round(total);\n}\n\n/** 90000 -> \"1m 30s\". For messages, not for parsing back. */\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) return \"?\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const parts: string[] = [];\n let rest = Math.round(ms / 1000);\n const units: [string, number][] = [[\"d\", 86_400], [\"h\", 3_600], [\"m\", 60], [\"s\", 1]];\n for (const [unit, size] of units) {\n if (rest >= size) {\n const n = Math.floor(rest / size);\n rest -= n * size;\n parts.push(`${n}${unit}`);\n }\n if (parts.length === 2) break;\n }\n return parts.join(\" \") || \"0s\";\n}\n\n/** \"5 minutes ago\", \"in 2h\". Relative to `now`. */\nexport function formatRelative(at: number, now: number): string {\n const diff = at - now;\n const abs = Math.abs(diff);\n const text = abs < 5_000 ? \"now\" : formatDuration(abs);\n if (abs < 5_000) return text;\n return diff < 0 ? `${text} ago` : `in ${text}`;\n}\n","/**\n * Environment variables, read only where there is a `process` to read them\n * from. Cloudflare Workers without nodejs_compat have none: there every value\n * comes from the options, which is where a Worker passes its env bindings.\n */\nexport function readEnv(name: string): string | undefined {\n return typeof process === \"undefined\" || !process.env ? undefined : process.env[name];\n}\n\n/** NODE_ENV is \"development\" or \"test\". Written out in full so bundlers that inline process.env.NODE_ENV still can. */\nexport function isDevelopment(): boolean {\n if (typeof process === \"undefined\" || !process.env) return false;\n const mode = process.env.NODE_ENV;\n return mode === \"development\" || mode === \"test\";\n}\n","import { Cron } from \"croner\";\nimport { parseDuration } from \"./duration.js\";\n\nexport interface ParsedSchedule {\n kind: \"cron\" | \"interval\";\n source: string;\n /** The IANA timezone a cron is read in, when one was given. */\n timezone?: string;\n /** For intervals, the period in milliseconds. */\n everyMs?: number;\n}\n\nconst cache = new Map<string, ParsedSchedule>();\n/** The croner instance behind each cron schedule, kept out of the public type. */\nconst crons = new WeakMap<ParsedSchedule, Cron>();\n\n/** How early a run may start and still count for the fire it was meant for. */\nexport const EARLY_SLACK_MS = 60_000;\n\n/**\n * \"0 2 * * *\" (cron, five or six fields), \"@hourly\", or \"every 5m\".\n * Parsed once per (schedule, timezone) pair and cached. The croner instance\n * gets no callback, so it schedules nothing; it is only used to compute fire\n * times. Without a timezone the expression is read in the process timezone,\n * like crontab. Vercel and GitHub Actions run their crons in UTC, so pass\n * timezone: \"UTC\" for those.\n */\nexport function parseSchedule(schedule: string, timezone?: string): ParsedSchedule {\n const key = `${timezone ?? \"\"}|${schedule}`;\n const hit = cache.get(key);\n if (hit) return hit;\n\n const text = schedule.trim();\n const every = /^every\\s+(.+)$/i.exec(text);\n let parsed: ParsedSchedule;\n if (every) {\n const everyMs = parseDuration(every[1]!, \"schedule interval\");\n if (everyMs < 1000) throw new Error(`schedule \"${schedule}\" is shorter than one second`);\n parsed = { kind: \"interval\", source: text, everyMs };\n } else {\n let cron: Cron;\n try {\n cron = new Cron(text, timezone ? { timezone } : {});\n } catch (error) {\n throw new Error(`schedule \"${schedule}\" is not a cron expression or \"every <duration>\": ${(error as Error).message}`);\n }\n parsed = { kind: \"cron\", source: text, ...(timezone ? { timezone } : {}) };\n crons.set(parsed, cron);\n }\n cache.set(key, parsed);\n return parsed;\n}\n\n/**\n * The first fire strictly after `from`, or null when the cron never fires\n * again. croner answers with times in the past when asked from inside the\n * hour that repeats when clocks go back, so its answers are filtered, and a\n * stretch of nothing but past times is stepped over an hour at a time.\n */\nfunction fireAfter(parsed: ParsedSchedule, from: number): number | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n let probe = from;\n for (let attempt = 0; attempt < 4; attempt++) {\n const runs = cron.nextRuns(8, new Date(probe));\n if (runs.length === 0) return null;\n const found = runs.find((d) => d.getTime() > from);\n if (found) return found.getTime();\n probe += 3_600_000;\n }\n return null;\n}\n\n/** The next time the schedule fires strictly after `from`. For an interval, counted from the last run when there is one. */\nexport function nextFire(parsed: ParsedSchedule, from: number, lastRunAt: number | null): number | null {\n if (parsed.kind === \"interval\") {\n const base = lastRunAt ?? from;\n return base + parsed.everyMs!;\n }\n return fireAfter(parsed, from);\n}\n\nexport interface Expectation {\n /** When the next run the schedule asks for is due. */\n dueAt: number;\n /** Missed once now passes this. */\n deadline: number;\n}\n\n/**\n * When the schedule next wants a run, given the last one. For a cron that is\n * the first fire the last run does not already cover; with no run yet, the\n * first fire at or after registration. For an interval it is the last run's\n * start (or registration) plus the interval. Null for a cron that never\n * fires again.\n *\n * Counting forward from the last run, rather than back from now, is what\n * lets a job whose period is shorter than its grace be missed at all, and it\n * works for a cron that fires once a year or less.\n */\nexport function expectation(\n parsed: ParsedSchedule,\n lastRunAt: number | null,\n registeredAt: number,\n graceMs: number,\n): Expectation | null {\n let dueAt: number | null;\n if (parsed.kind === \"interval\") {\n dueAt = (lastRunAt ?? registeredAt) + parsed.everyMs!;\n } else if (lastRunAt === null) {\n dueAt = fireAfter(parsed, registeredAt - 1);\n } else {\n dueAt = dueAfterRun(parsed, lastRunAt);\n }\n return dueAt === null ? null : { dueAt, deadline: dueAt + graceMs };\n}\n\n/** The first fire that a run starting at `startedAt` does not cover. */\nfunction dueAfterRun(parsed: ParsedSchedule, startedAt: number): number | null {\n // A fire at or before the start is covered by the run itself.\n const next = fireAfter(parsed, startedAt);\n if (next === null) return null;\n const following = fireAfter(parsed, next);\n const covers = runCovers(startedAt, next, following) || inSpringForwardGap(parsed, startedAt, next);\n return covers ? following : next;\n}\n\n/**\n * Whether a run starting at `startedAt` covers the fire at `dueAt`. A minute\n * of slack before the tick absorbs schedulers that fire a touch early. When\n * the fire after `dueAt` is known, the slack is at most half the gap between\n * the two, so one run of an every-minute cron never covers two fires.\n */\nexport function runCovers(startedAt: number, dueAt: number, followingAt: number | null = null): boolean {\n const slack = followingAt === null ? EARLY_SLACK_MS : Math.min(EARLY_SLACK_MS, Math.floor((followingAt - dueAt) / 2));\n return startedAt >= dueAt - slack;\n}\n\n/**\n * On the night clocks spring forward, a fire whose local time does not exist\n * (02:30 when 02:00 jumps to 03:00) is moved by croner to the same distance\n * past the jump (03:30), while vixie cron runs it at the jump itself (03:00).\n * A run that starts at or after the jump, and before the first fire after\n * it when that fire lies within one gap of it, is taken to cover that fire,\n * so neither scheduler's run is reported as missed. A cron that really fires\n * at 03:30 that night is treated the same way, which only matters if it also\n * ran early by up to an hour.\n */\nfunction inSpringForwardGap(parsed: ParsedSchedule, startedAt: number, fireAt: number): boolean {\n const LOOKBACK = 3 * 3_600_000;\n const after = utcOffset(fireAt, parsed.timezone);\n const before = utcOffset(fireAt - LOOKBACK, parsed.timezone);\n const gap = after - before;\n if (gap <= 0) return false;\n // Find the jump: the first minute in the window with the later offset.\n let lo = fireAt - LOOKBACK;\n let hi = fireAt;\n while (hi - lo > 60_000) {\n const mid = lo + Math.floor((hi - lo) / 2);\n if (utcOffset(mid, parsed.timezone) === after) hi = mid;\n else lo = mid;\n }\n const jumpAt = Math.floor(hi / 60_000) * 60_000;\n if (fireAt - jumpAt >= gap || startedAt < jumpAt - EARLY_SLACK_MS || startedAt >= fireAt) return false;\n // Only the first fire after the jump can be a moved one; a cron that also\n // fires at the jump (every 10 minutes, say) was not moved at all.\n return fireAfter(parsed, jumpAt - 1) === fireAt;\n}\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\n/** Milliseconds the zone's wall clock is ahead of UTC at `at`. */\nfunction utcOffset(at: number, timezone: string | undefined): number {\n const key = timezone ?? \"\";\n let format = formatters.get(key);\n if (!format) {\n format = new Intl.DateTimeFormat(\"en-US\", {\n ...(timezone ? { timeZone: timezone } : {}),\n hourCycle: \"h23\",\n year: \"numeric\", month: \"numeric\", day: \"numeric\", hour: \"numeric\", minute: \"numeric\", second: \"numeric\",\n });\n formatters.set(key, format);\n }\n const parts: Record<string, number> = {};\n for (const part of format.formatToParts(new Date(at))) {\n if (part.type !== \"literal\") parts[part.type] = Number(part.value);\n }\n const wall = Date.UTC(parts.year!, parts.month! - 1, parts.day!, parts.hour!, parts.minute!, parts.second!);\n return wall - Math.floor(at / 1000) * 1000;\n}\n","export function percentile(values: number[], p: number): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));\n return sorted[index]!;\n}\n\nexport function median(values: number[]): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n","/**\n * Pure decisions about a job's health. Each function takes the current state\n * and returns the new state plus the alerts that should go out. Nothing here\n * touches a store or a network, which is what makes it testable.\n */\nimport { formatDuration } from \"./duration.js\";\nimport { parseDuration } from \"./duration.js\";\nimport { expectation, nextFire, parseSchedule } from \"./schedule.js\";\nimport { median, percentile } from \"./stats.js\";\nimport type {\n AlertDraft,\n BudgetBreach,\n Condition,\n JobDefinition,\n JobHealth,\n JobState,\n JobSummary,\n Run,\n StoredJob,\n StoredJobDefinition,\n} from \"./types.js\";\n\nexport type { AlertDraft, BudgetBreach };\n\nexport interface Evaluation {\n state: JobState;\n alerts: AlertDraft[];\n}\n\nexport const DEFAULT_GRACE_MS = 10 * 60_000;\nexport const DEFAULT_TIMEOUT_MS = 60 * 60_000;\n/** Runs faster than this are never called slow, whatever the baseline says. */\nexport const SLOW_FLOOR_MS = 10_000;\n/** How many earlier runs a baseline needs before it is trusted. */\nexport const BASELINE_MIN_RUNS = 5;\n/** How many successful runs a baseline looks at, and how many runs a summary covers. */\nexport const BASELINE_WINDOW = 20;\n\nexport function emptyState(job: string): JobState {\n return { job, open: {}, consecutiveFailures: 0, silencedUntil: null, lastAlertAt: null, pendingRecovery: [], undelivered: [] };\n}\n\n/** A stored state with every field present, or a fresh one. State written by an older version lacks the newer fields. */\nexport function normalizeState(state: JobState | null, job: string): JobState {\n if (!state) return emptyState(job);\n return {\n ...emptyState(job),\n ...state,\n open: { ...state.open },\n pendingRecovery: [...(state.pendingRecovery ?? [])],\n undelivered: [...(state.undelivered ?? [])],\n };\n}\n\nfunction cloneState(state: JobState): JobState {\n return normalizeState(state, state.job);\n}\n\nfunction openCondition(state: JobState, condition: Condition, now: number): boolean {\n if (state.open[condition] !== undefined) return false;\n state.open[condition] = now;\n return true;\n}\n\n/**\n * Every open condition has alerted, so closing one owes a recovered message.\n * It is remembered until a successful run leaves nothing open and sends it.\n */\nfunction closeCondition(state: JobState, condition: Condition): boolean {\n if (state.open[condition] === undefined) return false;\n delete state.open[condition];\n const pending = (state.pendingRecovery ??= []);\n if (!pending.includes(condition)) pending.push(condition);\n return true;\n}\n\nexport function openConditions(state: JobState): Condition[] {\n return Object.keys(state.open) as Condition[];\n}\n\nexport function graceMs(def: Pick<JobDefinition, \"grace\">): number {\n return def.grace === undefined ? DEFAULT_GRACE_MS : parseDuration(def.grace, \"grace\");\n}\n\nexport function timeoutMs(def: Pick<JobDefinition, \"timeout\">): number {\n return def.timeout === undefined ? DEFAULT_TIMEOUT_MS : parseDuration(def.timeout, \"timeout\");\n}\n\n/** Slow threshold for a successful run, or null when there is nothing to compare against yet. */\nexport function slowThreshold(def: Pick<JobDefinition, \"maxDuration\">, history: Run[]): { thresholdMs: number; basis: string } | null {\n if (def.maxDuration !== undefined) {\n return { thresholdMs: parseDuration(def.maxDuration, \"maxDuration\"), basis: \"maxDuration\" };\n }\n const durations = history\n .filter((r) => r.status === \"ok\" && r.durationMs !== null)\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.durationMs!);\n if (durations.length < BASELINE_MIN_RUNS) return null;\n const p95 = percentile(durations, 95)!;\n return { thresholdMs: Math.max(2 * p95, SLOW_FLOOR_MS), basis: `twice the p95 of the last ${durations.length} runs (${formatDuration(p95)})` };\n}\n\nexport function budgetBreaches(def: Pick<JobDefinition, \"budget\">, run: Run, history: Run[]): BudgetBreach[] {\n const breaches: BudgetBreach[] = [];\n for (const [metric, value] of Object.entries(run.metrics)) {\n const ceiling = def.budget?.[metric];\n if (ceiling !== undefined) {\n if (value > ceiling) breaches.push({ metric, value, limit: ceiling, basis: \"budget\" });\n continue;\n }\n const past = history\n .filter((r) => r.status === \"ok\" && typeof r.metrics[metric] === \"number\")\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.metrics[metric]!);\n if (past.length < BASELINE_MIN_RUNS) continue;\n const usual = median(past)!;\n if (usual > 0 && value > 3 * usual) {\n breaches.push({ metric, value, limit: 3 * usual, basis: `three times the usual ${formatNumber(usual)}` });\n }\n }\n return breaches;\n}\n\n/** Whether `history` (newest first) holds a full baseline window of successful runs. */\nexport function hasFullBaseline(history: Run[]): boolean {\n return history.filter((r) => r.status === \"ok\").length >= BASELINE_WINDOW;\n}\n\nexport function formatNumber(n: number): string {\n if (Number.isInteger(n)) return n.toLocaleString(\"en-US\");\n return n.toLocaleString(\"en-US\", { maximumFractionDigits: 4 });\n}\n\n/**\n * Called when a run starts. Missed and stuck are about the absence of a run,\n * so a run starting closes them without an alert; the recovered message\n * waits for a successful finish.\n */\nexport function onRunStart(state: JobState): JobState {\n const next = cloneState(state);\n closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n return next;\n}\n\n/**\n * Called when a run finishes with status ok, failed or timeout. `history` is\n * the job's earlier runs, newest first, not including this one.\n */\nexport function onRunFinish(\n def: JobDefinition | StoredJobDefinition,\n run: Run,\n state: JobState,\n history: Run[],\n now: number,\n): Evaluation {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n\n if (run.status === \"ok\") {\n next.consecutiveFailures = 0;\n closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n closeCondition(next, \"failed\");\n\n const slow = slowThreshold(def, history);\n if (slow && run.durationMs !== null && run.durationMs > slow.thresholdMs) {\n if (openCondition(next, \"slow\", now)) {\n alerts.push({ type: \"slow\", run, details: { durationMs: run.durationMs, thresholdMs: slow.thresholdMs, basis: slow.basis } });\n }\n } else {\n closeCondition(next, \"slow\");\n }\n\n const breaches = budgetBreaches(def, run, history);\n if (breaches.length > 0) {\n if (openCondition(next, \"over_budget\", now)) {\n alerts.push({ type: \"over_budget\", run, details: { breaches } });\n }\n } else {\n closeCondition(next, \"over_budget\");\n }\n\n const pending = next.pendingRecovery ?? [];\n if (pending.length > 0 && openConditions(next).length === 0) {\n alerts.push({ type: \"recovered\", run, details: { after: [...pending] } });\n next.pendingRecovery = [];\n }\n return { state: next, alerts };\n }\n\n // failed or timeout\n next.consecutiveFailures += 1;\n closeCondition(next, \"missed\");\n const threshold = Math.max(1, def.failuresBeforeAlert ?? 1);\n const condition = run.status === \"timeout\" ? \"stuck\" : \"failed\";\n if (next.consecutiveFailures >= threshold) {\n if (openCondition(next, condition, now)) {\n alerts.push({ type: condition, run, details: { consecutiveFailures: next.consecutiveFailures, threshold } });\n }\n }\n return { state: next, alerts };\n}\n\n/**\n * Called by check(). Decides whether the schedule has been missed: the run\n * the schedule wants next (see expectation()) has not started and its grace\n * has run out. `lastRun` is the most recent run of any status. A job with no\n * schedule is never missed, and one whose schedule was removed while missed\n * was open gets a recovered alert (reason \"unscheduled\") for missed alone.\n */\nexport function onCheck(\n def: StoredJobDefinition,\n stored: StoredJob,\n lastRun: Run | null,\n state: JobState,\n now: number,\n): Evaluation & { nextExpectedAt: number | null; dueAt: number | null } {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n if (!def.schedule) {\n const since = next.open.missed;\n if (since !== undefined) {\n // The schedule went away while missed was open (the job was declared\n // again without one, or a source retired it), so nothing is due any\n // more. Missed closes now with a recovery of its own; other open\n // conditions keep their own rules. Missed is taken out of the pending\n // recovery too, so the next successful run does not name it again.\n delete next.open.missed;\n next.pendingRecovery = (next.pendingRecovery ?? []).filter((c) => c !== \"missed\");\n alerts.push({ type: \"recovered\", run: lastRun, details: { after: [\"missed\"], reason: \"unscheduled\", since } });\n }\n return { state: next, alerts, nextExpectedAt: null, dueAt: null };\n }\n\n const parsed = parseSchedule(def.schedule, def.timezone);\n const grace = graceMs(def);\n const lastRunAt = lastRun?.startedAt ?? null;\n const exp = expectation(parsed, lastRunAt, stored.createdAt, grace);\n const nextExpectedAt = parsed.kind === \"interval\" ? nextFire(parsed, stored.createdAt, lastRunAt) : nextFire(parsed, now, null);\n if (!exp) return { state: next, alerts, nextExpectedAt, dueAt: null };\n\n // An interval's next run is due a period after the last one started. If that\n // run is still going, the job is busy, not late; stuck covers one that never ends.\n if (parsed.kind === \"interval\" && lastRun?.status === \"running\") {\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n }\n\n if (now > exp.deadline) {\n if (openCondition(next, \"missed\", now)) {\n alerts.push({ type: \"missed\", run: lastRun, details: { dueAt: exp.dueAt, deadline: exp.deadline, graceMs: grace, lastRunAt } });\n }\n } else {\n // A run has started since it opened, or the grace was widened.\n closeCondition(next, \"missed\");\n }\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n}\n\n/** Whether a running run has gone on longer than the job's timeout. */\nexport function isStuck(def: Pick<JobDefinition, \"timeout\">, run: Run, now: number): boolean {\n return run.status === \"running\" && now - run.startedAt > timeoutMs(def);\n}\n\n/**\n * While a job is silenced nothing new is recorded as an incident: conditions\n * may close (so a job that recovered during the silence shows as healthy) but\n * none may open, so the first problem after the silence ends alerts normally.\n */\nexport function muteOpens(previous: JobState, next: JobState): JobState {\n const muted = cloneState(next);\n for (const condition of openConditions(muted)) {\n if (previous.open[condition] === undefined) delete muted.open[condition];\n }\n return muted;\n}\n\nexport function isSilenced(state: JobState, now: number): boolean {\n return state.silencedUntil !== null && state.silencedUntil > now;\n}\n\n/**\n * An evaluation as it is saved and sent: while the job was silenced when it\n * began, nothing opens and nothing is sent.\n */\nexport function applySilence(previous: JobState, evaluation: Evaluation, now: number): Evaluation {\n if (!isSilenced(previous, now)) return evaluation;\n return { state: muteOpens(previous, evaluation.state), alerts: [] };\n}\n\n/**\n * Whether an alert waiting to be retried no longer describes the job, so it\n * is dropped rather than sent late. An alert for a condition is stale once\n * that condition has closed, or has closed and opened again (it opened at a\n * time other than the alert's). A recovery is stale when any condition it\n * names is open again; while they all stay closed it is kept.\n */\nexport function staleAlert(alert: AlertDraft & { at: number }, state: JobState): boolean {\n if (alert.type === \"recovered\") return alert.details.after.some((condition) => state.open[condition] !== undefined);\n return state.open[alert.type] !== alert.at;\n}\n\n/** How a job looks at a glance. Silence wins, then stuck, failing and late. */\nexport function jobHealth(def: Pick<JobDefinition, \"timeout\">, lastRun: Run | null, state: JobState, now: number): JobHealth {\n const open = openConditions(state);\n if (isSilenced(state, now)) return \"silenced\";\n if (open.includes(\"stuck\") || (lastRun && isStuck(def, lastRun, now))) return \"stuck\";\n if (open.includes(\"failed\") || lastRun?.status === \"failed\" || lastRun?.status === \"timeout\") return \"failing\";\n if (open.includes(\"missed\")) return \"late\";\n if (!lastRun) return \"never_ran\";\n return \"healthy\";\n}\n\n/**\n * A job's summary from its most recent runs (newest first; the first\n * BASELINE_WINDOW are used) and its state. Stats cover runs of any status;\n * the percentiles are over the successful ones among them.\n */\nexport function summarize(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, now: number): JobSummary {\n return summary(stored, recent, state, nextExpectedAt, (lastRun) => jobHealth(stored.definition, lastRun, state, now));\n}\n\n/**\n * The summary of a job that could not be evaluated, say because its stored\n * schedule no longer parses. It reads nothing from the definition. The job\n * shows as failing (or silenced, while it is), since it needs a look, and\n * nothing is known about when it is next due.\n */\nexport function unevaluableSummary(stored: StoredJob, recent: Run[], state: JobState, now: number): JobSummary {\n return summary(stored, recent, state, null, () => (isSilenced(state, now) ? \"silenced\" : \"failing\"));\n}\n\nfunction summary(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, health: (lastRun: Run | null) => JobHealth): JobSummary {\n const window = recent.slice(0, BASELINE_WINDOW);\n const lastRun = window[0] ?? null;\n const finished = window.filter((r) => r.status !== \"running\");\n const okDurations = window.filter((r) => r.status === \"ok\" && r.durationMs !== null).map((r) => r.durationMs!);\n return {\n name: stored.name,\n definition: stored.definition,\n health: health(lastRun),\n open: openConditions(state),\n lastRun,\n nextExpectedAt,\n consecutiveFailures: state.consecutiveFailures,\n silencedUntil: state.silencedUntil,\n stats: {\n runs: finished.length,\n okRate: finished.length === 0 ? 1 : finished.filter((r) => r.status === \"ok\").length / finished.length,\n p50Ms: percentile(okDurations, 50),\n p95Ms: percentile(okDurations, 95),\n },\n };\n}\n","import { formatDuration, formatRelative } from \"./duration.js\";\nimport { formatNumber } from \"./evaluate.js\";\nimport type { Alert, AlertDraft, StoredJobDefinition } from \"./types.js\";\n\nfunction when(at: number | null | undefined, now: number): string {\n if (at === null || at === undefined) return \"never\";\n return `${new Date(at).toISOString().replace(\"T\", \" \").slice(0, 19)} UTC (${formatRelative(at, now)})`;\n}\n\nfunction firstLines(text: string | null, n: number): string {\n if (!text) return \"\";\n return text.split(\"\\n\").slice(0, n).join(\"\\n\");\n}\n\nfunction tail(text: string | null, n: number): string {\n if (!text) return \"\";\n const lines = text.trimEnd().split(\"\\n\");\n return lines.slice(Math.max(0, lines.length - n)).join(\"\\n\");\n}\n\n/** \"Error: x\" for a bare message, but not \"Error: TypeError: x\" for one that already names itself. */\nfunction errorLine(error: string): string {\n const text = firstLines(error, 4);\n return /^[A-Za-z_$][\\w$]*: /.test(text) ? text : `Error: ${text}`;\n}\n\n/** Turns a draft into the title and message every channel shows. */\nexport function composeAlert(draft: AlertDraft, def: StoredJobDefinition, now: number): Alert {\n const name = def.name;\n const run = draft.run;\n let title: string;\n const lines: string[] = [];\n\n switch (draft.type) {\n case \"missed\": {\n const d = draft.details;\n title = `${name} missed its scheduled run`;\n lines.push(`Due ${when(d.dueAt, now)}, and no run had started by ${when(d.deadline, now)} (grace ${formatDuration(d.graceMs)}).`);\n lines.push(`Schedule: ${def.schedule}${def.timezone ? ` (${def.timezone})` : \"\"}.`);\n lines.push(`Last run: ${run ? `${run.status} ${when(run.startedAt, now)}` : \"never\"}.`);\n break;\n }\n case \"failed\": {\n title = `${name} failed`;\n const n = draft.details.consecutiveFailures;\n if (n > 1) lines.push(`${n} consecutive failures.`);\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)}${run.durationMs !== null ? `, ran ${formatDuration(run.durationMs)}` : \"\"}.`);\n if (run.error) lines.push(errorLine(run.error));\n const out = tail(run.output, 8);\n if (out) lines.push(`Output (tail):\\n${out}`);\n }\n break;\n }\n case \"stuck\": {\n title = `${name} is stuck`;\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)} and never reported finishing. Marked as timed out after ${formatDuration(run.durationMs ?? now - run.startedAt)}.`);\n const out = tail(run.output, 8);\n if (out) lines.push(`Output so far (tail):\\n${out}`);\n }\n lines.push(`If the process was killed mid-run (a serverless timeout, a deploy), this is what that looks like.`);\n break;\n }\n case \"slow\": {\n const d = draft.details;\n title = `${name} was slow`;\n lines.push(`Took ${formatDuration(d.durationMs)}; the limit is ${formatDuration(d.thresholdMs)} (${d.basis}).`);\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"over_budget\": {\n title = `${name} went over budget`;\n for (const b of draft.details.breaches) {\n lines.push(`${b.metric}: ${formatNumber(b.value)}, limit ${formatNumber(b.limit)} (${b.basis}).`);\n }\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"recovered\": {\n if (draft.details.reason === \"unscheduled\") {\n title = `${name} is no longer scheduled`;\n const since = draft.details.since;\n lines.push(`${since === undefined ? \"\" : `Missed since ${when(since, now)}. `}It has no schedule now, so nothing is due; the missed alert is closed.`);\n break;\n }\n title = `${name} recovered`;\n const after = draft.details.after.map((c) => c.replace(\"_\", \" \")).join(\", \");\n lines.push(`A run ${run ? when(run.startedAt, now) : \"just now\"} succeeded${after ? ` after: ${after}` : \"\"}.`);\n if (run?.durationMs !== null && run?.durationMs !== undefined) lines.push(`Ran ${formatDuration(run.durationMs)}.`);\n break;\n }\n }\n\n return { ...draft, job: name, definition: def, title, message: lines.join(\"\\n\"), at: now };\n}\n","export function json(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\", ...headers },\n });\n}\n\n/** Compares two secrets without stopping at the first differing character. */\nexport function constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n","/** Output is capped so a chatty job cannot fill the store. The tail is kept. */\nexport const OUTPUT_CAP = 16 * 1024;\n\n/**\n * NUL characters are removed first, since Postgres refuses them in TEXT and\n * JSONB and the whole run row would be lost. The cap then applies to what is\n * left.\n */\nexport function capOutput(text: string): string {\n const clean = stripNul(text);\n if (clean.length <= OUTPUT_CAP) return clean;\n return \"[earlier output trimmed]\\n\" + clean.slice(clean.length - OUTPUT_CAP);\n}\n\n/** Removes every U+0000. */\nexport function stripNul(text: string): string {\n return text.includes(\"\\u0000\") ? text.replace(/\\u0000/g, \"\") : text;\n}\n\n/** \"Name: message\" and the first five stack frames, capped like output. */\nexport function errorMessage(error: unknown): string {\n return capOutput(describeError(error));\n}\n\nfunction describeError(error: unknown): string {\n if (error instanceof Error) {\n // The stack repeats the header (over several lines when the message has\n // newlines), so take only its frames.\n const frames = (error.stack ?? \"\").split(\"\\n\").filter((line) => /^\\s+at /.test(line)).slice(0, 5);\n return `${error.name}: ${error.message}${frames.length ? `\\n${frames.join(\"\\n\")}` : \"\"}`;\n }\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error) ?? String(error);\n } catch {\n return String(error);\n }\n}\n\nconst REDACTED = \"[redacted]\";\n\n// Bounded quantifiers throughout, so a long line cannot make these backtrack.\n// They apply in this order, each to the text the ones before it left.\nconst SECRET_PATTERNS: [RegExp, string | ((match: string, ...groups: string[]) => string)][] = [\n // A PEM private key, header to footer. Without a footer (the output was\n // trimmed) it runs to the end of the base64 body. A \"-\" that starts five\n // dashes ends the body, so the footer is never swallowed into it.\n [\n /-----BEGIN (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----(?:[A-Za-z0-9+/=\\s,:]|-(?!----)){0,16384}(?:-----END (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----)?/g,\n REDACTED,\n ],\n // password=..., API_KEY: ..., \"client_secret\": \"...\", TOKEN='...', token=...,\n // :password=>\"...\" (but not max_tokens: 800). A quoted value is blanked to\n // its closing quote, spaces and all, and keeps its quotes.\n [\n /\\b([A-Za-z0-9_-]{0,40}(?:secret|token|passw(?:or)?d|pwd|api[_-]?key|access[_-]?key|private[_-]?key|credential)[A-Za-z0-9_-]{0,40}(?<![Tt][Oo][Kk][Ee][Nn][Ss])\"?\\s{0,3}(?:=>|[=:])\\s{0,3})(?:(\")[^\"\\n]{1,4096}\"|(')[^'\\n]{1,4096}'|[\"']?[^\\s\"',;&]{1,4096})/gi,\n (_match, name: string, double?: string, single?: string) => {\n const quote = double ?? single ?? \"\";\n return `${name}${quote}${REDACTED}${quote}`;\n },\n ],\n // Authorization: Basic <base64> and Authorization: Token <token>, also as a JSON or hash entry.\n [/\\b((?:proxy-)?authorization[\"']?\\s{0,3}(?:=>|[=:])\\s{0,3}[\"']?\\s{0,3}(?:basic|token)\\s{1,3})[A-Za-z0-9._~+/=:-]{1,4096}/gi, `$1${REDACTED}`],\n // Credentials inside a URL: postgres://user:password@host. The password\n // runs to the last \"@\" before a \"/\" or a space, so one that contains \"@\"\n // is blanked whole.\n [/(\\b[a-z][a-z0-9+.-]{0,30}:\\/\\/[^\\s/:@]{0,256}:)[^\\s/]{1,256}@/gi, `$1${REDACTED}@`],\n // Authorization: Bearer <token>\n [/\\b(Bearer\\s{1,3})[A-Za-z0-9._~+/=-]{8,4096}/g, `$1${REDACTED}`],\n // A bare JWT: three base64url segments, the first starting eyJ.\n [/\\beyJ[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{0,4096}/g, REDACTED],\n // Incoming webhook URLs carry their secret in the path.\n [/(\\bhooks\\.slack\\.com\\/(?:services|workflows|triggers)\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n [/(\\bdiscord(?:app)?\\.com\\/api\\/(?:v\\d{1,2}\\/)?webhooks\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n // Well-known token shapes: AWS, GitHub, Slack, Stripe, Anthropic, OpenAI and Google style keys.\n [/\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g, REDACTED],\n [/\\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{20,255})\\b/g, REDACTED],\n [/\\bxox[abposr]-[A-Za-z0-9-]{10,255}/g, REDACTED],\n [/\\b[rsp]k_(?:live|test)_[A-Za-z0-9]{10,255}\\b/g, REDACTED],\n [/\\bwhsec_[A-Za-z0-9+/=]{16,255}/g, REDACTED],\n [/\\bsk-[A-Za-z0-9_-]{20,255}/g, REDACTED],\n [/\\bAIza[0-9A-Za-z_-]{35}(?![0-9A-Za-z_-])/g, REDACTED],\n];\n\n/**\n * The default `redact`: blanks values that look like secrets (key=value pairs\n * with secret-ish names, Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs and well-known token formats)\n * before output or an error is stored, shown or sent anywhere.\n */\nexport function redactSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) out = out.replace(pattern, replacement as string);\n return out;\n}\n","import { capOutput, OUTPUT_CAP } from \"./output.js\";\nimport type { Run } from \"./types.js\";\n\n/** What a job function receives. */\nexport interface JobContext {\n readonly name: string;\n readonly runId: string;\n readonly startedAt: number;\n /** Aborts when the job's timeout elapses. Honour it if the work can stop. */\n readonly signal: AbortSignal;\n /** Append a line of output. Kept with the run, capped at 16 KB, shown in alerts and the dashboard. */\n log(...parts: unknown[]): void;\n /** Report a number for this run: tokens, cost, rows, anything. Watched against budgets and baselines. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n}\n\nexport interface RunRecorder {\n context: JobContext;\n output(): string | null;\n /**\n * What an expect rule is checked against: everything logged, or when that\n * ran long, the first 16 KB and the last 16 KB. The stored output keeps only\n * the tail, so a \"done\" line printed early would otherwise be lost.\n */\n expectText(): string | null;\n metrics(): Record<string, number>;\n abort(): void;\n}\n\nfunction stringify(part: unknown): string {\n if (typeof part === \"string\") return part;\n if (part instanceof Error) return `${part.name}: ${part.message}`;\n try {\n return JSON.stringify(part);\n } catch {\n return String(part);\n }\n}\n\nexport function createRecorder(run: Run): RunRecorder {\n const lines: string[] = [];\n let size = 0;\n const head: string[] = [];\n let headSize = 0;\n let dropped = false;\n const metrics: Record<string, number> = {};\n const controller = new AbortController();\n\n const context: JobContext = {\n name: run.job,\n runId: run.id,\n startedAt: run.startedAt,\n signal: controller.signal,\n log(...parts) {\n const line = parts.map(stringify).join(\" \");\n if (headSize < OUTPUT_CAP) {\n head.push(line);\n headSize += line.length + 1;\n }\n lines.push(line);\n size += line.length + 1;\n // Drop from the front once well past the cap; capOutput trims exactly at the end.\n while (size > 64 * 1024 && lines.length > 1) {\n size -= lines.shift()!.length + 1;\n dropped = true;\n }\n },\n metric(name, value) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`metric \"${name}\" must be a finite number`);\n }\n metrics[name] = value;\n },\n metrics(values) {\n for (const [k, v] of Object.entries(values)) context.metric(k, v);\n },\n };\n\n return {\n context,\n output: () => (lines.length === 0 ? null : capOutput(lines.join(\"\\n\"))),\n expectText: () => {\n if (lines.length === 0) return null;\n const all = lines.join(\"\\n\");\n if (!dropped && all.length <= 2 * OUTPUT_CAP) return all;\n return head.join(\"\\n\").slice(0, OUTPUT_CAP) + \"\\n\" + all.slice(-OUTPUT_CAP);\n },\n metrics: () => ({ ...metrics }),\n abort: () => controller.abort(),\n };\n}\n","import type { JobDefinition, StoredJobDefinition } from \"./types.js\";\n\n/** A definition as a store can hold it: `expect` becomes a description. */\nexport function toStored(def: JobDefinition): StoredJobDefinition {\n const { expect, ...rest } = def;\n const stored: StoredJobDefinition = { ...rest };\n if (expect !== undefined) {\n stored.expect =\n typeof expect === \"string\" ? `contains ${JSON.stringify(expect)}`\n : expect instanceof RegExp ? `matches ${expect.toString()}`\n : \"custom function\";\n }\n return stored;\n}\n\nexport function checkExpectation(expect: JobDefinition[\"expect\"], output: string | null): string | null {\n if (expect === undefined) return null;\n const text = output ?? \"\";\n if (typeof expect === \"string\") {\n return text.includes(expect) ? null : `Output did not contain ${JSON.stringify(expect)}`;\n }\n if (expect instanceof RegExp) {\n expect.lastIndex = 0; // a /g or /y pattern would otherwise resume where the last run stopped\n return expect.test(text) ? null : `Output did not match ${expect.toString()}`;\n }\n let ok = false;\n try {\n ok = expect(text);\n } catch (error) {\n return `Output check threw: ${(error as Error).message}`;\n }\n return ok ? null : \"Output did not pass the expect() check\";\n}\n","import { formatDuration, formatRelative } from \"../duration.js\";\nimport type { JobSummary, Run } from \"../types.js\";\n\nexport function escapeHtml(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\nconst h = escapeHtml;\n\nconst CSS = `\n:root{--bg:#fbfbf9;--fg:#1b1b18;--muted:#6b6b64;--line:#e6e5df;--card:#fff;--ok:#1f8a4c;--warn:#b7791f;--bad:#c62828;--info:#2b5fb3;--pill:#f1f0ea;--mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--sans:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Inter,Roboto,sans-serif}\n@media(prefers-color-scheme:dark){:root{--bg:#121311;--fg:#ecece6;--muted:#9a9a91;--line:#2a2b27;--card:#1a1b18;--pill:#24251f}}\n*{box-sizing:border-box}html{-webkit-text-size-adjust:100%}\nbody{margin:0;background:var(--bg);color:var(--fg);font:15px/1.5 var(--sans)}\na{color:inherit}main{max-width:1080px;margin:0 auto;padding:24px 16px 64px}\nheader{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:20px}\nheader h1{font-size:18px;margin:0;letter-spacing:-.01em}header h1 a{text-decoration:none}\nheader .meta{color:var(--muted);font-size:13px}\n.card{background:var(--card);border:1px solid var(--line);border-radius:10px;overflow:hidden}\ntable{width:100%;border-collapse:collapse;font-size:14px}\nth{text-align:left;font-weight:600;color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.04em;padding:10px 12px;border-bottom:1px solid var(--line);white-space:nowrap}\ntd{padding:10px 12px;border-bottom:1px solid var(--line);vertical-align:top}\ntr:last-child td{border-bottom:0}\n.name{font-weight:600;white-space:nowrap}.name a{text-decoration:none}.name a:hover{text-decoration:underline}\n.mono{font-family:var(--mono);font-size:13px}.muted{color:var(--muted)}.nowrap{white-space:nowrap}\n.pill{display:inline-flex;align-items:center;gap:6px;padding:2px 9px;border-radius:999px;background:var(--pill);font-size:12px;font-weight:600;white-space:nowrap}\n.pill::before{content:\"\";width:7px;height:7px;border-radius:50%;background:currentColor}\n.ok{color:var(--ok)}.warn{color:var(--warn)}.bad{color:var(--bad)}.info{color:var(--info)}.mutedpill{color:var(--muted)}\n.spark{display:block}\nform.inline{display:inline}\nbutton,select{font:inherit;font-size:13px;padding:5px 10px;border:1px solid var(--line);border-radius:7px;background:var(--card);color:var(--fg);cursor:pointer}\nbutton:hover{border-color:var(--muted)}\n.actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}\n.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin:0 0 20px}\n.stat{padding:12px 14px}.stat .k{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}.stat .v{font-size:20px;font-weight:600;margin-top:2px}\npre{margin:0;padding:10px 12px;background:var(--pill);border-radius:8px;font:12.5px/1.45 var(--mono);white-space:pre-wrap;word-break:break-word;max-height:320px;overflow:auto}\ndetails summary{cursor:pointer;color:var(--muted);font-size:13px}details{margin-top:6px}\ndetails.confirm{margin:0}details.confirm summary{list-style:none;display:inline-block;font-size:13px;padding:5px 10px;border:1px solid var(--line);border-radius:7px;background:var(--card);color:var(--fg)}\ndetails.confirm summary::-webkit-details-marker{display:none}details.confirm[open] summary{border-color:var(--muted)}details.confirm form{margin-left:8px;font-size:13px}\n.empty{padding:40px 16px;text-align:center;color:var(--muted)}\ndl{display:grid;grid-template-columns:max-content 1fr;gap:6px 16px;margin:0;padding:14px 16px;font-size:14px}dt{color:var(--muted)}dd{margin:0}\nfooter{margin-top:28px;color:var(--muted);font-size:12px}\n@media(max-width:720px){.hide-sm{display:none}main{padding:16px 16px 48px}}\n`;\n\nexport function layout(title: string, body: string, options: { refresh?: number } = {}): string {\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<meta name=\"robots\" content=\"noindex,nofollow\">\n${options.refresh ? `<meta http-equiv=\"refresh\" content=\"${options.refresh}\">` : \"\"}\n<title>${h(title)}</title>\n<style>${CSS}</style>\n</head>\n<body><main>${body}</main></body>\n</html>`;\n}\n\nfunction healthPill(job: JobSummary): string {\n const map: Record<JobSummary[\"health\"], [string, string]> = {\n healthy: [\"ok\", \"healthy\"],\n late: [\"warn\", \"late\"],\n failing: [\"bad\", \"failing\"],\n stuck: [\"bad\", \"stuck\"],\n silenced: [\"mutedpill\", \"silenced\"],\n never_ran: [\"info\", \"never ran\"],\n };\n const [cls, label] = map[job.health];\n const extras = job.open.filter((c) => ![\"missed\", \"failed\", \"stuck\"].includes(c)).map((c) => c.replace(\"_\", \" \"));\n return `<span class=\"pill ${cls}\">${label}</span>${extras.length ? ` <span class=\"pill warn\">${h(extras.join(\", \"))}</span>` : \"\"}`;\n}\n\nfunction runPill(run: Run): string {\n const cls = run.status === \"ok\" ? \"ok\" : run.status === \"running\" ? \"info\" : \"bad\";\n return `<span class=\"pill ${cls}\">${h(run.status)}</span>`;\n}\n\nfunction sparkline(runs: Run[]): string {\n const points = [...runs].reverse().filter((r) => r.durationMs !== null).slice(-20);\n if (points.length < 2) return \"\";\n const w = 96, hgt = 22;\n const max = Math.max(...points.map((r) => r.durationMs!), 1);\n const step = w / (points.length - 1);\n const path = points.map((r, i) => `${i === 0 ? \"M\" : \"L\"}${(i * step).toFixed(1)},${(hgt - 2 - (r.durationMs! / max) * (hgt - 4)).toFixed(1)}`).join(\" \");\n const dots = points.map((r, i) => r.status === \"ok\" ? \"\" : `<circle cx=\"${(i * step).toFixed(1)}\" cy=\"${(hgt - 2 - (r.durationMs! / max) * (hgt - 4)).toFixed(1)}\" r=\"2.2\" fill=\"var(--bad)\"/>`).join(\"\");\n return `<svg class=\"spark\" width=\"${w}\" height=\"${hgt}\" viewBox=\"0 0 ${w} ${hgt}\" aria-hidden=\"true\"><path d=\"${path}\" fill=\"none\" stroke=\"var(--muted)\" stroke-width=\"1.5\"/>${dots}</svg>`;\n}\n\nfunction stamp(at: number | null, now: number): string {\n if (at === null) return `<span class=\"muted\">never</span>`;\n const iso = new Date(at).toISOString().replace(\"T\", \" \").slice(0, 19);\n return `<span class=\"nowrap\" title=\"${iso} UTC\">${h(formatRelative(at, now))}</span>`;\n}\n\nexport function dashboardPage(jobs: JobSummary[], runsByJob: Map<string, Run[]>, now: number, base: string, checkedAt: number | null): string {\n const rows = jobs.map((job) => {\n const last = job.lastRun;\n return `<tr>\n<td class=\"name\"><a href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${h(job.name)}</a>${job.definition.description ? `<div class=\"muted\" style=\"font-weight:400;font-size:13px;white-space:normal\">${h(job.definition.description)}</div>` : \"\"}</td>\n<td>${healthPill(job)}</td>\n<td class=\"mono nowrap\">${h(job.definition.schedule ?? \"\")}<span class=\"muted\">${job.definition.schedule ? \"\" : \"no schedule\"}</span></td>\n<td class=\"nowrap\">${last ? `${runPill(last)} ${stamp(last.startedAt, now)}${last.durationMs !== null ? ` <span class=\"muted\">${h(formatDuration(last.durationMs))}</span>` : \"\"}` : `<span class=\"muted\">never</span>`}</td>\n<td class=\"nowrap hide-sm\">${stamp(job.nextExpectedAt, now)}</td>\n<td class=\"hide-sm\">${sparkline(runsByJob.get(job.name) ?? [])}</td>\n</tr>`;\n }).join(\"\\n\");\n\n const body = `\n<header>\n <h1><a href=\"${h(base)}/\">CronWatch</a></h1>\n <div class=\"actions\">\n <span class=\"meta\">${jobs.length} job${jobs.length === 1 ? \"\" : \"s\"}${checkedAt ? `, checked ${h(formatRelative(checkedAt, now))}` : \"\"}</span>\n <form class=\"inline\" method=\"post\" action=\"${h(base)}/check\"><button type=\"submit\">Run check now</button></form>\n </div>\n</header>\n<div class=\"card\">\n${jobs.length === 0 ? `<div class=\"empty\">No jobs yet. Declare one with <code class=\"mono\">cw.job(\"name\", { schedule: \"0 2 * * *\" })</code> and run it once.</div>` : `<table>\n<thead><tr><th>Job</th><th>Health</th><th>Schedule</th><th>Last run</th><th class=\"hide-sm\">Next due</th><th class=\"hide-sm\">Durations</th></tr></thead>\n<tbody>${rows}</tbody></table>`}\n</div>\n<footer>Refreshes every minute. <a href=\"${h(base)}/api/jobs\">JSON</a></footer>`;\n return layout(\"CronWatch\", body, { refresh: 60 });\n}\n\nexport function jobPage(job: JobSummary, runs: Run[], now: number, base: string): string {\n const d = job.definition;\n const okRate = `${Math.round(job.stats.okRate * 100)}%`;\n const runRows = runs.map((run) => {\n const detail = [\n run.error ? `<details open><summary>error</summary><pre>${h(run.error)}</pre></details>` : \"\",\n run.output ? `<details${run.status === \"ok\" ? \"\" : \" open\"}><summary>output</summary><pre>${h(run.output)}</pre></details>` : \"\",\n ].join(\"\");\n const metrics = Object.entries(run.metrics).map(([k, v]) => `<span class=\"pill mutedpill\">${h(k)} ${h(Number.isInteger(v) ? v : v.toFixed(4))}</span>`).join(\" \");\n return `<tr>\n<td class=\"nowrap\">${runPill(run)}</td>\n<td class=\"nowrap\">${stamp(run.startedAt, now)}</td>\n<td class=\"nowrap\">${run.durationMs !== null ? h(formatDuration(run.durationMs)) : `<span class=\"muted\">running</span>`}</td>\n<td class=\"hide-sm\">${metrics}</td>\n<td class=\"mono hide-sm muted\">${h(run.trigger)}</td>\n</tr>${detail ? `<tr><td colspan=\"5\" style=\"padding-top:0\">${detail}</td></tr>` : \"\"}`;\n }).join(\"\\n\");\n\n const silenced = job.silencedUntil !== null && job.silencedUntil > now;\n const body = `\n<header>\n <h1><a href=\"${h(base)}/\">CronWatch</a> <span class=\"muted\">/</span> ${h(job.name)}</h1>\n <div class=\"actions\">\n ${healthPill(job)}\n ${silenced\n ? `<form class=\"inline\" method=\"post\" action=\"${h(base)}/jobs/${encodeURIComponent(job.name)}/unsilence\"><button type=\"submit\">Unsilence (until ${h(formatRelative(job.silencedUntil!, now))})</button></form>`\n : `<form class=\"inline\" method=\"post\" action=\"${h(base)}/jobs/${encodeURIComponent(job.name)}/silence\"><select name=\"for\"><option value=\"1h\">1 hour</option><option value=\"4h\">4 hours</option><option value=\"1d\">1 day</option><option value=\"7d\">1 week</option></select> <button type=\"submit\">Silence</button></form>`}\n <details class=\"confirm\"><summary>Forget</summary><form class=\"inline\" method=\"post\" action=\"${h(base)}/jobs/${encodeURIComponent(job.name)}/forget\"><span class=\"muted\">Remove this job and its runs from the store?</span> <button type=\"submit\">Forget</button></form></details>\n </div>\n</header>\n<div class=\"grid\">\n <div class=\"card stat\"><div class=\"k\">Last run</div><div class=\"v\">${job.lastRun ? h(formatRelative(job.lastRun.startedAt, now)) : \"never\"}</div></div>\n <div class=\"card stat\"><div class=\"k\">Next due</div><div class=\"v\">${job.nextExpectedAt ? h(formatRelative(job.nextExpectedAt, now)) : \"no schedule\"}</div></div>\n <div class=\"card stat\"><div class=\"k\">Success, last ${h(job.stats.runs)}</div><div class=\"v\">${h(okRate)}</div></div>\n <div class=\"card stat\"><div class=\"k\">p50 / p95</div><div class=\"v\">${job.stats.p50Ms !== null ? h(formatDuration(job.stats.p50Ms)) : \"?\"} <span class=\"muted\">/</span> ${job.stats.p95Ms !== null ? h(formatDuration(job.stats.p95Ms)) : \"?\"}</div></div>\n</div>\n<div class=\"card\" style=\"margin-bottom:20px\">\n<dl>\n <dt>Schedule</dt><dd class=\"mono\">${d.schedule ? h(d.schedule) + (d.timezone ? ` <span class=\"muted\">${h(d.timezone)}</span>` : \"\") : `<span class=\"muted\">none</span>`}</dd>\n <dt>Grace</dt><dd class=\"mono\">${h(d.grace ?? \"10m\")}</dd>\n <dt>Timeout</dt><dd class=\"mono\">${h(d.timeout ?? \"1h\")}</dd>\n ${d.maxDuration ? `<dt>Max duration</dt><dd class=\"mono\">${h(d.maxDuration)}</dd>` : \"\"}\n ${d.budget ? `<dt>Budget</dt><dd class=\"mono\">${h(Object.entries(d.budget).map(([k, v]) => `${k} ≤ ${v}`).join(\", \"))}</dd>` : \"\"}\n ${d.expect ? `<dt>Expect</dt><dd class=\"mono\">${h(d.expect)}</dd>` : \"\"}\n ${d.failuresBeforeAlert && d.failuresBeforeAlert > 1 ? `<dt>Alert after</dt><dd>${h(d.failuresBeforeAlert)} consecutive failures</dd>` : \"\"}\n ${d.description ? `<dt>Description</dt><dd>${h(d.description)}</dd>` : \"\"}\n ${d.tags?.length ? `<dt>Tags</dt><dd>${d.tags.map((t) => `<span class=\"pill mutedpill\">${h(t)}</span>`).join(\" \")}</dd>` : \"\"}\n ${job.open.length ? `<dt>Open</dt><dd>${job.open.map((c) => `<span class=\"pill warn\">${h(c.replace(\"_\", \" \"))}</span>`).join(\" \")}</dd>` : \"\"}\n ${job.consecutiveFailures > 0 ? `<dt>Consecutive failures</dt><dd>${h(job.consecutiveFailures)}</dd>` : \"\"}\n</dl>\n</div>\n<div class=\"card\">\n${runs.length === 0 ? `<div class=\"empty\">No runs yet.</div>` : `<table>\n<thead><tr><th>Status</th><th>Started</th><th>Duration</th><th class=\"hide-sm\">Metrics</th><th class=\"hide-sm\">Trigger</th></tr></thead>\n<tbody>${runRows}</tbody></table>`}\n</div>\n<footer><a href=\"${h(base)}/api/jobs/${encodeURIComponent(job.name)}\">JSON</a></footer>`;\n return layout(`${job.name}: CronWatch`, body, { refresh: 60 });\n}\n\nexport function messagePage(title: string, message: string, base: string): string {\n return layout(title, `<header><h1><a href=\"${h(base)}/\">CronWatch</a></h1></header><div class=\"card\"><div class=\"empty\"><strong>${h(title)}</strong><br>${h(message)}</div></div>`);\n}\n","import type { CronWatch } from \"../client.js\";\nimport { isDevelopment, readEnv } from \"../env.js\";\nimport { constantTimeEqual, json } from \"../http.js\";\nimport { parseDuration } from \"../duration.js\";\nimport type { Duration, Run } from \"../types.js\";\nimport { dashboardPage, jobPage, messagePage } from \"./html.js\";\n\nexport interface RoutesOptions {\n /**\n * Required to reach anything. Send it as `Authorization: Bearer <token>`,\n * or open the dashboard once with `?token=<token>` and a cookie is set.\n * Defaults to process.env.CRONWATCH_TOKEN (on Cloudflare Workers, which\n * have no process, pass env.CRONWATCH_TOKEN); an empty string counts as unset.\n * With no token while NODE_ENV is \"development\" or \"test\", the routes make\n * a random one and print a sign-in link to the server log on their first\n * request; with no token otherwise they answer 503. Pass `null` to opt out\n * and serve them open everywhere, for example behind your own auth.\n *\n * The check endpoint (/api/check) also accepts the client's cronSecret, so\n * a platform cron that sends `Authorization: Bearer <CRON_SECRET>` can\n * trigger checks without knowing the dashboard token.\n */\n token?: string | null;\n /** Where the routes are mounted, so links resolve. Default \"/cronwatch\". */\n basePath?: string;\n /**\n * The public origin the dashboard is served from, such as\n * \"https://app.example.com\", for an app behind a proxy whose request URLs\n * carry an internal host or scheme. Used in place of the request URL's\n * origin for the cross-site check on writes, the sign-in redirect (its\n * cookie is Secure when this is https, and the redirect back after a form\n * follows a Referer on this origin) and the development sign-in line.\n * Takes precedence over trustProxy.\n */\n origin?: string;\n /**\n * Take the public origin from X-Forwarded-Proto and X-Forwarded-Host (the\n * first value of each, falling back to the request URL's scheme or host\n * for whichever is missing) when a request carries either. Only for an app\n * whose proxy sets or overwrites both headers: a client can send them too.\n * Default false, which ignores them.\n */\n trustProxy?: boolean;\n}\n\nexport type FetchHandler = (request: Request) => Promise<Response>;\n\nexport interface Routes {\n handler: FetchHandler;\n GET: FetchHandler;\n POST: FetchHandler;\n DELETE: FetchHandler;\n}\n\nconst COOKIE = \"cronwatch_token\";\n\n/**\n * The cookie holds a digest of the token, so a leaked cookie does not reveal\n * the bearer token itself: the SHA-256 of \"cronwatch-cookie:<token>\", as hex.\n * Web Crypto, so the routes need nothing from node: and run on Workers too.\n */\nasync function cookieValue(token: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(`cronwatch-cookie:${token}`));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nconst DEFAULT_RUNS = 20;\nconst MAX_RUNS = 500;\n\nconst CSP = \"default-src 'none'; style-src 'unsafe-inline'; img-src 'self' data:; form-action 'self'; frame-ancestors 'none'; base-uri 'none'\";\n// same-origin rather than no-referrer: under no-referrer browsers send\n// `Origin: null` on form posts, which the CSRF check would refuse, and the\n// forms redirect back to the page named by the same-origin Referer.\nconst SECURITY_HEADERS = { \"x-content-type-options\": \"nosniff\", \"referrer-policy\": \"same-origin\", \"x-robots-tag\": \"noindex\" };\n\n/**\n * A token for one routes instance in development, when none is configured:\n * 32 random bytes, base64url (43 characters).\n */\nfunction developmentToken(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return btoa(String.fromCharCode(...bytes)).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * The line a development token is announced with, printed once with\n * console.info on the routes' first request:\n *\n * [cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: <origin><base>/?token=<token>\n *\n * <origin> is the first request's public origin (scheme, host and any\n * port): the `origin` option when set, the forwarded one under trustProxy,\n * otherwise the request URL's,\n * <base> the base path without a trailing slash (\"\" when mounted at the\n * root), and <token> the token as generated (base64url, so nothing needs\n * escaping).\n */\nfunction developmentSignInLine(origin: string, base: string, token: string): string {\n return `[cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: ${origin}${base}/?token=${token}`;\n}\n\nfunction safeDecode(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction readCookie(request: Request, name: string): string | null {\n const header = request.headers.get(\"cookie\");\n if (!header) return null;\n for (const part of header.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n // A malformed escape counts as no cookie.\n if (k === name) return safeDecode(rest.join(\"=\"));\n }\n return null;\n}\n\n/** The first entry of a comma-separated header, trimmed, or null when there is none. */\nfunction firstValue(value: string | null): string | null {\n const first = value?.split(\",\")[0]?.trim();\n return first ? first : null;\n}\n\n/**\n * The origin configured with `origin`, normalised, or null. Throws on a value\n * that is not an http or https origin, so a typo fails at startup.\n */\nfunction configuredOrigin(value: string | undefined): string | null {\n if (value === undefined || value === \"\") return null;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`routes: origin must be an absolute URL such as \"https://app.example.com\", got ${JSON.stringify(value)}`);\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error(`routes: origin must be http or https, got ${JSON.stringify(value)}`);\n return url.origin;\n}\n\n/**\n * The origin a browser sees for this request, with trustProxy: the forwarded\n * scheme and host when present and well formed, otherwise the request URL's own.\n */\nfunction forwardedOrigin(request: Request, url: URL): string {\n const proto = firstValue(request.headers.get(\"x-forwarded-proto\"))?.toLowerCase() ?? null;\n const host = firstValue(request.headers.get(\"x-forwarded-host\"));\n if (proto === null && host === null) return url.origin;\n if (proto !== null && proto !== \"http\" && proto !== \"https\") return url.origin;\n try {\n const built = new URL(`${proto ?? url.protocol.slice(0, -1)}://${host ?? url.host}`);\n // A \"host\" carrying a path, credentials, a query or a fragment is not a host.\n if (built.pathname !== \"/\" || built.username || built.password || built.search || built.hash) return url.origin;\n return built.origin;\n } catch {\n return url.origin;\n }\n}\n\nfunction stripBase(pathname: string, base: string): string {\n let path = pathname.startsWith(base) ? pathname.slice(base.length) : pathname;\n if (path === \"\") path = \"/\";\n if (path.length > 1 && path.endsWith(\"/\")) path = path.slice(0, -1);\n return path;\n}\n\nasync function readBody(request: Request): Promise<Record<string, string>> {\n const type = request.headers.get(\"content-type\") ?? \"\";\n try {\n if (type.includes(\"application/json\")) {\n const data = await request.json();\n return typeof data === \"object\" && data !== null ? Object.fromEntries(Object.entries(data).map(([k, v]) => [k, String(v)])) : {};\n }\n if (type.includes(\"application/x-www-form-urlencoded\") || type.includes(\"multipart/form-data\")) {\n const form = await request.formData();\n const out: Record<string, string> = {};\n for (const [k, v] of form.entries()) out[k] = String(v);\n return out;\n }\n } catch {\n return {};\n }\n return {};\n}\n\n/**\n * A browser attaches Origin or Sec-Fetch-Site to a cross-site form post, and\n * a page cannot forge either. Non-browser clients send neither.\n */\nfunction crossSite(request: Request, publicOrigin: string): boolean {\n const origin = request.headers.get(\"origin\");\n if (origin !== null && origin !== publicOrigin) return true;\n const site = request.headers.get(\"sec-fetch-site\");\n return site !== null && site !== \"same-origin\" && site !== \"none\";\n}\n\n/** Absent means one hour; a number or numeric string is milliseconds. Throws on anything else. */\nfunction silenceDuration(value: string | null | undefined): Duration {\n if (value === undefined || value === null) return \"1h\";\n const text = value.trim();\n const duration: Duration = /^\\d+(\\.\\d+)?$/.test(text) ? Number(text) : text;\n parseDuration(duration, \"silence duration\");\n return duration;\n}\n\nfunction runsLimit(value: string | null): number {\n const n = value === null || value.trim() === \"\" ? NaN : Math.trunc(Number(value));\n return Number.isFinite(n) ? Math.min(MAX_RUNS, Math.max(1, n)) : DEFAULT_RUNS;\n}\n\n/**\n * A fetch-style handler serving the dashboard and a small JSON API. Mount it\n * in a Next.js app at app/cronwatch/[[...path]]/route.ts:\n *\n * export const { GET, POST, DELETE } = cw.routes();\n */\nexport function createRoutes(cw: CronWatch, options: RoutesOptions = {}): Routes {\n const optedOut = options.token === null;\n const configured = optedOut ? null : (options.token || readEnv(\"CRONWATCH_TOKEN\") || null);\n const base = (options.basePath ?? \"/cronwatch\").replace(/\\/+$/, \"\");\n const developing = isDevelopment();\n const fixedOrigin = configuredOrigin(options.origin);\n const trustProxy = options.trustProxy === true;\n const originOf = (request: Request, url: URL): string =>\n fixedOrigin ?? (trustProxy ? forwardedOrigin(request, url) : url.origin);\n // A fetch handler cannot tell a local caller from a remote one (proxies,\n // tunnels and `next dev` listening on every interface all look alike), so\n // development gets a token too: made here, and shown only in the server log.\n const generated = !configured && !optedOut && developing;\n const token = generated ? developmentToken() : configured;\n let announced = false;\n // Worked out on the first request that needs it, then kept.\n let cookie: Promise<string> | null = null;\n const expectedCookie = (value: string) => (cookie ??= cookieValue(value));\n\n const serve = async (request: Request, url: URL, path: string, wantsHtml: boolean): Promise<Response> => {\n const method = request.method.toUpperCase();\n const publicOrigin = originOf(request, url);\n\n if (generated && !announced) {\n announced = true;\n console.info(developmentSignInLine(publicOrigin, base, token!));\n }\n\n // No token outside development: fail closed.\n if (!token && !optedOut) {\n return wantsHtml\n ? html(messagePage(\"CronWatch routes are locked\", \"Set CRONWATCH_TOKEN (or pass token to cw.routes()), or pass token: null to serve them open behind your own auth.\", base), 503)\n : api({ ok: false, error: \"CRONWATCH_TOKEN is not set\" }, 503);\n }\n\n if (method !== \"GET\" && method !== \"HEAD\" && crossSite(request, publicOrigin)) {\n return wantsHtml\n ? html(messagePage(\"Cross-site request refused\", \"Changes can only be made from the dashboard itself.\", base), 403)\n : api({ ok: false, error: \"Cross-site request refused\" }, 403);\n }\n\n const bearer = request.headers.get(\"authorization\")?.replace(/^Bearer\\s+/i, \"\") ?? null;\n if (token) {\n // ?token= is only the sign-in that moves the token into a cookie.\n const query = wantsHtml && method === \"GET\" ? url.searchParams.get(\"token\") : null;\n const sent = readCookie(request, COOKIE);\n const isCheck = path === \"/api/check\";\n const cronSecretOk = isCheck && bearer !== null && cw.cronSecret !== null && constantTimeEqual(bearer, cw.cronSecret);\n const tokenOk =\n bearer !== null ? constantTimeEqual(bearer, token)\n : query !== null ? constantTimeEqual(query, token)\n : sent !== null && constantTimeEqual(sent, await expectedCookie(token));\n if (!cronSecretOk && !tokenOk) {\n if (generated) {\n return wantsHtml\n ? html(messagePage(\"Sign in\", \"CRONWATCH_TOKEN is not set, so this development server made a token. The sign-in link is in the server log: open it once and this browser stays signed in.\", base), 401)\n : api({ ok: false, error: \"Unauthorized: CRONWATCH_TOKEN is not set, so this development server made a token; it is in the server log\" }, 401);\n }\n return wantsHtml\n ? html(messagePage(\"Sign in\", `Open this page with ?token=<your CRONWATCH_TOKEN> once and it will stay signed in.`, base), 401)\n : api({ ok: false, error: \"Unauthorized\" }, 401);\n }\n if (query !== null) {\n // Move the token from the URL into a cookie so it is not in history or logs.\n url.searchParams.delete(\"token\");\n const secure = publicOrigin.startsWith(\"https:\") ? \"; Secure\" : \"\";\n return redirect(url.pathname + (url.search || \"\"), {\n \"set-cookie\": `${COOKIE}=${await expectedCookie(token)}; Path=${base || \"/\"}; HttpOnly; SameSite=Lax; Max-Age=${60 * 60 * 24 * 30}${secure}`,\n });\n }\n }\n\n const redirectBack = () => {\n const referer = request.headers.get(\"referer\") ?? \"\";\n return redirect(referer.startsWith(publicOrigin + \"/\") ? referer : `${base}/`);\n };\n const decoded = path.split(\"/\").filter(Boolean).map(safeDecode);\n if (decoded.some((part) => part === null)) {\n return wantsHtml ? html(messagePage(\"Bad request\", \"The path is not valid.\", base), 400) : api({ ok: false, error: \"Bad path\" }, 400);\n }\n const parts = decoded as string[];\n\n // HTML\n if (method === \"GET\" && path === \"/\") {\n const entries = await cw.jobsWithRuns(20);\n const runsByJob = new Map<string, Run[]>(entries.map((entry) => [entry.job.name, entry.runs]));\n return html(dashboardPage(entries.map((entry) => entry.job), runsByJob, cw.now(), base, null));\n }\n if (method === \"GET\" && parts[0] === \"jobs\" && parts.length === 2) {\n const job = await cw.jobSummary(parts[1]!);\n if (!job) return html(messagePage(\"No such job\", `${parts[1]} is not in the store.`, base), 404);\n return html(jobPage(job, await cw.runs(job.name, 50), cw.now(), base));\n }\n if (method === \"POST\" && path === \"/check\") {\n await cw.check();\n return redirectBack();\n }\n if (method === \"POST\" && parts[0] === \"jobs\" && parts.length === 3) {\n const name = parts[1]!;\n if (parts[2] === \"forget\") {\n await cw.forget(name);\n return redirect(`${base}/`);\n }\n if (parts[2] !== \"silence\" && parts[2] !== \"unsilence\") return html(messagePage(\"Not found\", path, base), 404);\n if (!(await cw.jobSummary(name))) return html(messagePage(\"No such job\", `${name} is not in the store.`, base), 404);\n if (parts[2] === \"silence\") {\n let duration: Duration;\n try {\n duration = silenceDuration((await readBody(request)).for);\n } catch (e) {\n return html(messagePage(\"Not silenced\", (e as Error).message, base), 400);\n }\n await cw.silence(name, duration);\n } else await cw.unsilence(name);\n return redirectBack();\n }\n\n // JSON API\n if (parts[0] === \"api\") {\n const rest = parts.slice(1);\n if (method === \"GET\" && rest[0] === \"jobs\" && rest.length === 1) {\n return api({ ok: true, jobs: await cw.jobs() });\n }\n if (rest[0] === \"jobs\" && rest.length === 2) {\n const name = rest[1]!;\n if (method === \"GET\") {\n const job = await cw.jobSummary(name);\n if (!job) return api({ ok: false, error: \"No such job\" }, 404);\n return api({ ok: true, job, runs: await cw.runs(name, runsLimit(url.searchParams.get(\"runs\"))) });\n }\n if (method === \"DELETE\") {\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n await cw.forget(name);\n return api({ ok: true });\n }\n }\n if (method === \"POST\" && rest[0] === \"jobs\" && rest.length === 3) {\n const name = rest[1]!;\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n if (rest[2] === \"silence\") {\n const body = await readBody(request);\n let duration: Duration;\n try {\n duration = silenceDuration(body.for ?? url.searchParams.get(\"for\"));\n } catch (e) {\n return api({ ok: false, error: (e as Error).message }, 400);\n }\n return api({ ok: true, state: await cw.silence(name, duration) });\n }\n if (rest[2] === \"unsilence\") return api({ ok: true, state: await cw.unsilence(name) });\n }\n if (rest[0] === \"check\" && rest.length === 1) {\n // A page cannot send an Authorization header cross-site, so a GET\n // may only run the check when it carries a bearer (token or cron secret).\n if (method === \"GET\" && bearer === null) {\n return api({ ok: false, error: \"Use POST, or GET with an Authorization bearer\" }, 405, { allow: \"POST\" });\n }\n if (method === \"GET\" || method === \"POST\") {\n const result = await cw.check();\n return api({ ok: true, ...result });\n }\n }\n if (method === \"GET\" && rest[0] === \"runs\" && rest.length === 2) {\n const run = await cw.getRun(rest[1]!);\n return run ? api({ ok: true, run }) : api({ ok: false, error: \"No such run\" }, 404);\n }\n return api({ ok: false, error: \"Not found\" }, 404);\n }\n\n return html(messagePage(\"Not found\", path, base), 404);\n };\n\n const handler: FetchHandler = async (request) => {\n let wantsHtml = true;\n try {\n const url = new URL(request.url);\n const path = stripBase(url.pathname, base);\n wantsHtml = !path.startsWith(\"/api\");\n return await serve(request, url, path, wantsHtml);\n } catch (e) {\n try {\n cw.onError(e, \"routes\");\n } catch {\n // An onError that throws must not turn a 500 into an unhandled rejection.\n }\n return wantsHtml\n ? html(messagePage(\"Something went wrong\", \"The request failed and the error was reported.\", base), 500)\n : api({ ok: false, error: \"Internal error\" }, 500);\n }\n };\n\n return { handler, GET: handler, POST: handler, DELETE: handler };\n}\n\nfunction api(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return json(body, status, { ...SECURITY_HEADERS, ...headers });\n}\n\nfunction redirect(location: string, headers: Record<string, string> = {}): Response {\n return new Response(null, { status: 303, headers: { location, \"cache-control\": \"no-store\", ...SECURITY_HEADERS, ...headers } });\n}\n\nfunction html(body: string, status = 200): Response {\n return new Response(body, {\n status,\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": \"no-store\",\n \"content-security-policy\": CSP,\n \"x-frame-options\": \"DENY\",\n ...SECURITY_HEADERS,\n },\n });\n}\n","import type { JobState, Run, Store, StoredJob, StoredJobDefinition } from \"../types.js\";\n\n/**\n * Keeps everything in process memory. The default when no store is given,\n * good for tests and for trying the library out. State is gone on restart,\n * so a missed run cannot be noticed across one.\n */\nexport function memory(): Store {\n const jobs = new Map<string, StoredJob>();\n const runs = new Map<string, Run>();\n const order = new Map<string, number>();\n const states = new Map<string, JobState>();\n let seq = 0;\n\n const clone = <T>(v: T): T => JSON.parse(JSON.stringify(v));\n // Code unit order, as the SQL stores sort by bytes rather than by locale.\n const byName = (a: StoredJob, b: StoredJob) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0);\n\n return {\n async upsertJob(definition: StoredJobDefinition, now: number) {\n const existing = jobs.get(definition.name);\n jobs.set(definition.name, {\n name: definition.name,\n definition: clone(definition),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n });\n },\n async getJob(name) {\n const j = jobs.get(name);\n return j ? clone(j) : null;\n },\n async listJobs() {\n return [...jobs.values()].map(clone).sort(byName);\n },\n async deleteJob(name) {\n jobs.delete(name);\n states.delete(name);\n for (const [id, run] of runs) if (run.job === name) { runs.delete(id); order.delete(id); }\n },\n async insertRun(run) {\n // Like SQL's primary key: an id already recorded is refused, never overwritten.\n if (runs.has(run.id)) throw new Error(`run ${run.id} already exists`);\n runs.set(run.id, clone(run));\n order.set(run.id, ++seq);\n },\n async updateRun(run) {\n // Like SQL's UPDATE: a run that is gone (its job was forgotten) stays gone, and only these fields change.\n const existing = runs.get(run.id);\n if (!existing) return;\n const { status, finishedAt, durationMs, error, output, metrics } = clone(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n },\n async updateRunIf(run, fromStatuses) {\n const existing = runs.get(run.id);\n if (!existing || !fromStatuses.includes(existing.status)) return false;\n const { status, finishedAt, durationMs, error, output, metrics } = clone(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n return true;\n },\n async getRun(id) {\n const r = runs.get(id);\n return r ? clone(r) : null;\n },\n async listRuns(job, limit) {\n return [...runs.values()]\n .filter((r) => r.job === job)\n .sort((a, b) => b.startedAt - a.startedAt || order.get(b.id)! - order.get(a.id)!)\n .slice(0, limit)\n .map(clone);\n },\n async lastRun(job) {\n const list = await this.listRuns(job, 1);\n return list[0] ?? null;\n },\n async runningRuns() {\n return [...runs.values()]\n .filter((r) => r.status === \"running\")\n .sort((a, b) => a.startedAt - b.startedAt || order.get(a.id)! - order.get(b.id)!)\n .map(clone);\n },\n async getState(job) {\n const s = states.get(job);\n return s ? clone(s) : null;\n },\n async setState(state) {\n states.set(state.job, clone(state));\n },\n async compareAndSetState(state, expectedVersion) {\n if ((states.get(state.job)?.version ?? 0) !== expectedVersion) return false;\n states.set(state.job, clone(state));\n return true;\n },\n async prune(before) {\n // Each job's newest run is kept whatever its age: without it, a job\n // that runs less often than the retention looks like it never ran.\n const newest = new Map<string, number>();\n for (const run of runs.values()) newest.set(run.job, Math.max(newest.get(run.job) ?? -Infinity, run.startedAt));\n let n = 0;\n for (const [id, run] of runs) {\n if (run.status !== \"running\" && run.startedAt < before && run.startedAt < newest.get(run.job)!) {\n runs.delete(id);\n order.delete(id);\n n++;\n }\n }\n return n;\n },\n };\n}\n","import { formatDuration, parseDuration } from \"./duration.js\";\nimport { isDevelopment, readEnv } from \"./env.js\";\nimport {\n applySilence,\n BASELINE_WINDOW,\n emptyState,\n hasFullBaseline,\n isSilenced,\n isStuck,\n normalizeState,\n onCheck,\n onRunFinish,\n onRunStart,\n staleAlert,\n summarize,\n timeoutMs,\n unevaluableSummary,\n} from \"./evaluate.js\";\nimport { composeAlert } from \"./format.js\";\nimport { constantTimeEqual, json } from \"./http.js\";\nimport { createRecorder } from \"./job.js\";\nimport type { JobContext } from \"./job.js\";\nimport { capOutput, errorMessage, OUTPUT_CAP, redactSecrets, stripNul } from \"./output.js\";\nimport { parseSchedule } from \"./schedule.js\";\nimport { checkExpectation, toStored } from \"./serialize.js\";\nimport { createRoutes } from \"./routes/index.js\";\nimport type { Routes, RoutesOptions } from \"./routes/index.js\";\nimport { memory } from \"./stores/memory.js\";\nimport type {\n Alert,\n AlertChannel,\n AlertDraft,\n CheckResult,\n Condition,\n Duration,\n JobDefinition,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageFn,\n} from \"./types.js\";\n\nexport type JobFn<T> = (job: JobContext) => Promise<T> | T;\nexport type HandlerFn<T> = (job: JobContext, request: Request) => Promise<T> | T;\n\nexport interface HandlerOptions {\n /**\n * Callers must send `Authorization: Bearer <secret>`. Defaults to the\n * client's cronSecret, which defaults to process.env.CRON_SECRET (what\n * Vercel sends its cron requests with). An empty string counts as unset.\n * With no secret at all the handler answers 503 unless NODE_ENV is\n * \"development\" or \"test\". Pass null to allow anyone.\n */\n secret?: string | null;\n}\n\nexport interface JobHandle {\n readonly name: string;\n readonly definition: JobDefinition;\n /** Run the function now, recording the run. Rethrows whatever the function throws. */\n run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T>;\n /** A fetch-style request handler (Next.js route, Hono, Bun, Deno) that runs the function and records the run. */\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions): (request: Request) => Promise<Response>;\n /**\n * Record a running run now and finish it later, perhaps from another\n * process (see resume()). Store failures go to onError; it never throws for\n * them. A run that is never finished is marked stuck by the first check\n * after the job's timeout.\n */\n start(options?: StartOptions): Promise<RunHandle>;\n /** A handle on a run this job started elsewhere, by its id, so this process can log to it and finish it. */\n resume(runId: string): Promise<RunHandle>;\n}\n\nexport interface StartOptions {\n /** What started the run, as with run(). Default \"start\". */\n trigger?: string;\n /**\n * Your own stable id for the run, such as an Inngest run id, 1 to 200\n * characters, not starting with \"pgcron:\" (the pg_cron source's). A start\n * with an id already recorded for this job records nothing and returns a\n * handle on that run instead; an id recorded for another job throws,\n * whether that job's start is still in flight or long done.\n */\n id?: string;\n}\n\n/**\n * How a started run ended. `{ error }` is a failure, recorded like an error\n * run() caught. Otherwise the run succeeded, and `result` (or a string\n * passed on its own) is treated like the value run()'s function returns:\n * a string is the output when nothing was logged, `expect` is checked, and\n * a Response with status 400 or above is a failure.\n */\nexport type RunOutcome = { status?: \"ok\"; result?: unknown } | { error: unknown };\n\n/** A run recorded by job.start() or found by job.resume(), to finish later. */\nexport interface RunHandle {\n readonly id: string;\n readonly job: string;\n /** When the run started; null when a resumed run could not be read. */\n readonly startedAt: number | null;\n /** False once finished, and from the start for a resumed run that already finished or does not exist. */\n readonly active: boolean;\n /** Add a line of output. Kept in the handle until flush() or finish(). */\n log(...parts: unknown[]): void;\n /** Report a number for this run. A later value for the same name replaces an earlier one. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n /**\n * Append the lines and metrics added so far to the stored run, which must\n * still be running and belong to this job. A read, change and write of the\n * run's row, written only while it is still running: two processes\n * appending to one run at the same moment can lose one's lines, but a flush\n * never undoes a finish. The first 16 KB of everything flushed stay in the\n * handle, so an expect rule at finish() sees an early line as run() would.\n */\n flush(): Promise<void>;\n /**\n * Finish the run, judge it like any other and send what that produces.\n * Resolves to the run as recorded, or null when nothing was recorded: the\n * run was already finished (here or elsewhere), was not found, or belongs\n * to another job, which is reported to onError. When several processes\n * finish one run, only the one whose write lands judges it. Never throws\n * for the store: a store that fails is reported, nothing is recorded, and\n * the handle stays active so finish() can be called again.\n */\n finish(outcome?: RunOutcome | string): Promise<Run | null>;\n /** finish({ error }). */\n fail(error: unknown): Promise<Run | null>;\n}\n\n/**\n * What a Source may use of the client: declare jobs, read the store, and\n * record runs it found elsewhere. A CronWatch is one.\n */\nexport interface SourceHost {\n /** Declare a job, as CronWatch.job(). Throws for an invalid name or option. */\n job(name: string, options?: JobOptions): unknown;\n /** See CronWatch.recordRun(). */\n recordRun(run: Run, options?: RecordRunOptions): Promise<Alert[]>;\n readonly store: Store;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n}\n\n/**\n * Runs that happen somewhere CronWatch cannot wrap, such as inside the\n * database (see @cronwatch/sdk/pg-cron). check() calls sync() on each source\n * first, so what it records is evaluated in the same check.\n */\nexport interface Source {\n name: string;\n /** Declare the jobs and record their new runs. Returns the alerts recording them sent. */\n sync(host: SourceHost): Promise<Alert[] | void>;\n}\n\nexport interface RecordRunOptions {\n /** False stores the run without evaluating it, for history imported on first sight. Default true. */\n evaluate?: boolean;\n}\n\nexport interface CronWatchOptions {\n /** Where jobs, runs and state live. Defaults to an in-memory store that forgets on restart. */\n store?: Store;\n /**\n * Where runs this process does not wrap come from, such as pg_cron jobs.\n * Each is synced at the start of every check(); one that throws is\n * reported to onError and the check carries on.\n */\n sources?: Source[];\n /** Where alerts go. Defaults to the console. */\n alerts?: AlertChannel[];\n /** Adds a short diagnosis to every alert except recoveries. See @cronwatch/sdk/anthropic. */\n triage?: TriageFn;\n /**\n * Shared secret that handler() requests must carry. Defaults to\n * process.env.CRON_SECRET (on Cloudflare Workers, which have no process,\n * pass env.CRON_SECRET); an empty string counts as unset. Pass null to\n * let handlers run without one.\n */\n cronSecret?: string | null;\n /** How long finished runs are kept. Default \"30d\". */\n retention?: Duration;\n /** Applied to every job unless the job sets its own. */\n defaults?: Pick<JobOptions, \"grace\" | \"timeout\" | \"timezone\" | \"failuresBeforeAlert\">;\n /**\n * Applied to every run's output and error before it is stored, shown or\n * sent to an alert channel or triage. The default blanks values that look\n * like secrets (password=..., Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs, AWS, GitHub, Slack, Stripe,\n * Google and API key formats). Pass your own function, or false to keep\n * output exactly as logged. A function that throws or returns something\n * other than a string is reported to onError and the default is used.\n */\n redact?: ((text: string) => string) | false;\n /**\n * \"now\" (the default) sends alerts from this process. \"check\" sends nothing\n * from here: each alert is queued in the store and the next check, in a\n * process that delivers now, sends it (with triage). For a process that\n * records runs but cannot reach the network, such as a sandboxed backup job.\n * Its `alerts` and `triage` are not used.\n */\n deliver?: \"now\" | \"check\";\n /** Called with anything that goes wrong outside a job: the store failing, an alert channel failing, a triage timeout. */\n onError?: (error: unknown, where: string) => void;\n /** The clock. Tests use this. */\n now?: () => number;\n}\n\ninterface ExecuteResult<T> {\n run: Run;\n result: T | undefined;\n error: unknown;\n threw: boolean;\n}\n\nconst NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$/;\nconst TRIAGE_TIMEOUT_MS = 25_000;\n/** How long one channel may take to send one alert. */\nconst CHANNEL_TIMEOUT_MS = 15_000;\nconst PRUNE_INTERVAL_MS = 60 * 60_000;\n/** Undelivered alerts kept per job for retry; the oldest go first. */\nconst MAX_UNDELIVERED = 20;\n/**\n * Wall-clock time one check spends retrying undelivered alerts, across every\n * job. Once it is spent the rest wait for the next check.\n */\nconst RETRY_BUDGET_MS = 20_000;\n/** Reads and writes of one job's state before an update gives up on a store that keeps changing under it. */\nconst STATE_ATTEMPTS = 10;\n/** Runs read for a baseline, and the most read when failures crowd out the successes. */\nconst HISTORY_PAGE = BASELINE_WINDOW + 5;\nconst HISTORY_MAX = 200;\n\n/** Throws a clear error for options that would otherwise quietly turn a check off. */\nfunction validateDefinition(def: JobDefinition): void {\n const name = def.name;\n if (def.schedule !== undefined) {\n if (typeof def.schedule !== \"string\" || def.schedule.trim() === \"\") throw new Error(`job \"${name}\": schedule must be a non-empty string`);\n parseSchedule(def.schedule, def.timezone);\n }\n if (def.timezone !== undefined) {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: def.timezone });\n } catch {\n throw new Error(`job \"${name}\": timezone \"${def.timezone}\" is not an IANA timezone`);\n }\n }\n if (def.grace !== undefined) parseDuration(def.grace, \"grace\");\n if (def.timeout !== undefined && parseDuration(def.timeout, \"timeout\") <= 0) throw new Error(`job \"${name}\": timeout must be longer than zero`);\n if (def.maxDuration !== undefined && parseDuration(def.maxDuration, \"maxDuration\") <= 0) {\n throw new Error(`job \"${name}\": maxDuration must be longer than zero`);\n }\n if (def.failuresBeforeAlert !== undefined && !(Number.isInteger(def.failuresBeforeAlert) && def.failuresBeforeAlert >= 1)) {\n throw new Error(`job \"${name}\": failuresBeforeAlert must be a whole number, 1 or more (got ${String(def.failuresBeforeAlert)})`);\n }\n if (def.budget !== undefined) {\n if (typeof def.budget !== \"object\" || def.budget === null) throw new Error(`job \"${name}\": budget must be an object of { metric: ceiling }`);\n for (const [metric, ceiling] of Object.entries(def.budget)) {\n if (typeof ceiling !== \"number\" || !Number.isFinite(ceiling) || ceiling < 0) {\n throw new Error(`job \"${name}\": budget.${metric} must be a finite number, 0 or more (got ${String(ceiling)})`);\n }\n }\n }\n if (def.expect !== undefined && typeof def.expect !== \"string\" && !(def.expect instanceof RegExp) && typeof def.expect !== \"function\") {\n throw new Error(`job \"${name}\": expect must be a string, a RegExp or a function`);\n }\n}\n\nfunction sameState(a: JobState, b: JobState): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/** Identifies an alert across retries. */\nfunction alertKey(alert: Alert): string {\n return `${alert.type}|${alert.at}|${alert.run?.id ?? \"\"}`;\n}\n\nexport class CronWatch {\n readonly store: Store;\n readonly alerts: AlertChannel[];\n readonly triage: TriageFn | undefined;\n readonly sources: Source[];\n /** The secret handler() requests must carry, or null when none is set. */\n readonly cronSecret: string | null;\n readonly retentionMs: number;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n /** cronSecret was passed as null: handlers may run without a secret. */\n private readonly secretOptOut: boolean;\n private readonly redact: (text: string) => string;\n /** \"check\": queue alerts for another process's check instead of sending them. See CronWatchOptions.deliver. */\n private readonly deferDelivery: boolean;\n private readonly defaults: NonNullable<CronWatchOptions[\"defaults\"]>;\n private readonly definitions = new Map<string, JobDefinition>();\n private readonly synced = new Set<string>();\n /** The tail of each job's queue of state updates. See serial(). */\n private readonly queues = new Map<string, Promise<void>>();\n /** start() calls with an id still in flight, so two at once in this process record one run. */\n private readonly starting = new Map<string, Promise<RunHandle>>();\n private ready: Promise<void> | null = null;\n private checking: Promise<CheckResult> | null = null;\n private lastPruneAt = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private firstTick: ReturnType<typeof setTimeout> | null = null;\n private usingDefaultStore = false;\n private warnedNoSecret = false;\n private warnedDeferredStart = false;\n\n constructor(options: CronWatchOptions = {}) {\n this.store = options.store ?? (this.usingDefaultStore = true, memory());\n this.alerts = options.alerts ?? [consoleChannel()];\n this.triage = options.triage;\n this.sources = options.sources ?? [];\n const secret = options.cronSecret === undefined ? readEnv(\"CRON_SECRET\") : options.cronSecret;\n this.cronSecret = secret ? secret : null;\n this.secretOptOut = options.cronSecret === null;\n this.retentionMs = parseDuration(options.retention ?? \"30d\", \"retention\");\n this.defaults = options.defaults ?? {};\n this.now = options.now ?? (() => Date.now());\n const redact = options.redact;\n this.redact = redact === false ? (text) => text\n : typeof redact === \"function\" ? (text) => {\n try {\n const out: unknown = redact(text);\n if (typeof out !== \"string\") throw new TypeError(`redact must return a string, not ${out === null ? \"null\" : typeof out}`);\n return out;\n } catch (e) {\n // A broken redact must not stop the run finishing, nor leak what it was given.\n this.report(e, \"redact\");\n return redactSecrets(text);\n }\n }\n : redactSecrets;\n if (options.deliver !== undefined && options.deliver !== \"now\" && options.deliver !== \"check\") {\n throw new Error(`deliver must be \"now\" or \"check\", not ${JSON.stringify(options.deliver)}`);\n }\n this.deferDelivery = options.deliver === \"check\";\n this.onError = options.onError ?? ((error, where) => console.error(`[cronwatch] ${where}:`, error));\n }\n\n /** Declare a job. Call it once, at module level, and keep the handle. */\n job(name: string, options: JobOptions = {}): JobHandle {\n if (!NAME_RE.test(name)) {\n throw new Error(`job name \"${name}\" must be 1 to 120 characters of letters, digits, \".\", \"_\", \":\" or \"-\"`);\n }\n const definition: JobDefinition = { ...this.defaults, ...options, name };\n validateDefinition(definition);\n this.definitions.set(name, definition);\n this.synced.delete(name);\n return this.handle(definition);\n }\n\n /** Run a job by name without keeping a handle. Defines it on first use. */\n run<T>(name: string, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, options: JobOptions, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, optionsOrFn: JobOptions | JobFn<T>, maybeFn?: JobFn<T>): Promise<T> {\n const fn = typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!;\n const options = typeof optionsOrFn === \"function\" ? undefined : optionsOrFn;\n const handle = options || !this.definitions.has(name) ? this.job(name, options) : this.handle(this.definitions.get(name)!);\n return handle.run(fn);\n }\n\n /** The definitions declared in this process. */\n definedJobs(): JobDefinition[] {\n return [...this.definitions.values()];\n }\n\n /** A handle on a run started elsewhere, as job(name).resume(runId). The job must be declared in this process. */\n resumeRun(name: string, runId: string): Promise<RunHandle> {\n const definition = this.definitions.get(name);\n if (!definition) return Promise.reject(new Error(`resumeRun: job \"${name}\" is not declared; call job() first`));\n return this.resumeHandle(definition, runId);\n }\n\n private handle(definition: JobDefinition): JobHandle {\n const self = this;\n return {\n name: definition.name,\n definition,\n async run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T> {\n const outcome = await self.execute(definition, fn, options?.trigger ?? \"run\");\n if (outcome.threw) throw outcome.error;\n return outcome.result as T;\n },\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions) {\n const own = options?.secret;\n const secret = own === null ? null : own ? own : self.cronSecret;\n const optedOut = own === null || (!own && self.secretOptOut);\n return async (request: Request): Promise<Response> => {\n if (!secret && !optedOut && !isDevelopment()) {\n self.warnNoSecret();\n return json({ ok: false, error: \"CRON_SECRET is not set, so this job will not run for an unauthenticated request. Set it, or pass secret: null to handler() to allow anyone.\" }, 503);\n }\n if (secret) {\n const header = request.headers.get(\"authorization\") ?? \"\";\n if (!constantTimeEqual(header, `Bearer ${secret}`)) {\n return json({ ok: false, error: \"Unauthorized\" }, 401);\n }\n }\n const outcome = await self.execute(definition, (job) => fn(job, request), \"handler\");\n if (outcome.result instanceof Response) return outcome.result;\n const body = {\n ok: outcome.run.status === \"ok\",\n job: definition.name,\n run: outcome.run.id,\n status: outcome.run.status,\n durationMs: outcome.run.durationMs,\n // Error text only goes to a caller who proved they hold the secret.\n ...(secret && outcome.run.error ? { error: outcome.run.error.split(\"\\n\")[0] } : {}),\n };\n return json(body, outcome.run.status === \"ok\" ? 200 : 500);\n };\n },\n start(options?: StartOptions): Promise<RunHandle> {\n return self.startRun(definition, options ?? {});\n },\n resume(runId: string): Promise<RunHandle> {\n return self.resumeHandle(definition, runId);\n },\n };\n }\n\n private warnNoSecret(): void {\n if (this.warnedNoSecret) return;\n this.warnedNoSecret = true;\n this.onError(new Error(\"handler() refused a request because no CRON_SECRET is set; pass secret: null to allow unauthenticated requests\"), \"handler\");\n }\n\n /** onError, for places that must carry on even when onError itself throws. */\n private report(error: unknown, where: string): void {\n try {\n this.onError(error, where);\n } catch {\n // Nothing more can be done with it.\n }\n }\n\n private async ensureReady(): Promise<void> {\n if (!this.ready) {\n this.ready = (async () => {\n if (this.store.init) await this.store.init();\n if (this.usingDefaultStore && readEnv(\"NODE_ENV\") === \"production\") {\n console.warn(\"[cronwatch] using the in-memory store: runs and state are lost on restart. Pass a store from @cronwatch/sdk/sqlite or @cronwatch/sdk/postgres.\");\n }\n })().catch((error: unknown) => {\n // Let the next call try again rather than failing forever.\n this.ready = null;\n throw error;\n });\n }\n await this.ready;\n }\n\n private async sync(definition: JobDefinition): Promise<void> {\n await this.ensureReady();\n if (this.synced.has(definition.name)) return;\n await this.store.upsertJob(toStored(definition), this.now());\n this.synced.add(definition.name);\n }\n\n /**\n * Runs `fn` after every earlier state update for the same job has settled,\n * so two runs (or a run and a check) in this process never read and write\n * the job's state over each other. Other processes are coordinated by\n * updateState() instead.\n */\n private serial<T>(job: string, fn: () => Promise<T>): Promise<T> {\n const result = (this.queues.get(job) ?? Promise.resolve()).then(fn);\n const tail = result.then(() => {}, () => {});\n this.queues.set(job, tail);\n void tail.then(() => {\n if (this.queues.get(job) === tail) this.queues.delete(job);\n });\n return result;\n }\n\n private async readState(job: string): Promise<JobState> {\n return normalizeState(await this.store.getState(job), job);\n }\n\n /**\n * Every read-modify-write of a job's state goes through here. In turn with\n * this process's other updates to the job (serial()), it reads the state,\n * asks `change` for the next one, and writes it with the version one\n * higher, only if the stored version is still the one read. When another\n * process wrote in between, the write is refused and it starts again from\n * a fresh read, up to STATE_ATTEMPTS times. So `change` may run more than\n * once and must only compute: whatever it returns from the attempt that\n * was written is the result. Nothing is written when the state is\n * unchanged. Returns the state as stored.\n */\n private updateState<T>(\n job: string,\n change: (current: JobState) => { state: JobState; result: T } | Promise<{ state: JobState; result: T }>,\n ): Promise<{ state: JobState; result: T }> {\n return this.serial(job, async () => {\n for (let attempt = 1; ; attempt++) {\n const current = await this.readState(job);\n const { state, result } = await change(current);\n if (sameState(state, current)) return { state: current, result };\n const version = current.version ?? 0;\n const next: JobState = { ...state, version: version + 1 };\n if (await this.writeState(next, version)) return { state: next, result };\n if (attempt >= STATE_ATTEMPTS) {\n throw new Error(`the state of ${job} changed under ${STATE_ATTEMPTS} attempts in a row to update it; gave up`);\n }\n }\n });\n }\n\n /** A conditional write, or for a store without compareAndSetState, a plain one that always succeeds. */\n private async writeState(state: JobState, expectedVersion: number): Promise<boolean> {\n if (typeof this.store.compareAndSetState === \"function\") return this.store.compareAndSetState(state, expectedVersion);\n await this.store.setState(state);\n return true;\n }\n\n /**\n * Runs a function as a recorded run. The function always runs, whatever\n * the store is doing: store errors go to onError, and the result is the\n * function's own outcome. Never throws for the job's own error; see `threw`.\n */\n private async execute<T>(definition: JobDefinition, fn: JobFn<T>, trigger: string): Promise<ExecuteResult<T>> {\n const name = definition.name;\n const startedAt = this.now();\n const run: Run = {\n id: crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt,\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n this.onError(e, `recording ${name}`);\n }\n // Closing missed and stuck happens beside the job, which never waits on it.\n const started = recorded\n ? this.updateState(name, (before) => ({ state: onRunStart(before), result: undefined }))\n .then(() => {}, (e) => this.onError(e, `starting ${name}`))\n : Promise.resolve();\n\n const recorder = createRecorder(run);\n const timer = setTimeout(() => recorder.abort(), timeoutMs(definition));\n if (typeof timer === \"object\" && \"unref\" in timer) timer.unref();\n\n let result: T | undefined;\n let error: unknown;\n let threw = false;\n try {\n result = await fn(recorder.context);\n } catch (e) {\n error = e;\n threw = true;\n } finally {\n clearTimeout(timer);\n }\n\n const finishedAt = this.now();\n run.finishedAt = finishedAt;\n run.durationMs = Math.max(0, finishedAt - startedAt);\n run.metrics = recorder.metrics();\n run.output = recorder.output() ?? (typeof result === \"string\" ? capOutput(result) : null);\n this.conclude(definition, run, result, error, threw, recorder.expectText() ?? (typeof result === \"string\" ? result : null));\n\n await started;\n try {\n const ignored = await this.recordFinish(definition, run, recorded, finishedAt);\n if (ignored) this.report(new Error(`run ${run.id} of ${name} ${ignored}; ignored`), `finishing ${name}`);\n } catch (e) {\n this.onError(e, `recording ${name}`);\n }\n return { run, result, error, threw };\n }\n\n /**\n * Sets a finished run's status and error from how it ended, then redacts\n * its output and error. Shared by execute() and RunHandle.finish().\n */\n private conclude(definition: JobDefinition, run: Run, result: unknown, error: unknown, threw: boolean, expectText: string | null): void {\n if (threw) {\n run.status = \"failed\";\n run.error = errorMessage(error);\n } else if (result instanceof Response && result.status >= 400) {\n run.status = \"failed\";\n run.error = `HTTP ${result.status}${result.statusText ? ` ${result.statusText}` : \"\"}`;\n } else {\n const unmet = checkExpectation(definition.expect, expectText);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n } else {\n run.status = \"ok\";\n }\n }\n // Redacted after the expect check, so a rule can still match what was\n // logged. NULs go last, so not even a custom redact can store one.\n if (run.output !== null) run.output = stripNul(this.redact(run.output));\n if (run.error !== null) run.error = stripNul(this.redact(run.error));\n }\n\n /**\n * Writes a finished run and evaluates it. `recorded` says whether its\n * start was written; if not, it is inserted now. Returns why nothing was\n * recorded (another process finished the run first, say), or null. Throws\n * when the store does, so a handle can be finished again. Shared by\n * execute() and RunHandle.finish().\n */\n private async recordFinish(definition: JobDefinition, run: Run, recorded: boolean, finishedAt: number): Promise<string | null> {\n if (!recorded) {\n // The start was never written; the store may be back by now.\n await this.sync(definition);\n try {\n await this.store.insertRun(run);\n await this.finishRun(toStored(definition), run, finishedAt);\n return null;\n } catch (e) {\n // Another process may have recorded a run with this id meanwhile.\n const stored = await this.store.getRun(run.id).catch(() => null);\n if (!stored) throw e;\n if (stored.job !== run.job) return `belongs to job \"${stored.job}\"`;\n }\n }\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) return claim.ignored;\n if (!claim.lateAfterTimeout || run.status === \"ok\") await this.finishRun(toStored(definition), run, finishedAt);\n return null;\n }\n\n /** A conditional write (Store.updateRunIf), or for a store without one, a read then a plain write. */\n private async writeRunIf(run: Run, fromStatuses: Run[\"status\"][]): Promise<boolean> {\n if (typeof this.store.updateRunIf === \"function\") return this.store.updateRunIf(run, fromStatuses);\n const stored = await this.store.getRun(run.id);\n if (!stored || !fromStatuses.includes(stored.status)) return false;\n await this.store.updateRun(run);\n return true;\n }\n\n /**\n * Writes a finished run over its stored row, only while that row is still\n * running, or else still marked timeout by a check. Only the process whose\n * write lands goes on to evaluate the run; for the others it returns why\n * nothing was written. `lateAfterTimeout` means a check already counted\n * the run as a stuck failure: a late failure must not count twice, while\n * a late success still closes stuck and recovers. Throws when the store does.\n */\n private async claimFinish(run: Run): Promise<{ lateAfterTimeout: boolean } | { ignored: string }> {\n if (await this.writeRunIf(run, [\"running\"])) return { lateAfterTimeout: false };\n if (await this.writeRunIf(run, [\"timeout\"])) return { lateAfterTimeout: true };\n const stored = await this.store.getRun(run.id);\n return { ignored: stored ? `was already finished as ${stored.status}` : \"was not found\" };\n }\n\n /** job.start(): records a running run and returns a handle to finish it. See JobHandle.start. */\n private async startRun(definition: JobDefinition, options: StartOptions): Promise<RunHandle> {\n const id = options.id;\n if (id === undefined) return this.recordStart(definition, options.trigger);\n checkRunId(definition.name, id, \"start\");\n // Keyed by job as well, so another job's start with the same id is not\n // handed this job's run: it fails as it would one call later.\n const key = `${definition.name}\\n${id}`;\n const inFlight = this.starting.get(key);\n if (inFlight) return inFlight;\n const started = this.recordStart(definition, options.trigger, id).finally(() => {\n if (this.starting.get(key) === started) this.starting.delete(key);\n });\n this.starting.set(key, started);\n return started;\n }\n\n /**\n * The start of execute() without the function: the run is inserted and\n * missed and stuck close (onRunStart). A store that fails is reported and\n * the handle inserts the finished run instead, as execute() does.\n */\n private async recordStart(definition: JobDefinition, trigger = \"start\", id?: string): Promise<RunHandle> {\n const name = definition.name;\n if (id !== undefined) {\n let stored: Run | null = null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(id);\n } catch (e) {\n this.onError(e, `recording ${name}`);\n }\n if (stored) return this.existingHandle(definition, stored);\n }\n const run: Run = {\n id: id ?? crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt: this.now(),\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n // Another process may have started a run with this id first.\n const stored = id === undefined ? null : await this.store.getRun(id).catch(() => null);\n if (stored) return this.existingHandle(definition, stored);\n this.onError(e, `recording ${name}`);\n }\n if (recorded) {\n await this.updateState(name, (before) => ({ state: onRunStart(before), result: undefined }))\n .catch((e: unknown) => this.onError(e, `starting ${name}`));\n }\n return this.runHandle(definition, run.id, run, recorded, null);\n }\n\n /** job.resume() and cw.resumeRun(). A store that cannot be read is reported, and finish() reads it again. */\n private async resumeHandle(definition: JobDefinition, runId: string): Promise<RunHandle> {\n checkRunId(definition.name, runId, \"resume\");\n let stored: Run | null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(runId);\n } catch (e) {\n this.onError(e, `resuming ${definition.name}`);\n return this.runHandle(definition, runId, null, true, null);\n }\n if (!stored) return this.runHandle(definition, runId, null, true, \"was not found\");\n return this.existingHandle(definition, stored);\n }\n\n /** A handle on a stored run. One still running, or marked timeout by a check, can be finished. */\n private existingHandle(definition: JobDefinition, stored: Run): RunHandle {\n if (stored.job !== definition.name) {\n throw new Error(`run \"${stored.id}\" belongs to job \"${stored.job}\", not \"${definition.name}\"`);\n }\n const finished = stored.status === \"ok\" || stored.status === \"failed\";\n return this.runHandle(definition, stored.id, stored, true, finished ? `already finished as ${stored.status}` : null);\n }\n\n /**\n * The handle itself. `base` is the run as last known here, `recorded`\n * whether its start is in the store, and `inactive` why finish() has\n * nothing to do, or null. Lines and metrics wait in the handle until\n * flush() or finish() merges them onto a fresh read of the stored run.\n */\n private runHandle(definition: JobDefinition, id: string, base: Run | null, recorded: boolean, inactive: string | null): RunHandle {\n const self = this;\n const name = definition.name;\n const fresh = () => createRecorder({ id, job: name, startedAt: base?.startedAt ?? 0 } as Run);\n let recorder = fresh();\n let finished = inactive !== null;\n let finishCalled = false;\n /**\n * The first OUTPUT_CAP characters of every line flushed from this\n * handle, unredacted, or null before the first flush. The stored output\n * keeps only the tail, so without it an expect rule at finish() would\n * miss a line logged early, which run() would have seen.\n */\n let head: string | null = null;\n let queue: Promise<unknown> = Promise.resolve();\n const inTurn = <T>(fn: () => Promise<T>): Promise<T> => {\n const result = queue.then(fn);\n queue = result.catch(() => {});\n return result;\n };\n const ignored = (why: string) => self.report(new Error(`run ${id} of ${name} ${why}; ignored`), `finishing ${name}`);\n\n const finish = (outcome?: RunOutcome | string): Promise<Run | null> => {\n if (finishCalled) {\n ignored(\"was already finished by this handle\");\n return Promise.resolve(null);\n }\n finishCalled = true;\n const wasInactive = finished;\n finished = true;\n // The store failed part way and nothing was recorded, so the handle can be finished again.\n const retryable = (error: unknown): null => {\n finishCalled = false;\n finished = false;\n self.report(error, `finishing ${name}`);\n return null;\n };\n return inTurn(async () => {\n if (wasInactive) {\n ignored(inactive!);\n return null;\n }\n let from = base;\n if (recorded) {\n try {\n from = (await self.store.getRun(id)) ?? base;\n } catch (e) {\n return retryable(e);\n }\n }\n if (!from) {\n ignored(\"was not found\");\n return null;\n }\n if (from.job !== name) {\n ignored(`belongs to job \"${from.job}\"`);\n return null;\n }\n if (from.status === \"ok\" || from.status === \"failed\") {\n ignored(`was already finished as ${from.status}`);\n return null;\n }\n const failed = typeof outcome === \"object\" && outcome !== null && \"error\" in outcome;\n const result = typeof outcome === \"string\" ? outcome : failed ? undefined : outcome?.result;\n const error = failed ? (outcome as { error: unknown }).error : undefined;\n const finishedAt = self.now();\n const added = recorder.output() ?? (typeof result === \"string\" ? capOutput(result) : null);\n const run: Run = {\n ...from,\n status: \"running\",\n finishedAt,\n durationMs: Math.max(0, finishedAt - from.startedAt),\n error: null,\n output: joinOutput(from.output, added),\n metrics: { ...from.metrics, ...recorder.metrics() },\n };\n const expectText = joinLines(head, joinLines(from.output, recorder.expectText() ?? (typeof result === \"string\" ? result : null)));\n self.conclude(definition, run, result, error, failed, expectText);\n let why: string | null;\n try {\n why = await self.recordFinish(definition, run, recorded, finishedAt);\n } catch (e) {\n return retryable(e);\n }\n if (why) {\n ignored(why);\n return null;\n }\n return run;\n });\n };\n\n return {\n id,\n job: name,\n startedAt: base?.startedAt ?? null,\n get active() {\n return !finished;\n },\n log: (...parts: unknown[]) => recorder.context.log(...parts),\n metric: (metric: string, value: number) => recorder.context.metric(metric, value),\n metrics: (values: Record<string, number>) => recorder.context.metrics(values),\n flush: () => inTurn(async () => {\n if (finished || !recorded) return;\n const lines = recorder.output();\n const metrics = recorder.metrics();\n if (lines === null && Object.keys(metrics).length === 0) return;\n // Lines logged while this waits on the store go to a new recorder.\n const taken = recorder;\n recorder = fresh();\n const putBack = () => {\n const later = recorder;\n recorder = fresh();\n for (const text of [taken.expectText(), later.expectText()]) if (text !== null) recorder.context.log(text);\n recorder.context.metrics({ ...taken.metrics(), ...later.metrics() });\n };\n try {\n const stored = await self.store.getRun(id);\n // Not running: the lines stay here for finish(), which reports why it cannot record them.\n if (!stored || stored.status !== \"running\") return putBack();\n if (stored.job !== name) {\n putBack();\n self.report(new Error(`run ${id} of ${name} belongs to job \"${stored.job}\"; ignored`), `flushing ${name}`);\n return;\n }\n const output = lines === null ? stored.output : joinOutput(stored.output, stripNul(self.redact(lines)));\n // Only over a row still running, so a flush never undoes a finish written meanwhile.\n if (!(await self.writeRunIf({ ...stored, output, metrics: { ...stored.metrics, ...metrics } }, [\"running\"]))) return putBack();\n const text = taken.expectText();\n if (text !== null && (head === null || head.length < OUTPUT_CAP)) head = (joinLines(head, text) ?? \"\").slice(0, OUTPUT_CAP);\n } catch (e) {\n putBack();\n self.report(e, `flushing ${name}`);\n }\n }),\n finish,\n fail: (error: unknown) => finish({ error }),\n };\n }\n\n /**\n * Record a run that happened outside this process, for a Source. Its job\n * must be declared with job() first. Runs are keyed by id: a new one is\n * inserted, a stored one still running (or marked timeout by a check) is\n * finished when this one is not running, and anything else is left alone,\n * so recording the same run twice changes nothing. Finishing is\n * conditional (see Store.updateRunIf): when two processes record the same\n * finish, only the one whose write lands evaluates it, and the other\n * reports it as already finished. A stored run of another job is left\n * alone and reported. A finished run is judged as if it had been wrapped\n * here (expect, failures, duration, budgets) and its output and error are\n * redacted the same way; one finishing after a check marked it timeout is\n * judged only when it succeeded, as RunHandle.finish() does. Returns the\n * alerts it sent.\n */\n async recordRun(input: Run, options: RecordRunOptions = {}): Promise<Alert[]> {\n const declared = this.definitions.get(input.job);\n if (!declared) throw new Error(`recordRun: job \"${input.job}\" is not declared; call job() first`);\n await this.sync(declared);\n const run: Run = { ...input, metrics: { ...input.metrics } };\n if (run.status === \"ok\") {\n const unmet = checkExpectation(declared.expect, run.output);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n }\n }\n if (run.output !== null) run.output = stripNul(this.redact(capOutput(run.output)));\n if (run.error !== null) run.error = stripNul(this.redact(capOutput(run.error)));\n const evaluate = options.evaluate !== false;\n const definition = toStored(declared);\n\n const stored = await this.store.getRun(run.id);\n if (stored) return this.recordOver(definition, stored, run, evaluate);\n try {\n await this.store.insertRun(run);\n } catch (e) {\n // Another process recorded it first.\n const again = await this.store.getRun(run.id).catch(() => null);\n if (again) return this.recordOver(definition, again, run, evaluate);\n throw e;\n }\n if (!evaluate) return [];\n await this.updateState(run.job, (before) => ({ state: onRunStart(before), result: undefined }));\n if (run.status === \"running\") return [];\n return this.finishRun(definition, run, this.now());\n }\n\n /** recordRun() for a run already stored. */\n private async recordOver(definition: StoredJobDefinition, stored: Run, run: Run, evaluate: boolean): Promise<Alert[]> {\n if (stored.job !== run.job) {\n this.report(new Error(`run ${run.id} of ${run.job} belongs to job \"${stored.job}\"; ignored`), `recording ${run.job}`);\n return [];\n }\n if ((stored.status !== \"running\" && stored.status !== \"timeout\") || run.status === \"running\") return [];\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) {\n this.report(new Error(`run ${run.id} of ${run.job} ${claim.ignored}; ignored`), `recording ${run.job}`);\n return [];\n }\n if (!evaluate || (claim.lateAfterTimeout && run.status !== \"ok\")) return [];\n return this.finishRun(definition, run, this.now());\n }\n\n /**\n * Evaluate a finished run (ok, failed, or timed out by a check), already\n * written, against the job's state and send what that produces. Never throws.\n */\n private async finishRun(definition: StoredJobDefinition, run: Run, now: number): Promise<Alert[]> {\n let drafts: AlertDraft[];\n try {\n let history: Run[] | null = null;\n ({ result: drafts } = await this.updateState(run.job, async (previous) => {\n history ??= await this.history(run);\n const settled = applySilence(previous, onRunFinish(definition, run, previous, history, now), now);\n return { state: settled.state, result: settled.alerts };\n }));\n } catch (e) {\n this.onError(e, `evaluating ${run.job}`);\n return [];\n }\n return this.dispatch(drafts, definition, now);\n }\n\n /**\n * The runs before `run`, newest first, with up to BASELINE_WINDOW\n * successful ones when the store has them. One small read normally; a\n * larger one only when failures crowd the successes out of it.\n */\n private async history(run: Run): Promise<Run[]> {\n let runs = await this.store.listRuns(run.job, HISTORY_PAGE);\n if (runs.length === HISTORY_PAGE && !hasFullBaseline(runs.filter((r) => r.id !== run.id))) {\n runs = await this.store.listRuns(run.job, HISTORY_MAX);\n }\n return runs.filter((r) => r.id !== run.id);\n }\n\n /**\n * Look for missed and stuck runs across every job, send alerts, retry\n * alerts no channel accepted, and prune old runs. Call it from an interval\n * (start()), a cron hitting the mounted routes, or by hand. Concurrent\n * calls share one check.\n */\n check(): Promise<CheckResult> {\n if (!this.checking) {\n this.checking = this.runCheck().finally(() => {\n this.checking = null;\n });\n }\n return this.checking;\n }\n\n private async runCheck(): Promise<CheckResult> {\n await this.ensureReady();\n const alerts: Alert[] = [];\n for (const source of this.sources) {\n try {\n alerts.push(...((await source.sync(this)) ?? []));\n } catch (e) {\n this.onError(e, `source ${source.name}`);\n }\n }\n for (const definition of this.definitions.values()) await this.sync(definition);\n const now = this.now();\n\n // Runs that never reported back. One that cannot be judged (its job's\n // stored timeout no longer parses, say) is reported and skipped.\n for (const run of await this.store.runningRuns()) {\n try {\n const declared = this.definitions.get(run.job);\n const definition = declared ? toStored(declared) : (await this.store.getJob(run.job))?.definition;\n if (!definition || !isStuck(definition, run, now)) continue;\n const timeout = timeoutMs(definition);\n run.status = \"timeout\";\n run.finishedAt = now;\n run.durationMs = now - run.startedAt;\n run.error = `Still running after ${formatDuration(timeout)}; marked as timed out`;\n // Only over a row still running: a finish that landed meanwhile wins.\n if (!(await this.writeRunIf(run, [\"running\"]))) continue;\n alerts.push(...(await this.finishRun(definition, run, now)));\n } catch (e) {\n this.onError(e, `checking ${run.job}`);\n }\n }\n\n // Each job on its own: one that cannot be evaluated is reported, shown\n // as failing (see unevaluableSummary) and does not stop the others.\n const jobs: JobSummary[] = [];\n const retries = { spentMs: 0 };\n for (const stored of await this.store.listJobs()) {\n try {\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW);\n let nextExpectedAt: number | null = null;\n const { state, result: drafts } = await this.updateState(stored.name, (previous) => {\n const evaluation = onCheck(stored.definition, stored, recent[0] ?? null, previous, now);\n nextExpectedAt = evaluation.nextExpectedAt;\n const settled = applySilence(previous, evaluation, now);\n return { state: settled.state, result: settled.alerts };\n });\n alerts.push(...(await this.retryUndelivered(stored.name, state, now, retries)));\n alerts.push(...(await this.dispatch(drafts, stored.definition, now)));\n jobs.push(summarize(stored, recent, state, nextExpectedAt, now));\n } catch (e) {\n this.onError(e, `checking ${stored.name}`);\n jobs.push(await this.unevaluable(stored, now));\n }\n }\n\n let pruned = 0;\n if (now - this.lastPruneAt > PRUNE_INTERVAL_MS) {\n this.lastPruneAt = now;\n try {\n pruned = await this.store.prune(now - this.retentionMs);\n } catch (e) {\n this.onError(e, \"pruning\");\n }\n }\n\n return { checkedAt: now, jobs, alerts, pruned };\n }\n\n /** A job's summary and its newest runs, without alerting. A job that cannot be evaluated is reported and shown as failing. */\n private async snapshot(stored: StoredJob, now: number, runs: number): Promise<{ job: JobSummary; runs: Run[] }> {\n let recent: Run[] = [];\n try {\n recent = await this.store.listRuns(stored.name, Math.max(runs, BASELINE_WINDOW));\n const state = await this.readState(stored.name);\n const { nextExpectedAt } = onCheck(stored.definition, stored, recent[0] ?? null, state, now);\n return { job: summarize(stored, recent, state, nextExpectedAt, now), runs: recent.slice(0, runs) };\n } catch (e) {\n this.onError(e, `reading ${stored.name}`);\n return { job: await this.unevaluable(stored, now), runs: recent.slice(0, runs) };\n }\n }\n\n /** The summary of a job whose evaluation failed, from whatever can still be read. */\n private async unevaluable(stored: StoredJob, now: number): Promise<JobSummary> {\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW).catch((): Run[] => []);\n const state = await this.readState(stored.name).catch(() => emptyState(stored.name));\n return unevaluableSummary(stored, recent, state, now);\n }\n\n /** Every job the store knows about, with its health. Does not send alerts. */\n async jobs(): Promise<JobSummary[]> {\n return (await this.jobsWithRuns(0)).map((entry) => entry.job);\n }\n\n /** Every job's summary with its newest `limit` runs, read together. What the dashboard shows. */\n async jobsWithRuns(limit = 20): Promise<{ job: JobSummary; runs: Run[] }[]> {\n await this.ensureReady();\n for (const definition of this.definitions.values()) await this.sync(definition);\n const now = this.now();\n const out: { job: JobSummary; runs: Run[] }[] = [];\n for (const stored of await this.store.listJobs()) out.push(await this.snapshot(stored, now, clampLimit(limit, 20, 0)));\n return out;\n }\n\n async jobSummary(name: string): Promise<JobSummary | null> {\n await this.ensureReady();\n const definition = this.definitions.get(name);\n if (definition) await this.sync(definition);\n const stored = await this.store.getJob(name);\n if (!stored) return null;\n return (await this.snapshot(stored, this.now(), 0)).job;\n }\n\n /** A job's runs, newest first. `limit` is a whole number from 1 to 500. */\n async runs(name: string, limit = 50): Promise<Run[]> {\n await this.ensureReady();\n return this.store.listRuns(name, clampLimit(limit, 50, 1));\n }\n\n async getRun(id: string): Promise<Run | null> {\n await this.ensureReady();\n return this.store.getRun(id);\n }\n\n /** Stop alerts for a job for a while. State keeps updating underneath. */\n async silence(name: string, duration: Duration): Promise<JobState> {\n const ms = parseDuration(duration, \"silence duration\");\n return this.patchState(name, (state) => { state.silencedUntil = this.now() + ms; });\n }\n\n async unsilence(name: string): Promise<JobState> {\n return this.patchState(name, (state) => { state.silencedUntil = null; });\n }\n\n /** Read, change and write one job's state, in turn with every other update to it. */\n private async patchState(name: string, change: (state: JobState) => void): Promise<JobState> {\n await this.ensureReady();\n const { state } = await this.updateState(name, (current) => {\n const next = normalizeState(current, name);\n change(next);\n return { state: next, result: undefined };\n });\n return state;\n }\n\n /** Remove a job and its runs from the store. A job still declared in code comes back on its next run. */\n async forget(name: string): Promise<void> {\n await this.ensureReady();\n this.definitions.delete(name);\n this.synced.delete(name);\n await this.store.deleteJob(name);\n }\n\n /** The dashboard and JSON API as fetch-style handlers. See createRoutes(). */\n routes(options?: RoutesOptions): Routes {\n return createRoutes(this, options);\n }\n\n /**\n * Check on an interval, for long-running servers. Default every minute.\n * Not for serverless functions or Cloudflare Workers, where nothing runs\n * between requests: call check() from a cron there instead.\n */\n start(every: Duration = \"1m\"): void {\n if (this.timer) return;\n const ms = Math.max(5_000, parseDuration(every, \"check interval\"));\n if (this.deferDelivery && !this.warnedDeferredStart) {\n this.warnedDeferredStart = true;\n console.warn('[cronwatch] start() was called with deliver: \"check\", so these checks send no alerts. Another process must run checks with deliver: \"now\" (the default) to send them.');\n }\n const tick = () => this.check().catch((e) => this.onError(e, \"check\"));\n this.timer = setInterval(tick, ms);\n if (typeof this.timer === \"object\" && \"unref\" in this.timer) this.timer.unref();\n this.firstTick = setTimeout(() => {\n this.firstTick = null;\n void tick();\n }, 1_000);\n if (typeof this.firstTick === \"object\" && \"unref\" in this.firstTick) this.firstTick.unref();\n }\n\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n if (this.firstTick) clearTimeout(this.firstTick);\n this.timer = null;\n this.firstTick = null;\n }\n\n async close(): Promise<void> {\n this.stop();\n if (this.store.close) await this.store.close();\n }\n\n /**\n * Compose, triage and send each draft. The state was saved before this\n * (updateState), so a slow channel holds up nothing else; afterwards only\n * the delivery fields are written back, onto a fresh read of the state.\n */\n private async dispatch(drafts: AlertDraft[], definition: StoredJobDefinition, now: number): Promise<Alert[]> {\n if (drafts.length === 0) return [];\n const composed: Alert[] = [];\n const delivered: Alert[] = [];\n const failed: Alert[] = [];\n for (const draft of drafts) {\n const alert = composeAlert(draft, definition, now);\n if (this.deferDelivery) {\n failed.push(alert);\n } else {\n if (this.triage && alert.type !== \"recovered\") await this.addTriage(alert, TRIAGE_TIMEOUT_MS);\n (await this.deliver(alert) ? delivered : failed).push(alert);\n }\n composed.push(alert);\n }\n await this.recordDelivery(definition.name, delivered, failed, [], now);\n return composed;\n }\n\n /**\n * Send the alerts that no channel accepted last time, once each, oldest\n * first. `state` is the job's state as this check left it: an alert that\n * no longer describes it (staleAlert) is dropped instead. Retries across a\n * check share RETRY_BUDGET_MS of wall-clock time; once it is spent the rest\n * stay queued for the next check.\n */\n private async retryUndelivered(name: string, state: JobState, now: number, budget: { spentMs: number }): Promise<Alert[]> {\n const pending = state.undelivered ?? [];\n if (pending.length === 0 || isSilenced(state, now) || this.deferDelivery) return [];\n const delivered: Alert[] = [];\n const failed: Alert[] = [];\n const dropped = pending.filter((alert) => staleAlert(alert, state));\n for (const alert of pending) {\n if (dropped.includes(alert)) continue;\n const left = RETRY_BUDGET_MS - budget.spentMs;\n if (left <= 0) break;\n const started = Date.now();\n // An alert queued by a process that delivers at check time was never\n // triaged. One that was tried (triage: null) is not tried again.\n if (this.triage && alert.type !== \"recovered\" && alert.triage === undefined) await this.addTriage(alert, Math.min(TRIAGE_TIMEOUT_MS, left));\n (await this.deliver(alert) ? delivered : failed).push(alert);\n budget.spentMs += Math.max(0, Date.now() - started);\n }\n await this.recordDelivery(name, delivered, failed, dropped, now);\n return delivered;\n }\n\n /**\n * Mark delivered alerts done, drop stale ones, and keep failed ones for the\n * next check. A failed alert replaces its stored copy, so a triage made on\n * this attempt is kept. lastAlertAt moves only on a delivery.\n */\n private async recordDelivery(name: string, delivered: Alert[], failed: Alert[], dropped: Alert[], now: number): Promise<void> {\n try {\n const { result: trimmed } = await this.updateState(name, (previous) => {\n const state = normalizeState(previous, name);\n const done = new Set([...delivered, ...dropped].map(alertKey));\n const retried = new Map(failed.map((a) => [alertKey(a), a]));\n const kept = state.undelivered!.filter((a) => !done.has(alertKey(a))).map((a) => retried.get(alertKey(a)) ?? a);\n const known = new Set(kept.map(alertKey));\n kept.push(...failed.filter((a) => !known.has(alertKey(a))));\n state.undelivered = kept.slice(-MAX_UNDELIVERED);\n if (delivered.length > 0) state.lastAlertAt = now;\n return { state, result: Math.max(0, kept.length - MAX_UNDELIVERED) };\n });\n if (trimmed > 0) {\n this.onError(\n new Error(`${trimmed} undelivered alert${trimmed === 1 ? \"\" : \"s\"} for ${name} dropped: only the newest ${MAX_UNDELIVERED} are kept for retry`),\n `alert queue for ${name}`,\n );\n }\n } catch (e) {\n this.onError(e, `recording alert delivery for ${name}`);\n }\n }\n\n /** Send to every channel at once. True when at least one accepted it, or there are none. */\n private async deliver(alert: Alert): Promise<boolean> {\n if (this.alerts.length === 0) return true;\n const results = await Promise.all(\n this.alerts.map(async (channel) => {\n try {\n await withTimeout(channel.send(alert, { onError: (e) => this.report(e, `alert channel ${channel.name}`) }), CHANNEL_TIMEOUT_MS);\n return true;\n } catch (e) {\n this.onError(e, `alert channel ${channel.name}`);\n return false;\n }\n }),\n );\n return results.includes(true);\n }\n\n /** Sets alert.triage to the diagnosis, or to null when there is none, so it is tried once per alert. */\n private async addTriage(alert: Alert, timeout: number): Promise<void> {\n const controller = new AbortController();\n try {\n const recentRuns = await this.store.listRuns(alert.job, 5);\n const diagnosis = await withTimeout(this.triage!({ alert, recentRuns, signal: controller.signal }), timeout);\n alert.triage = typeof diagnosis === \"string\" && diagnosis !== \"\" ? diagnosis : null;\n } catch (e) {\n controller.abort();\n alert.triage = null;\n this.onError(e, `triage for ${alert.job}`);\n }\n }\n}\n\n/** Run ids that start with this belong to the pg_cron source (see @cronwatch/sdk/pg-cron). */\nexport const RESERVED_RUN_ID_PREFIX = \"pgcron:\";\n\n/** Throws for a run id no store could hold, or one reserved for the pg_cron source. */\nfunction checkRunId(job: string, id: unknown, method: string): void {\n if (typeof id !== \"string\" || id.length === 0 || id.length > 200) {\n throw new Error(`job \"${job}\": ${method}() needs a run id of 1 to 200 characters (got ${typeof id === \"string\" ? `${id.length} characters` : typeof id})`);\n }\n if (id.startsWith(RESERVED_RUN_ID_PREFIX)) {\n throw new Error(`job \"${job}\": ${method}() cannot take a run id starting with \"${RESERVED_RUN_ID_PREFIX}\", which the pg_cron source uses for its runs`);\n }\n}\n\n/** Two stretches of text as one, a line apart; either may be null. */\nfunction joinLines(before: string | null, after: string | null): string | null {\n if (before === null || before === \"\") return after;\n if (after === null) return before;\n return `${before}\\n${after}`;\n}\n\n/** Output appended to stored output, capped like any run's. */\nfunction joinOutput(before: string | null, after: string | null): string | null {\n const joined = joinLines(before, after);\n return joined === null ? null : capOutput(joined);\n}\n\n/** A whole number in range, or the fallback for anything that is not a number. */\nfunction clampLimit(limit: number, fallback: number, min: number): number {\n const n = typeof limit === \"number\" && Number.isFinite(limit) ? Math.trunc(limit) : fallback;\n return Math.min(500, Math.max(min, n));\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const t = setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms);\n if (typeof t === \"object\" && \"unref\" in t) t.unref();\n promise.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });\n });\n}\n\n/** Writes alerts to the console. The default channel. */\nexport function consoleChannel(): AlertChannel {\n return {\n name: \"console\",\n async send(alert) {\n const line = `[cronwatch] ${alert.title}\\n${alert.message}${alert.triage ? `\\nTriage: ${alert.triage}` : \"\"}`;\n if (alert.type === \"recovered\") console.info(line);\n else console.error(line);\n },\n };\n}\n\n/** Wrap any function as an alert channel. */\nexport function custom(name: string, send: (alert: Alert) => Promise<void> | void): AlertChannel {\n return { name, send: async (alert) => { await send(alert); } };\n}\n\nexport type { Condition };\n","import { CronWatch } from \"./client.js\";\nimport type { CronWatchOptions } from \"./client.js\";\n\n/**\n * Create a CronWatch client. One per app, at module level:\n *\n * export const cw = cronwatch({ store: sqlite({ path: \"./data/cronwatch.db\" }), alerts: [slack({ webhookUrl })] });\n * export const nightly = cw.job(\"nightly-report\", { schedule: \"0 2 * * *\", grace: \"15m\" });\n */\nexport function cronwatch(options: CronWatchOptions = {}): CronWatch {\n return new CronWatch(options);\n}\n\nexport { CronWatch, consoleChannel, custom } from \"./client.js\";\nexport type { CronWatchOptions, HandlerFn, HandlerOptions, JobFn, JobHandle, RecordRunOptions, RunHandle, RunOutcome, Source, SourceHost, StartOptions } from \"./client.js\";\nexport type { JobContext } from \"./job.js\";\nexport { memory } from \"./stores/memory.js\";\nexport { createRoutes } from \"./routes/index.js\";\nexport type { FetchHandler, Routes, RoutesOptions } from \"./routes/index.js\";\nexport { parseDuration, formatDuration } from \"./duration.js\";\nexport { parseSchedule, nextFire } from \"./schedule.js\";\nexport type { ParsedSchedule } from \"./schedule.js\";\nexport { composeAlert } from \"./format.js\";\nexport type {\n Alert,\n AlertChannel,\n AlertDetails,\n AlertDraft,\n AlertType,\n BudgetBreach,\n ChannelContext,\n CheckResult,\n Condition,\n Duration,\n ExpectRule,\n JobDefinition,\n JobHealth,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n RunStatus,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageContext,\n TriageFn,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"sources":["../src/duration.ts","../src/env.ts","../src/schedule.ts","../src/stats.ts","../src/evaluate.ts","../src/format.ts","../src/http.ts","../src/output.ts","../src/job.ts","../src/serialize.ts","../src/routes/escape.ts","../src/routes/icons.ts","../src/routes/pwa.ts","../src/routes/timeline.ts","../src/routes/html.ts","../src/routes/index.ts","../src/stores/memory.ts","../src/client.ts","../src/index.ts"],"names":["Cron","graceMs","when","times","t","r","cache","tail"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Duration } from \"./types.js\";\n\nconst UNIT_MS: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n};\n\n/**\n * \"15m\" -> 900000. Accepts a plain number of milliseconds, and compound\n * strings such as \"1h30m\". Whitespace between parts is fine.\n */\nexport function parseDuration(value: Duration, label = \"duration\"): number {\n if (typeof value === \"number\") {\n if (!Number.isFinite(value) || value < 0) throw new Error(`${label} must be a non-negative number of milliseconds`);\n return value;\n }\n const text = value.trim().toLowerCase();\n if (text === \"\") throw new Error(`${label} is empty`);\n const re = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g;\n let total = 0;\n let consumed = \"\";\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n total += parseFloat(match[1]!) * UNIT_MS[match[2]!]!;\n consumed += match[0];\n }\n if (consumed.replace(/\\s+/g, \"\") !== text.replace(/\\s+/g, \"\")) {\n throw new Error(`${label} \"${value}\" is not a duration like \"15m\", \"1h30m\" or \"90s\"`);\n }\n return Math.round(total);\n}\n\n/** 90000 -> \"1m 30s\". For messages, not for parsing back. */\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms)) return \"?\";\n if (ms < 1000) return `${Math.round(ms)}ms`;\n const parts: string[] = [];\n let rest = Math.round(ms / 1000);\n const units: [string, number][] = [[\"d\", 86_400], [\"h\", 3_600], [\"m\", 60], [\"s\", 1]];\n for (const [unit, size] of units) {\n if (rest >= size) {\n const n = Math.floor(rest / size);\n rest -= n * size;\n parts.push(`${n}${unit}`);\n }\n if (parts.length === 2) break;\n }\n return parts.join(\" \") || \"0s\";\n}\n\n/** \"5 minutes ago\", \"in 2h\". Relative to `now`. */\nexport function formatRelative(at: number, now: number): string {\n const diff = at - now;\n const abs = Math.abs(diff);\n const text = abs < 5_000 ? \"now\" : formatDuration(abs);\n if (abs < 5_000) return text;\n return diff < 0 ? `${text} ago` : `in ${text}`;\n}\n","/**\n * Environment variables, read only where there is a `process` to read them\n * from. Cloudflare Workers without nodejs_compat have none: there every value\n * comes from the options, which is where a Worker passes its env bindings.\n */\nexport function readEnv(name: string): string | undefined {\n return typeof process === \"undefined\" || !process.env ? undefined : process.env[name];\n}\n\n/** NODE_ENV is \"development\" or \"test\". Written out in full so bundlers that inline process.env.NODE_ENV still can. */\nexport function isDevelopment(): boolean {\n if (typeof process === \"undefined\" || !process.env) return false;\n const mode = process.env.NODE_ENV;\n return mode === \"development\" || mode === \"test\";\n}\n","import { Cron } from \"croner\";\nimport { parseDuration } from \"./duration.js\";\n\nexport interface ParsedSchedule {\n kind: \"cron\" | \"interval\";\n source: string;\n /** The IANA timezone a cron is read in, when one was given. */\n timezone?: string;\n /** For intervals, the period in milliseconds. */\n everyMs?: number;\n}\n\nconst cache = new Map<string, ParsedSchedule>();\n/** The croner instance behind each cron schedule, kept out of the public type. */\nconst crons = new WeakMap<ParsedSchedule, Cron>();\n\n/** How early a run may start and still count for the fire it was meant for. */\nexport const EARLY_SLACK_MS = 60_000;\n\n/**\n * \"0 2 * * *\" (cron, five or six fields), \"@hourly\", or \"every 5m\".\n * Parsed once per (schedule, timezone) pair and cached. The croner instance\n * gets no callback, so it schedules nothing; it is only used to compute fire\n * times. Without a timezone the expression is read in the process timezone,\n * like crontab. Vercel and GitHub Actions run their crons in UTC, so pass\n * timezone: \"UTC\" for those.\n */\nexport function parseSchedule(schedule: string, timezone?: string): ParsedSchedule {\n const key = `${timezone ?? \"\"}|${schedule}`;\n const hit = cache.get(key);\n if (hit) return hit;\n\n const text = schedule.trim();\n const every = /^every\\s+(.+)$/i.exec(text);\n let parsed: ParsedSchedule;\n if (every) {\n const everyMs = parseDuration(every[1]!, \"schedule interval\");\n if (everyMs < 1000) throw new Error(`schedule \"${schedule}\" is shorter than one second`);\n parsed = { kind: \"interval\", source: text, everyMs };\n } else {\n let cron: Cron;\n try {\n cron = new Cron(text, timezone ? { timezone } : {});\n } catch (error) {\n throw new Error(`schedule \"${schedule}\" is not a cron expression or \"every <duration>\": ${(error as Error).message}`);\n }\n parsed = { kind: \"cron\", source: text, ...(timezone ? { timezone } : {}) };\n crons.set(parsed, cron);\n }\n cache.set(key, parsed);\n return parsed;\n}\n\n/**\n * The first fire strictly after `from`, or null when the cron never fires\n * again. croner answers with times in the past when asked from inside the\n * hour that repeats when clocks go back, so its answers are filtered, and a\n * stretch of nothing but past times is stepped over an hour at a time.\n */\nfunction fireAfter(parsed: ParsedSchedule, from: number): number | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n let probe = from;\n for (let attempt = 0; attempt < 4; attempt++) {\n const runs = cron.nextRuns(8, new Date(probe));\n if (runs.length === 0) return null;\n const found = runs.find((d) => d.getTime() > from);\n if (found) return found.getTime();\n probe += 3_600_000;\n }\n return null;\n}\n\n/**\n * Every fire of a cron strictly after `from` and at or before `to`,\n * ascending, or null when there are more than `limit`. Asks croner for fires\n * in batches, which is far cheaper than one nextFire per fire, and drops any\n * that do not move forward (see fireAfter).\n */\nexport function firesBetween(parsed: ParsedSchedule, from: number, to: number, limit: number): number[] | null {\n const cron = crons.get(parsed);\n if (!cron) throw new Error(`schedule \"${parsed.source}\" was not made by parseSchedule`);\n const out: number[] = [];\n let probe = from;\n let last = from;\n for (let guard = 0; guard < 1000; guard++) {\n const batch = cron.nextRuns(Math.min(limit + 1 - out.length, 24), new Date(probe));\n if (batch.length === 0) return out;\n for (const date of batch) {\n const t = date.getTime();\n if (t <= last) continue;\n if (t > to) return out;\n out.push(t);\n last = t;\n if (out.length > limit) return null;\n }\n const end = batch[batch.length - 1]!.getTime();\n probe = end > probe ? end : probe + 3_600_000;\n }\n return out;\n}\n\n/** The next time the schedule fires strictly after `from`. For an interval, counted from the last run when there is one. */\nexport function nextFire(parsed: ParsedSchedule, from: number, lastRunAt: number | null): number | null {\n if (parsed.kind === \"interval\") {\n const base = lastRunAt ?? from;\n return base + parsed.everyMs!;\n }\n return fireAfter(parsed, from);\n}\n\nexport interface Expectation {\n /** When the next run the schedule asks for is due. */\n dueAt: number;\n /** Missed once now passes this. */\n deadline: number;\n}\n\n/**\n * When the schedule next wants a run, given the last one. For a cron that is\n * the first fire the last run does not already cover; with no run yet, the\n * first fire at or after registration. For an interval it is the last run's\n * start (or registration) plus the interval. Null for a cron that never\n * fires again.\n *\n * Counting forward from the last run, rather than back from now, is what\n * lets a job whose period is shorter than its grace be missed at all, and it\n * works for a cron that fires once a year or less.\n */\nexport function expectation(\n parsed: ParsedSchedule,\n lastRunAt: number | null,\n registeredAt: number,\n graceMs: number,\n): Expectation | null {\n let dueAt: number | null;\n if (parsed.kind === \"interval\") {\n dueAt = (lastRunAt ?? registeredAt) + parsed.everyMs!;\n } else if (lastRunAt === null) {\n dueAt = fireAfter(parsed, registeredAt - 1);\n } else {\n dueAt = dueAfterRun(parsed, lastRunAt);\n }\n return dueAt === null ? null : { dueAt, deadline: dueAt + graceMs };\n}\n\n/** The first fire that a run starting at `startedAt` does not cover. */\nfunction dueAfterRun(parsed: ParsedSchedule, startedAt: number): number | null {\n // A fire at or before the start is covered by the run itself.\n const next = fireAfter(parsed, startedAt);\n if (next === null) return null;\n const following = fireAfter(parsed, next);\n const covers = runCovers(startedAt, next, following) || inSpringForwardGap(parsed, startedAt, next);\n return covers ? following : next;\n}\n\n/**\n * Whether a run starting at `startedAt` covers the fire at `dueAt`. A minute\n * of slack before the tick absorbs schedulers that fire a touch early. When\n * the fire after `dueAt` is known, the slack is at most half the gap between\n * the two, so one run of an every-minute cron never covers two fires.\n */\nexport function runCovers(startedAt: number, dueAt: number, followingAt: number | null = null): boolean {\n const slack = followingAt === null ? EARLY_SLACK_MS : Math.min(EARLY_SLACK_MS, Math.floor((followingAt - dueAt) / 2));\n return startedAt >= dueAt - slack;\n}\n\n/**\n * On the night clocks spring forward, a fire whose local time does not exist\n * (02:30 when 02:00 jumps to 03:00) is moved by croner to the same distance\n * past the jump (03:30), while vixie cron runs it at the jump itself (03:00).\n * A run that starts at or after the jump, and before the first fire after\n * it when that fire lies within one gap of it, is taken to cover that fire,\n * so neither scheduler's run is reported as missed. A cron that really fires\n * at 03:30 that night is treated the same way, which only matters if it also\n * ran early by up to an hour.\n */\nfunction inSpringForwardGap(parsed: ParsedSchedule, startedAt: number, fireAt: number): boolean {\n const LOOKBACK = 3 * 3_600_000;\n const after = utcOffset(fireAt, parsed.timezone);\n const before = utcOffset(fireAt - LOOKBACK, parsed.timezone);\n const gap = after - before;\n if (gap <= 0) return false;\n // Find the jump: the first minute in the window with the later offset.\n let lo = fireAt - LOOKBACK;\n let hi = fireAt;\n while (hi - lo > 60_000) {\n const mid = lo + Math.floor((hi - lo) / 2);\n if (utcOffset(mid, parsed.timezone) === after) hi = mid;\n else lo = mid;\n }\n const jumpAt = Math.floor(hi / 60_000) * 60_000;\n if (fireAt - jumpAt >= gap || startedAt < jumpAt - EARLY_SLACK_MS || startedAt >= fireAt) return false;\n // Only the first fire after the jump can be a moved one; a cron that also\n // fires at the jump (every 10 minutes, say) was not moved at all.\n return fireAfter(parsed, jumpAt - 1) === fireAt;\n}\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\n\n/** Milliseconds the zone's wall clock is ahead of UTC at `at`. */\nfunction utcOffset(at: number, timezone: string | undefined): number {\n const key = timezone ?? \"\";\n let format = formatters.get(key);\n if (!format) {\n format = new Intl.DateTimeFormat(\"en-US\", {\n ...(timezone ? { timeZone: timezone } : {}),\n hourCycle: \"h23\",\n year: \"numeric\", month: \"numeric\", day: \"numeric\", hour: \"numeric\", minute: \"numeric\", second: \"numeric\",\n });\n formatters.set(key, format);\n }\n const parts: Record<string, number> = {};\n for (const part of format.formatToParts(new Date(at))) {\n if (part.type !== \"literal\") parts[part.type] = Number(part.value);\n }\n const wall = Date.UTC(parts.year!, parts.month! - 1, parts.day!, parts.hour!, parts.minute!, parts.second!);\n return wall - Math.floor(at / 1000) * 1000;\n}\n","export function percentile(values: number[], p: number): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));\n return sorted[index]!;\n}\n\nexport function median(values: number[]): number | null {\n if (values.length === 0) return null;\n const sorted = [...values].sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;\n}\n","/**\n * Pure decisions about a job's health. Each function takes the current state\n * and returns the new state plus the alerts that should go out. Nothing here\n * touches a store or a network, which is what makes it testable.\n */\nimport { formatDuration } from \"./duration.js\";\nimport { parseDuration } from \"./duration.js\";\nimport { expectation, nextFire, parseSchedule } from \"./schedule.js\";\nimport { median, percentile } from \"./stats.js\";\nimport type {\n AlertDraft,\n BudgetBreach,\n Condition,\n JobDefinition,\n JobHealth,\n JobState,\n JobSummary,\n Run,\n StoredJob,\n StoredJobDefinition,\n} from \"./types.js\";\n\nexport type { AlertDraft, BudgetBreach };\n\nexport interface Evaluation {\n state: JobState;\n alerts: AlertDraft[];\n}\n\nexport const DEFAULT_GRACE_MS = 10 * 60_000;\nexport const DEFAULT_TIMEOUT_MS = 60 * 60_000;\n/** Runs faster than this are never called slow, whatever the baseline says. */\nexport const SLOW_FLOOR_MS = 10_000;\n/** How many earlier runs a baseline needs before it is trusted. */\nexport const BASELINE_MIN_RUNS = 5;\n/** How many successful runs a baseline looks at, and how many runs a summary covers. */\nexport const BASELINE_WINDOW = 20;\n\nexport function emptyState(job: string): JobState {\n return { job, open: {}, consecutiveFailures: 0, silencedUntil: null, lastAlertAt: null, pendingRecovery: [], undelivered: [] };\n}\n\n/** A stored state with every field present, or a fresh one. State written by an older version lacks the newer fields. */\nexport function normalizeState(state: JobState | null, job: string): JobState {\n if (!state) return emptyState(job);\n return {\n ...emptyState(job),\n ...state,\n open: { ...state.open },\n pendingRecovery: [...(state.pendingRecovery ?? [])],\n undelivered: [...(state.undelivered ?? [])],\n };\n}\n\nfunction cloneState(state: JobState): JobState {\n return normalizeState(state, state.job);\n}\n\nfunction openCondition(state: JobState, condition: Condition, now: number): boolean {\n if (state.open[condition] !== undefined) return false;\n state.open[condition] = now;\n return true;\n}\n\n/**\n * Every open condition has alerted, so closing one owes a recovered message.\n * It is remembered until a successful run leaves nothing open and sends it.\n */\nfunction closeCondition(state: JobState, condition: Condition): boolean {\n if (state.open[condition] === undefined) return false;\n delete state.open[condition];\n const pending = (state.pendingRecovery ??= []);\n if (!pending.includes(condition)) pending.push(condition);\n return true;\n}\n\nexport function openConditions(state: JobState): Condition[] {\n return Object.keys(state.open) as Condition[];\n}\n\nexport function graceMs(def: Pick<JobDefinition, \"grace\">): number {\n return def.grace === undefined ? DEFAULT_GRACE_MS : parseDuration(def.grace, \"grace\");\n}\n\nexport function timeoutMs(def: Pick<JobDefinition, \"timeout\">): number {\n return def.timeout === undefined ? DEFAULT_TIMEOUT_MS : parseDuration(def.timeout, \"timeout\");\n}\n\n/** Slow threshold for a successful run, or null when there is nothing to compare against yet. */\nexport function slowThreshold(def: Pick<JobDefinition, \"maxDuration\">, history: Run[]): { thresholdMs: number; basis: string } | null {\n if (def.maxDuration !== undefined) {\n return { thresholdMs: parseDuration(def.maxDuration, \"maxDuration\"), basis: \"maxDuration\" };\n }\n const durations = history\n .filter((r) => r.status === \"ok\" && r.durationMs !== null)\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.durationMs!);\n if (durations.length < BASELINE_MIN_RUNS) return null;\n const p95 = percentile(durations, 95)!;\n return { thresholdMs: Math.max(2 * p95, SLOW_FLOOR_MS), basis: `twice the p95 of the last ${durations.length} runs (${formatDuration(p95)})` };\n}\n\nexport function budgetBreaches(def: Pick<JobDefinition, \"budget\">, run: Run, history: Run[]): BudgetBreach[] {\n const breaches: BudgetBreach[] = [];\n for (const [metric, value] of Object.entries(run.metrics)) {\n const ceiling = def.budget?.[metric];\n if (ceiling !== undefined) {\n if (value > ceiling) breaches.push({ metric, value, limit: ceiling, basis: \"budget\" });\n continue;\n }\n const past = history\n .filter((r) => r.status === \"ok\" && typeof r.metrics[metric] === \"number\")\n .slice(0, BASELINE_WINDOW)\n .map((r) => r.metrics[metric]!);\n if (past.length < BASELINE_MIN_RUNS) continue;\n const usual = median(past)!;\n if (usual > 0 && value > 3 * usual) {\n breaches.push({ metric, value, limit: 3 * usual, basis: `three times the usual ${formatNumber(usual)}` });\n }\n }\n return breaches;\n}\n\n/** Whether `history` (newest first) holds a full baseline window of successful runs. */\nexport function hasFullBaseline(history: Run[]): boolean {\n return history.filter((r) => r.status === \"ok\").length >= BASELINE_WINDOW;\n}\n\nexport function formatNumber(n: number): string {\n if (Number.isInteger(n)) return n.toLocaleString(\"en-US\");\n return n.toLocaleString(\"en-US\", { maximumFractionDigits: 4 });\n}\n\n/**\n * Called when a run starts. Missed and stuck are about the absence of a run,\n * so a run starting closes them without an alert; the recovered message\n * waits for a successful finish.\n */\nexport function onRunStart(state: JobState): JobState {\n const next = cloneState(state);\n closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n return next;\n}\n\n/**\n * Called when a run finishes with status ok, failed or timeout. `history` is\n * the job's earlier runs, newest first, not including this one.\n */\nexport function onRunFinish(\n def: JobDefinition | StoredJobDefinition,\n run: Run,\n state: JobState,\n history: Run[],\n now: number,\n): Evaluation {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n\n if (run.status === \"ok\") {\n next.consecutiveFailures = 0;\n closeCondition(next, \"missed\");\n closeCondition(next, \"stuck\");\n closeCondition(next, \"failed\");\n\n const slow = slowThreshold(def, history);\n if (slow && run.durationMs !== null && run.durationMs > slow.thresholdMs) {\n if (openCondition(next, \"slow\", now)) {\n alerts.push({ type: \"slow\", run, details: { durationMs: run.durationMs, thresholdMs: slow.thresholdMs, basis: slow.basis } });\n }\n } else {\n closeCondition(next, \"slow\");\n }\n\n const breaches = budgetBreaches(def, run, history);\n if (breaches.length > 0) {\n if (openCondition(next, \"over_budget\", now)) {\n alerts.push({ type: \"over_budget\", run, details: { breaches } });\n }\n } else {\n closeCondition(next, \"over_budget\");\n }\n\n const pending = next.pendingRecovery ?? [];\n if (pending.length > 0 && openConditions(next).length === 0) {\n alerts.push({ type: \"recovered\", run, details: { after: [...pending] } });\n next.pendingRecovery = [];\n }\n return { state: next, alerts };\n }\n\n // failed or timeout\n next.consecutiveFailures += 1;\n closeCondition(next, \"missed\");\n const threshold = Math.max(1, def.failuresBeforeAlert ?? 1);\n const condition = run.status === \"timeout\" ? \"stuck\" : \"failed\";\n if (next.consecutiveFailures >= threshold) {\n if (openCondition(next, condition, now)) {\n alerts.push({ type: condition, run, details: { consecutiveFailures: next.consecutiveFailures, threshold } });\n }\n }\n return { state: next, alerts };\n}\n\n/**\n * Called by check(). Decides whether the schedule has been missed: the run\n * the schedule wants next (see expectation()) has not started and its grace\n * has run out. `lastRun` is the most recent run of any status. A job with no\n * schedule is never missed, and one whose schedule was removed while missed\n * was open gets a recovered alert (reason \"unscheduled\") for missed alone.\n */\nexport function onCheck(\n def: StoredJobDefinition,\n stored: StoredJob,\n lastRun: Run | null,\n state: JobState,\n now: number,\n): Evaluation & { nextExpectedAt: number | null; dueAt: number | null } {\n const next = cloneState(state);\n const alerts: AlertDraft[] = [];\n if (!def.schedule) {\n const since = next.open.missed;\n if (since !== undefined) {\n // The schedule went away while missed was open (the job was declared\n // again without one, or a source retired it), so nothing is due any\n // more. Missed closes now with a recovery of its own; other open\n // conditions keep their own rules. Missed is taken out of the pending\n // recovery too, so the next successful run does not name it again.\n delete next.open.missed;\n next.pendingRecovery = (next.pendingRecovery ?? []).filter((c) => c !== \"missed\");\n alerts.push({ type: \"recovered\", run: lastRun, details: { after: [\"missed\"], reason: \"unscheduled\", since } });\n }\n return { state: next, alerts, nextExpectedAt: null, dueAt: null };\n }\n\n const parsed = parseSchedule(def.schedule, def.timezone);\n const grace = graceMs(def);\n const lastRunAt = lastRun?.startedAt ?? null;\n const exp = expectation(parsed, lastRunAt, stored.createdAt, grace);\n const nextExpectedAt = parsed.kind === \"interval\" ? nextFire(parsed, stored.createdAt, lastRunAt) : nextFire(parsed, now, null);\n if (!exp) return { state: next, alerts, nextExpectedAt, dueAt: null };\n\n // An interval's next run is due a period after the last one started. If that\n // run is still going, the job is busy, not late; stuck covers one that never ends.\n if (parsed.kind === \"interval\" && lastRun?.status === \"running\") {\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n }\n\n if (now > exp.deadline) {\n if (openCondition(next, \"missed\", now)) {\n alerts.push({ type: \"missed\", run: lastRun, details: { dueAt: exp.dueAt, deadline: exp.deadline, graceMs: grace, lastRunAt } });\n }\n } else {\n // A run has started since it opened, or the grace was widened.\n closeCondition(next, \"missed\");\n }\n return { state: next, alerts, nextExpectedAt, dueAt: exp.dueAt };\n}\n\n/** Whether a running run has gone on longer than the job's timeout. */\nexport function isStuck(def: Pick<JobDefinition, \"timeout\">, run: Run, now: number): boolean {\n return run.status === \"running\" && now - run.startedAt > timeoutMs(def);\n}\n\n/**\n * While a job is silenced nothing new is recorded as an incident: conditions\n * may close (so a job that recovered during the silence shows as healthy) but\n * none may open, so the first problem after the silence ends alerts normally.\n */\nexport function muteOpens(previous: JobState, next: JobState): JobState {\n const muted = cloneState(next);\n for (const condition of openConditions(muted)) {\n if (previous.open[condition] === undefined) delete muted.open[condition];\n }\n return muted;\n}\n\nexport function isSilenced(state: JobState, now: number): boolean {\n return state.silencedUntil !== null && state.silencedUntil > now;\n}\n\n/**\n * An evaluation as it is saved and sent: while the job was silenced when it\n * began, nothing opens and nothing is sent.\n */\nexport function applySilence(previous: JobState, evaluation: Evaluation, now: number): Evaluation {\n if (!isSilenced(previous, now)) return evaluation;\n return { state: muteOpens(previous, evaluation.state), alerts: [] };\n}\n\n/**\n * Whether an alert waiting to be retried no longer describes the job, so it\n * is dropped rather than sent late. An alert for a condition is stale once\n * that condition has closed, or has closed and opened again (it opened at a\n * time other than the alert's). A recovery is stale when any condition it\n * names is open again; while they all stay closed it is kept.\n */\nexport function staleAlert(alert: AlertDraft & { at: number }, state: JobState): boolean {\n if (alert.type === \"recovered\") return alert.details.after.some((condition) => state.open[condition] !== undefined);\n return state.open[alert.type] !== alert.at;\n}\n\n/** How a job looks at a glance. Silence wins, then stuck, failing and late. */\nexport function jobHealth(def: Pick<JobDefinition, \"timeout\">, lastRun: Run | null, state: JobState, now: number): JobHealth {\n const open = openConditions(state);\n if (isSilenced(state, now)) return \"silenced\";\n if (open.includes(\"stuck\") || (lastRun && isStuck(def, lastRun, now))) return \"stuck\";\n if (open.includes(\"failed\") || lastRun?.status === \"failed\" || lastRun?.status === \"timeout\") return \"failing\";\n if (open.includes(\"missed\")) return \"late\";\n if (!lastRun) return \"never_ran\";\n return \"healthy\";\n}\n\n/**\n * A job's summary from its most recent runs (newest first; the first\n * BASELINE_WINDOW are used) and its state. Stats cover runs of any status;\n * the percentiles are over the successful ones among them.\n */\nexport function summarize(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, now: number): JobSummary {\n return summary(stored, recent, state, nextExpectedAt, (lastRun) => jobHealth(stored.definition, lastRun, state, now));\n}\n\n/**\n * The summary of a job that could not be evaluated, say because its stored\n * schedule no longer parses. It reads nothing from the definition. The job\n * shows as failing (or silenced, while it is), since it needs a look, and\n * nothing is known about when it is next due.\n */\nexport function unevaluableSummary(stored: StoredJob, recent: Run[], state: JobState, now: number): JobSummary {\n return summary(stored, recent, state, null, () => (isSilenced(state, now) ? \"silenced\" : \"failing\"));\n}\n\nfunction summary(stored: StoredJob, recent: Run[], state: JobState, nextExpectedAt: number | null, health: (lastRun: Run | null) => JobHealth): JobSummary {\n const window = recent.slice(0, BASELINE_WINDOW);\n const lastRun = window[0] ?? null;\n const finished = window.filter((r) => r.status !== \"running\");\n const okDurations = window.filter((r) => r.status === \"ok\" && r.durationMs !== null).map((r) => r.durationMs!);\n return {\n name: stored.name,\n definition: stored.definition,\n health: health(lastRun),\n open: openConditions(state),\n lastRun,\n nextExpectedAt,\n consecutiveFailures: state.consecutiveFailures,\n silencedUntil: state.silencedUntil,\n stats: {\n runs: finished.length,\n okRate: finished.length === 0 ? 1 : finished.filter((r) => r.status === \"ok\").length / finished.length,\n p50Ms: percentile(okDurations, 50),\n p95Ms: percentile(okDurations, 95),\n },\n };\n}\n","import { formatDuration, formatRelative } from \"./duration.js\";\nimport { formatNumber } from \"./evaluate.js\";\nimport type { Alert, AlertDraft, StoredJobDefinition } from \"./types.js\";\n\nfunction when(at: number | null | undefined, now: number): string {\n if (at === null || at === undefined) return \"never\";\n return `${new Date(at).toISOString().replace(\"T\", \" \").slice(0, 19)} UTC (${formatRelative(at, now)})`;\n}\n\nfunction firstLines(text: string | null, n: number): string {\n if (!text) return \"\";\n return text.split(\"\\n\").slice(0, n).join(\"\\n\");\n}\n\nfunction tail(text: string | null, n: number): string {\n if (!text) return \"\";\n const lines = text.trimEnd().split(\"\\n\");\n return lines.slice(Math.max(0, lines.length - n)).join(\"\\n\");\n}\n\n/** \"Error: x\" for a bare message, but not \"Error: TypeError: x\" for one that already names itself. */\nfunction errorLine(error: string): string {\n const text = firstLines(error, 4);\n return /^[A-Za-z_$][\\w$]*: /.test(text) ? text : `Error: ${text}`;\n}\n\n/** Turns a draft into the title and message every channel shows. */\nexport function composeAlert(draft: AlertDraft, def: StoredJobDefinition, now: number): Alert {\n const name = def.name;\n const run = draft.run;\n let title: string;\n const lines: string[] = [];\n\n switch (draft.type) {\n case \"missed\": {\n const d = draft.details;\n title = `${name} missed its scheduled run`;\n lines.push(`Due ${when(d.dueAt, now)}, and no run had started by ${when(d.deadline, now)} (grace ${formatDuration(d.graceMs)}).`);\n lines.push(`Schedule: ${def.schedule}${def.timezone ? ` (${def.timezone})` : \"\"}.`);\n lines.push(`Last run: ${run ? `${run.status} ${when(run.startedAt, now)}` : \"never\"}.`);\n break;\n }\n case \"failed\": {\n title = `${name} failed`;\n const n = draft.details.consecutiveFailures;\n if (n > 1) lines.push(`${n} consecutive failures.`);\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)}${run.durationMs !== null ? `, ran ${formatDuration(run.durationMs)}` : \"\"}.`);\n if (run.error) lines.push(errorLine(run.error));\n const out = tail(run.output, 8);\n if (out) lines.push(`Output (tail):\\n${out}`);\n }\n break;\n }\n case \"stuck\": {\n title = `${name} is stuck`;\n if (run) {\n lines.push(`Started ${when(run.startedAt, now)} and never reported finishing. Marked as timed out after ${formatDuration(run.durationMs ?? now - run.startedAt)}.`);\n const out = tail(run.output, 8);\n if (out) lines.push(`Output so far (tail):\\n${out}`);\n }\n lines.push(`If the process was killed mid-run (a serverless timeout, a deploy), this is what that looks like.`);\n break;\n }\n case \"slow\": {\n const d = draft.details;\n title = `${name} was slow`;\n lines.push(`Took ${formatDuration(d.durationMs)}; the limit is ${formatDuration(d.thresholdMs)} (${d.basis}).`);\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"over_budget\": {\n title = `${name} went over budget`;\n for (const b of draft.details.breaches) {\n lines.push(`${b.metric}: ${formatNumber(b.value)}, limit ${formatNumber(b.limit)} (${b.basis}).`);\n }\n if (run) lines.push(`Started ${when(run.startedAt, now)}.`);\n break;\n }\n case \"recovered\": {\n if (draft.details.reason === \"unscheduled\") {\n title = `${name} is no longer scheduled`;\n const since = draft.details.since;\n lines.push(`${since === undefined ? \"\" : `Missed since ${when(since, now)}. `}It has no schedule now, so nothing is due; the missed alert is closed.`);\n break;\n }\n title = `${name} recovered`;\n const after = draft.details.after.map((c) => c.replace(\"_\", \" \")).join(\", \");\n lines.push(`A run ${run ? when(run.startedAt, now) : \"just now\"} succeeded${after ? ` after: ${after}` : \"\"}.`);\n if (run?.durationMs !== null && run?.durationMs !== undefined) lines.push(`Ran ${formatDuration(run.durationMs)}.`);\n break;\n }\n }\n\n return { ...draft, job: name, definition: def, title, message: lines.join(\"\\n\"), at: now };\n}\n","export function json(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"content-type\": \"application/json; charset=utf-8\", \"cache-control\": \"no-store\", ...headers },\n });\n}\n\n/** Compares two secrets without stopping at the first differing character. */\nexport function constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n return diff === 0;\n}\n","/** Output is capped so a chatty job cannot fill the store. The tail is kept. */\nexport const OUTPUT_CAP = 16 * 1024;\n\n/**\n * NUL characters are removed first, since Postgres refuses them in TEXT and\n * JSONB and the whole run row would be lost. The cap then applies to what is\n * left.\n */\nexport function capOutput(text: string): string {\n const clean = stripNul(text);\n if (clean.length <= OUTPUT_CAP) return clean;\n return \"[earlier output trimmed]\\n\" + clean.slice(clean.length - OUTPUT_CAP);\n}\n\n/** Removes every U+0000. */\nexport function stripNul(text: string): string {\n return text.includes(\"\\u0000\") ? text.replace(/\\u0000/g, \"\") : text;\n}\n\n/** \"Name: message\" and the first five stack frames, capped like output. */\nexport function errorMessage(error: unknown): string {\n return capOutput(describeError(error));\n}\n\nfunction describeError(error: unknown): string {\n if (error instanceof Error) {\n // The stack repeats the header (over several lines when the message has\n // newlines), so take only its frames.\n const frames = (error.stack ?? \"\").split(\"\\n\").filter((line) => /^\\s+at /.test(line)).slice(0, 5);\n return `${error.name}: ${error.message}${frames.length ? `\\n${frames.join(\"\\n\")}` : \"\"}`;\n }\n if (typeof error === \"string\") return error;\n try {\n return JSON.stringify(error) ?? String(error);\n } catch {\n return String(error);\n }\n}\n\nconst REDACTED = \"[redacted]\";\n\n// Bounded quantifiers throughout, so a long line cannot make these backtrack.\n// They apply in this order, each to the text the ones before it left.\nconst SECRET_PATTERNS: [RegExp, string | ((match: string, ...groups: string[]) => string)][] = [\n // A PEM private key, header to footer. Without a footer (the output was\n // trimmed) it runs to the end of the base64 body. A \"-\" that starts five\n // dashes ends the body, so the footer is never swallowed into it.\n [\n /-----BEGIN (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----(?:[A-Za-z0-9+/=\\s,:]|-(?!----)){0,16384}(?:-----END (?:[A-Z0-9]{1,20} ){0,3}PRIVATE KEY-----)?/g,\n REDACTED,\n ],\n // password=..., API_KEY: ..., \"client_secret\": \"...\", TOKEN='...', token=...,\n // :password=>\"...\" (but not max_tokens: 800). A quoted value is blanked to\n // its closing quote, spaces and all, and keeps its quotes.\n [\n /\\b([A-Za-z0-9_-]{0,40}(?:secret|token|passw(?:or)?d|pwd|api[_-]?key|access[_-]?key|private[_-]?key|credential)[A-Za-z0-9_-]{0,40}(?<![Tt][Oo][Kk][Ee][Nn][Ss])\"?\\s{0,3}(?:=>|[=:])\\s{0,3})(?:(\")[^\"\\n]{1,4096}\"|(')[^'\\n]{1,4096}'|[\"']?[^\\s\"',;&]{1,4096})/gi,\n (_match, name: string, double?: string, single?: string) => {\n const quote = double ?? single ?? \"\";\n return `${name}${quote}${REDACTED}${quote}`;\n },\n ],\n // Authorization: Basic <base64> and Authorization: Token <token>, also as a JSON or hash entry.\n [/\\b((?:proxy-)?authorization[\"']?\\s{0,3}(?:=>|[=:])\\s{0,3}[\"']?\\s{0,3}(?:basic|token)\\s{1,3})[A-Za-z0-9._~+/=:-]{1,4096}/gi, `$1${REDACTED}`],\n // Credentials inside a URL: postgres://user:password@host. The password\n // runs to the last \"@\" before a \"/\" or a space, so one that contains \"@\"\n // is blanked whole.\n [/(\\b[a-z][a-z0-9+.-]{0,30}:\\/\\/[^\\s/:@]{0,256}:)[^\\s/]{1,256}@/gi, `$1${REDACTED}@`],\n // Authorization: Bearer <token>\n [/\\b(Bearer\\s{1,3})[A-Za-z0-9._~+/=-]{8,4096}/g, `$1${REDACTED}`],\n // A bare JWT: three base64url segments, the first starting eyJ.\n [/\\beyJ[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{4,4096}\\.[A-Za-z0-9_-]{0,4096}/g, REDACTED],\n // Incoming webhook URLs carry their secret in the path.\n [/(\\bhooks\\.slack\\.com\\/(?:services|workflows|triggers)\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n [/(\\bdiscord(?:app)?\\.com\\/api\\/(?:v\\d{1,2}\\/)?webhooks\\/)[A-Za-z0-9/_-]{1,255}/gi, `$1${REDACTED}`],\n // Well-known token shapes: AWS, GitHub, Slack, Stripe, Anthropic, OpenAI and Google style keys.\n [/\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\b/g, REDACTED],\n [/\\b(?:gh[pousr]_[A-Za-z0-9]{30,255}|github_pat_[A-Za-z0-9_]{20,255})\\b/g, REDACTED],\n [/\\bxox[abposr]-[A-Za-z0-9-]{10,255}/g, REDACTED],\n [/\\b[rsp]k_(?:live|test)_[A-Za-z0-9]{10,255}\\b/g, REDACTED],\n [/\\bwhsec_[A-Za-z0-9+/=]{16,255}/g, REDACTED],\n [/\\bsk-[A-Za-z0-9_-]{20,255}/g, REDACTED],\n [/\\bAIza[0-9A-Za-z_-]{35}(?![0-9A-Za-z_-])/g, REDACTED],\n];\n\n/**\n * The default `redact`: blanks values that look like secrets (key=value pairs\n * with secret-ish names, Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs and well-known token formats)\n * before output or an error is stored, shown or sent anywhere.\n */\nexport function redactSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) out = out.replace(pattern, replacement as string);\n return out;\n}\n","import { capOutput, OUTPUT_CAP } from \"./output.js\";\nimport type { Run } from \"./types.js\";\n\n/** What a job function receives. */\nexport interface JobContext {\n readonly name: string;\n readonly runId: string;\n readonly startedAt: number;\n /** Aborts when the job's timeout elapses. Honour it if the work can stop. */\n readonly signal: AbortSignal;\n /** Append a line of output. Kept with the run, capped at 16 KB, shown in alerts and the dashboard. */\n log(...parts: unknown[]): void;\n /** Report a number for this run: tokens, cost, rows, anything. Watched against budgets and baselines. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n}\n\nexport interface RunRecorder {\n context: JobContext;\n output(): string | null;\n /**\n * What an expect rule is checked against: everything logged, or when that\n * ran long, the first 16 KB and the last 16 KB. The stored output keeps only\n * the tail, so a \"done\" line printed early would otherwise be lost.\n */\n expectText(): string | null;\n metrics(): Record<string, number>;\n abort(): void;\n}\n\nfunction stringify(part: unknown): string {\n if (typeof part === \"string\") return part;\n if (part instanceof Error) return `${part.name}: ${part.message}`;\n try {\n return JSON.stringify(part);\n } catch {\n return String(part);\n }\n}\n\nexport function createRecorder(run: Run): RunRecorder {\n const lines: string[] = [];\n let size = 0;\n const head: string[] = [];\n let headSize = 0;\n let dropped = false;\n const metrics: Record<string, number> = {};\n const controller = new AbortController();\n\n const context: JobContext = {\n name: run.job,\n runId: run.id,\n startedAt: run.startedAt,\n signal: controller.signal,\n log(...parts) {\n const line = parts.map(stringify).join(\" \");\n if (headSize < OUTPUT_CAP) {\n head.push(line);\n headSize += line.length + 1;\n }\n lines.push(line);\n size += line.length + 1;\n // Drop from the front once well past the cap; capOutput trims exactly at the end.\n while (size > 64 * 1024 && lines.length > 1) {\n size -= lines.shift()!.length + 1;\n dropped = true;\n }\n },\n metric(name, value) {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`metric \"${name}\" must be a finite number`);\n }\n metrics[name] = value;\n },\n metrics(values) {\n for (const [k, v] of Object.entries(values)) context.metric(k, v);\n },\n };\n\n return {\n context,\n output: () => (lines.length === 0 ? null : capOutput(lines.join(\"\\n\"))),\n expectText: () => {\n if (lines.length === 0) return null;\n const all = lines.join(\"\\n\");\n if (!dropped && all.length <= 2 * OUTPUT_CAP) return all;\n return head.join(\"\\n\").slice(0, OUTPUT_CAP) + \"\\n\" + all.slice(-OUTPUT_CAP);\n },\n metrics: () => ({ ...metrics }),\n abort: () => controller.abort(),\n };\n}\n","import type { JobDefinition, StoredJobDefinition } from \"./types.js\";\n\n/** A definition as a store can hold it: `expect` becomes a description. */\nexport function toStored(def: JobDefinition): StoredJobDefinition {\n const { expect, ...rest } = def;\n const stored: StoredJobDefinition = { ...rest };\n if (expect !== undefined) {\n stored.expect =\n typeof expect === \"string\" ? `contains ${JSON.stringify(expect)}`\n : expect instanceof RegExp ? `matches ${expect.toString()}`\n : \"custom function\";\n }\n return stored;\n}\n\nexport function checkExpectation(expect: JobDefinition[\"expect\"], output: string | null): string | null {\n if (expect === undefined) return null;\n const text = output ?? \"\";\n if (typeof expect === \"string\") {\n return text.includes(expect) ? null : `Output did not contain ${JSON.stringify(expect)}`;\n }\n if (expect instanceof RegExp) {\n expect.lastIndex = 0; // a /g or /y pattern would otherwise resume where the last run stopped\n return expect.test(text) ? null : `Output did not match ${expect.toString()}`;\n }\n let ok = false;\n try {\n ok = expect(text);\n } catch (error) {\n return `Output check threw: ${(error as Error).message}`;\n }\n return ok ? null : \"Output did not pass the expect() check\";\n}\n","/** Escapes text for HTML, attribute values included. Every string a page shows goes through this. */\nexport function escapeHtml(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n","// Generated by scripts/make-dashboard-icons.mjs. Do not edit; change the drawing there and run it.\n\n/** The favicon: the clock on a dark rounded square. */\nexport const ICON_SVG = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 40 40\\\"><rect width=\\\"40\\\" height=\\\"40\\\" rx=\\\"10\\\" fill=\\\"#141417\\\"/><rect x=\\\"0.5\\\" y=\\\"0.5\\\" width=\\\"39\\\" height=\\\"39\\\" rx=\\\"9.5\\\" fill=\\\"none\\\" stroke=\\\"#2a2a2f\\\"/><circle cx=\\\"20\\\" cy=\\\"20\\\" r=\\\"10.5\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\"/><path d=\\\"M20 12.5V20h6\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"/></svg>\";\n/** The same square to every edge, for masks. */\nexport const MASKABLE_SVG = \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 40 40\\\"><rect width=\\\"40\\\" height=\\\"40\\\" fill=\\\"#141417\\\"/><circle cx=\\\"20\\\" cy=\\\"20\\\" r=\\\"10.5\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\"/><path d=\\\"M20 12.5V20h6\\\" fill=\\\"none\\\" stroke=\\\"#f3f3f1\\\" stroke-width=\\\"2\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"/></svg>\";\n/** PNGs, base64: 192 and 512 for the manifest, a maskable 512, and iOS's 180 home screen icon. */\nexport const ICON_192_PNG = \"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\";\nexport const ICON_512_PNG = \"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\";\nexport const MASKABLE_512_PNG = \"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\";\nexport const APPLE_TOUCH_ICON_PNG = \"iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAMAAAAKE/YAAAAAM1BMVEUUFBciIiU+PkBaWlt2dnaRkZKfn5+tra27u7tMTE7X19bz8/FoaGnl5eMwMDKEhITJycgc8OlvAAAFSklEQVR42u2caZPjKAyGOZ042XXm///LSVXaB9fW7vYYfGTawiJO1+j91IcNj4UQAoMZI5FIJBKJRCKRSCQSiUQikUgkEolEIpG+izh+iZ9ijIVPvTd0baRclhic0+17QvOrqfzT/4pBP8K7QUulvrzGWvdG0A0328oJOtwxLISA7IXf+OzcB/ZXfzw01wJUhgwsHO0eqvbge0Rrj4SuTybrPt23h7nHLayZWVh3Cp0IIfRa9UyteIPnl/4YSzfD8on1w1/n8aF5iOuyQVx1PwBaXuZmdvbyDKT5UPMnFB/u5dDqNGPo3O+7pJDn2QW9fTG0rmYBwc1dt2bzzsblLNQM5qXQlZ6a/eeij3rPhFj+eWpcM7wwekyZzbJPaR4YC57NPaavJ71XcvcyS0+YQ7+sWNSfP7RLP5cnvtfWcq8/m96v5Xy/AvLyn8GmlUrmXwI9iRv9al/6+xfJeW0McUGluUhGHgB/zJS5y4patkt+Ocny0M0ludlnjg/OJ/VeGnBbQ29Ien94eJapVpzH7gh/cqilbzIZA7OZGfNdrFneykLXiQ/bHcyM+bSkuih00gm7nasCbbdaLD60igGu3z2zdjEcGlUOmsdmNJbtlo0mqHkxaDV6cTAMQWbMDL0qBd3E4btHWS0K0UGqphB07HkGaanImZXCUaETQ58Zks5ZpgZAx76i7ljQd5WTJAOgx6ZcTkjy9VMsiseEjgvPqGvNbZxBFoAeG1I4TGgn4LnbZmg+ltmhvo4I42iuODr0NdqGocqtVIEFbWICjwsd02mDDj0GacuQZRdVYEHHtaELNvRYoK+Rocem03ds6LuG+sdW6DGIPhi6HtD1DDC0x4f2haA5B8el7boua8GBHq+/40PfBTBpgkIbVkCmMLQvAe2B0AoIXQOXZp+swwzt6mpKIWhg4vFs+BSnIaykH4XcAyuXVtVqTl0GusLyY1Wv5DW40AW04/GPg2bvBj0gXbMPOsCq2rA3wrYr/KEM9MaUd/iK2qZPXwOhFRB6YyIWevHbjjZM3npJWxZ6c5xuARG91WXdQxSNBoWgdQloXRjaN/jMjS8EHV4xRwy40DEREwVd2rFC0CXniNjQcW0C3akbA+3lW6Hb8cIPbOixQNEiQ8f8QGFDK3AKtRl6bDqJ3BXj/lqNDh1DncSFlgwcTTdDhzFvO6OeI+DjWzkb0KHjxNqjmlr6r2bue6AdNKfepphLuwLQsZ/4Gx7zzWekYgDo6HIWbYBpLAMmS8BQ0MeLB6w3XCEW2RaxdOLLGqkvSs1yOgqk9sTUEuUdF4/Rcyi0dYIxG1e/UWYwOq7Vg4wAa+e4aydni+gi6YgTdtgWP1giYaOBT7vdOtm0qmHeBqw6eZWj1D6/rhMPs7CigClbmySmale6J9KSgKve4OTnnGyQ3bHZNNkgy1yXnRhu1IWPQxc/ZUe++pzaHHq6CJ5mynSrWJc3NO4sAx4DQro5XmVFPpUyZ2xazQhcPr1JcTA1r9IF1SHDw3KirU83dknlA9A10jpNzivgrCHCpdRc8ev2ntSE/cdcih2DepbzH3gMirnpjf68xUe4uk473YsPnB17tC877fG+CtM5iJbPj1c3rqrktDFEmz39yc8f3OKEmzy5H1ou5o+N1D/cIil0PH/Ktmvh5bbavsL42rX/xuKhlq3Qq16j9uwM/pZHsP/Aw+7/xTHodoLB7t0WvHvdNhgJGiEGaQ7/FsL/8eHFn8r4lh8lwVq2Dc5WVj1veGHkh8Xa4v6Hf2gnrjIU/6QRiUQikUgkEolEIpFIJBKJRCKRSCQSifR99A+QQLqujpJ2+QAAAABJRU5ErkJggg==\";\n","import { APPLE_TOUCH_ICON_PNG, ICON_192_PNG, ICON_512_PNG, ICON_SVG, MASKABLE_512_PNG, MASKABLE_SVG } from \"./icons.js\";\n\n/*\n * What makes the dashboard an installable web app: a manifest, icons, a\n * service worker, the script that registers it and a page to show offline.\n * None of it says anything about the jobs, so it is served without the token\n * (a browser fetches the manifest and icons without cookies in some flows).\n */\n\n/** The page colours the app's window takes: the paper behind the sheet, and the sheet the header sits on. */\nexport const BACKGROUND_COLOR = \"#f4f4f5\";\nexport const THEME_COLOR = \"#ffffff\";\nexport const THEME_COLOR_DARK = \"#111113\";\n\n/** The manifest, for the dashboard mounted at `base` (\"\" at the root). */\nexport function manifest(base: string): string {\n const icon = (name: string, sizes: string, type: string, purpose: string) => ({ src: `${base}/icons/${name}`, sizes, type, purpose });\n return JSON.stringify({\n id: `${base}/`,\n name: \"CronWatch\",\n short_name: \"CronWatch\",\n description: \"The scheduled jobs of this app: their health, their last day and their runs.\",\n start_url: `${base}/`,\n scope: `${base}/`,\n display: \"standalone\",\n background_color: BACKGROUND_COLOR,\n theme_color: THEME_COLOR,\n icons: [\n icon(\"icon.svg\", \"any\", \"image/svg+xml\", \"any\"),\n icon(\"maskable.svg\", \"any\", \"image/svg+xml\", \"maskable\"),\n icon(\"icon-192.png\", \"192x192\", \"image/png\", \"any\"),\n icon(\"icon-512.png\", \"512x512\", \"image/png\", \"any\"),\n icon(\"maskable-512.png\", \"512x512\", \"image/png\", \"maskable\"),\n ],\n });\n}\n\n/**\n * Registers the service worker, and does nothing else. The page works the\n * same without it. Its own URL gives the base, so it is the same text\n * wherever the dashboard is mounted.\n */\nexport const APP_JS = `\"use strict\";\n(function () {\n var script = document.currentScript;\n if (!script || !(\"serviceWorker\" in navigator)) return;\n var base = new URL(\"./\", script.src);\n navigator.serviceWorker.register(new URL(\"sw.js\", base).href, { scope: base.pathname }).catch(function () {});\n})();\n`;\n\n/**\n * The service worker. It caches the app shell (the offline page, the\n * manifest, the icons and app.js) and nothing else: every other request goes\n * to the network as the page made it, and its answer is never stored, since\n * the pages and the JSON carry job data. When a page cannot be reached it\n * shows the offline page. Its scope gives the base, so it is the same text\n * wherever the dashboard is mounted.\n */\nexport const SW_JS = `\"use strict\";\nvar VERSION = \"cronwatch-shell-1\";\nvar SCOPE = self.registration.scope;\nvar CACHE = VERSION + \" \" + SCOPE;\nvar SHELL = [\"offline\", \"manifest.webmanifest\", \"app.js\", \"icons/icon.svg\", \"icons/maskable.svg\", \"icons/icon-192.png\", \"icons/icon-512.png\", \"icons/maskable-512.png\", \"icons/apple-touch-icon.png\"].map(function (path) {\n return new URL(path, SCOPE).href;\n});\nvar OFFLINE = SHELL[0];\n\nself.addEventListener(\"install\", function (event) {\n event.waitUntil(caches.open(CACHE).then(function (cache) {\n return cache.addAll(SHELL.map(function (url) { return new Request(url, { credentials: \"omit\", cache: \"reload\" }); }));\n }).then(function () { return self.skipWaiting(); }));\n});\n\nself.addEventListener(\"activate\", function (event) {\n event.waitUntil(caches.keys().then(function (keys) {\n return Promise.all(keys.filter(function (key) {\n return key !== CACHE && key.indexOf(\"cronwatch-shell-\") === 0 && key.slice(key.indexOf(\" \") + 1) === SCOPE;\n }).map(function (key) { return caches.delete(key); }));\n }).then(function () { return self.clients.claim(); }));\n});\n\nself.addEventListener(\"fetch\", function (event) {\n var request = event.request;\n if (request.method !== \"GET\") return;\n var url = new URL(request.url);\n url.search = \"\";\n if (SHELL.indexOf(url.href) !== -1 && url.href !== OFFLINE) {\n event.respondWith(caches.open(CACHE).then(function (cache) {\n return cache.match(url.href).then(function (hit) { return hit || fetch(request); });\n }));\n return;\n }\n if (request.mode !== \"navigate\") return;\n event.respondWith(fetch(request).catch(function () {\n return caches.open(CACHE).then(function (cache) { return cache.match(OFFLINE); }).then(function (page) {\n return page || new Response(\"You are offline.\", { status: 503, headers: { \"content-type\": \"text/plain; charset=utf-8\" } });\n });\n }));\n});\n`;\n\nexport interface StaticAsset {\n type: string;\n body: string | Uint8Array<ArrayBuffer>;\n cache: string;\n /** The service worker, which may control everything under the base. */\n worker?: boolean;\n}\n\nconst YEAR = \"public, max-age=31536000, immutable\";\nconst REVALIDATE = \"no-cache\";\n\nfunction decode(base64: string): Uint8Array<ArrayBuffer> {\n const bytes = atob(base64);\n const out = new Uint8Array(bytes.length);\n for (let i = 0; i < bytes.length; i++) out[i] = bytes.charCodeAt(i);\n return out;\n}\n\nconst ICONS: Record<string, () => StaticAsset> = {\n \"/icons/icon.svg\": () => ({ type: \"image/svg+xml\", body: ICON_SVG, cache: YEAR }),\n \"/icons/maskable.svg\": () => ({ type: \"image/svg+xml\", body: MASKABLE_SVG, cache: YEAR }),\n \"/icons/icon-192.png\": () => ({ type: \"image/png\", body: decode(ICON_192_PNG), cache: YEAR }),\n \"/icons/icon-512.png\": () => ({ type: \"image/png\", body: decode(ICON_512_PNG), cache: YEAR }),\n \"/icons/maskable-512.png\": () => ({ type: \"image/png\", body: decode(MASKABLE_512_PNG), cache: YEAR }),\n \"/icons/apple-touch-icon.png\": () => ({ type: \"image/png\", body: decode(APPLE_TOUCH_ICON_PNG), cache: YEAR }),\n};\n\n/**\n * The app shell file at `path` (the path under the base), or null. The\n * offline page is HTML and is served by the routes themselves.\n */\nexport function staticAsset(path: string, base: string): StaticAsset | null {\n if (path === \"/manifest.webmanifest\") return { type: \"application/manifest+json\", body: manifest(base), cache: REVALIDATE };\n if (path === \"/app.js\") return { type: \"text/javascript; charset=utf-8\", body: APP_JS, cache: REVALIDATE };\n if (path === \"/sw.js\") return { type: \"text/javascript; charset=utf-8\", body: SW_JS, cache: REVALIDATE, worker: true };\n return Object.hasOwn(ICONS, path) ? ICONS[path]!() : null;\n}\n","/**\n * The dashboard's timelines: one lane per job (or per day, on a job's page),\n * drawn on the server as inline SVG so the page needs no script.\n *\n * Every time a job was due is a faint tick, worked out from its schedule with\n * the same functions the checks use (nextFire and expectation), so the lane\n * shows the cadence the job is meant to keep. Every run it recorded is a\n * solid mark on top, as wide as it took and coloured by how it ended. A slot\n * the check has reported missed is a dashed box. The empty part of a lane\n * carries a short note about anything open, and a visually hidden list says\n * the same things in words.\n *\n * Every time is UTC: without script the page cannot know the viewer's zone.\n */\nimport { formatDuration } from \"../duration.js\";\nimport { graceMs, isStuck, timeoutMs } from \"../evaluate.js\";\nimport { expectation, firesBetween, parseSchedule, type ParsedSchedule } from \"../schedule.js\";\nimport type { JobSummary, Run } from \"../types.js\";\nimport { escapeHtml as h } from \"./escape.js\";\n\nconst HOUR = 3_600_000;\nconst DAY = 24 * HOUR;\n\n/** The board's span: the last day, plus a few hours ahead so what is due soon shows. */\nexport const BOARD_BEHIND_MS = DAY;\nexport const BOARD_AHEAD_MS = 3 * HOUR;\n/** How many jobs the board's timeline draws. The table below it lists every job. */\nexport const BOARD_LANES = 30;\n/**\n * Runs read for a lane when the twenty the table reads start inside the span,\n * so a frequent job's lane is not cut short. Older runs than this are shown\n * as not loaded rather than as absent.\n */\nexport const BOARD_RUNS = 200;\n/** How many days a job's page draws. */\nexport const WEEK_DAYS = 7;\n\n/** Width of a lane in SVG units. Lanes stretch to fit, so strokes do not scale. */\nconst W = 1000;\n/** A lane with more due times than this shows its cadence as a dotted line instead. */\nconst MAX_TICKS = 330;\n/** More missed slots than this are drawn as one dashed band. */\nconst MAX_BOXES = 8;\n/** The narrowest a missed box is drawn, in SVG units. */\nconst MIN_BOX = 10;\n\nconst MONTHS = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\nconst WEEKDAYS = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\n/** \"22:42\", in UTC. */\nexport function clock(t: number): string {\n return new Date(t).toISOString().slice(11, 16);\n}\n\n/** \"Sat 26 Sep\", in UTC. */\nexport function dayLabel(t: number): string {\n const d = new Date(t);\n return `${WEEKDAYS[d.getUTCDay()]} ${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]}`;\n}\n\n/** \"22:42\" on the same UTC day as `now`, otherwise \"25 Sep 22:42\". */\nexport function when(t: number, now: number): string {\n if (Math.floor(t / DAY) === Math.floor(now / DAY)) return clock(t);\n const d = new Date(t);\n return `${d.getUTCDate()} ${MONTHS[d.getUTCMonth()]} ${clock(t)}`;\n}\n\n/** The stretch of time a timeline draws, and the moment it was drawn. */\nexport interface Span {\n from: number;\n to: number;\n now: number;\n}\n\n/** The job's schedule, parsed, or null when it has none or it no longer parses. */\nexport function parsedSchedule(job: JobSummary): ParsedSchedule | null {\n if (!job.definition.schedule) return null;\n try {\n return parseSchedule(job.definition.schedule, job.definition.timezone);\n } catch {\n return null;\n }\n}\n\nfunction safely<T>(fn: () => T, fallback: T): T {\n try {\n return fn();\n } catch {\n return fallback;\n }\n}\n\nexport interface DueTimes {\n /** Every time the job was or will be due within the span, ascending. */\n times: number[];\n /** True when there are too many to draw one by one; `times` is then empty. */\n dense: boolean;\n}\n\n/**\n * When the job was due within `from` to `to`. A cron's fires come from\n * nextFire. An interval is due one period after each run started, and after\n * the last run once a period for as long as nothing runs (the times a\n * missed interval job keeps being asked for); with no run yet, from its\n * next expected time.\n */\nexport function dueTimes(job: JobSummary, parsed: ParsedSchedule | null, runs: Run[], from: number, to: number): DueTimes {\n if (!parsed) return { times: [], dense: false };\n if (parsed.kind === \"interval\") {\n const every = parsed.everyMs!;\n if ((to - from) / every > MAX_TICKS) return { times: [], dense: true };\n const starts = runs.map((r) => r.startedAt).sort((a, b) => a - b);\n const times = new Set<number>();\n for (const start of starts) {\n const t = start + every;\n if (t >= from && t <= to) times.add(t);\n }\n let t = starts.length ? starts[starts.length - 1]! + every : job.nextExpectedAt;\n if (t !== null) {\n if (t < from) t += Math.ceil((from - t) / every) * every;\n for (; t <= to; t += every) times.add(t);\n }\n return { times: [...times].sort((a, b) => a - b), dense: false };\n }\n const times = safely(() => firesBetween(parsed, from - 1, to, MAX_TICKS), []);\n return times === null ? { times: [], dense: true } : { times, dense: false };\n}\n\n/**\n * The slot a missed job was due at, the one the check reported: the first\n * fire its last run does not cover (expectation(), as onCheck works it\n * out). A job that never ran has no run to count from, so the latest due\n * time whose grace has passed stands in. Null when missed is not open.\n */\nexport function missedAt(job: JobSummary, parsed: ParsedSchedule | null, times: number[], now: number): number | null {\n if (!parsed || !job.open.includes(\"missed\")) return null;\n const grace = safely(() => graceMs(job.definition), 0);\n const last = job.lastRun?.startedAt ?? null;\n if (last !== null) return safely(() => expectation(parsed, last, last, grace)?.dueAt ?? null, null);\n const past = times.filter((t) => t + grace < now);\n return past.length ? past[past.length - 1]! : null;\n}\n\ntype Tone = \"ok\" | \"bad\" | \"timeout\" | \"warn\" | \"running\" | \"stuck\";\n\nfunction toneOf(run: Run, job: JobSummary, now: number): Tone {\n if (run.status === \"running\") return safely(() => isStuck(job.definition, run, now), false) ? \"stuck\" : \"running\";\n if (run.status === \"failed\") return \"bad\";\n if (run.status === \"timeout\") return \"timeout\";\n const latest = job.lastRun?.id === run.id;\n return latest && (job.open.includes(\"over_budget\") || job.open.includes(\"slow\")) ? \"warn\" : \"ok\";\n}\n\nfunction timeoutText(job: JobSummary): string {\n return safely(() => formatDuration(timeoutMs(job.definition)), \"configured\");\n}\n\n/** One run, as its tooltip says it. */\nfunction describeRun(run: Run, tone: Tone, job: JobSummary, now: number): string {\n const at = `${when(run.startedAt, now)} UTC`;\n if (tone === \"running\") return `running since ${at}, ${formatDuration(now - run.startedAt)} so far`;\n if (tone === \"stuck\") return `running since ${at}, past its ${timeoutText(job)} timeout`;\n const took = run.durationMs !== null ? `, took ${formatDuration(run.durationMs)}` : \"\";\n const extra = tone === \"warn\" ? (job.open.includes(\"over_budget\") ? \", over budget\" : \", slow\") : \"\";\n return `${run.status} at ${at}${took}${extra}`;\n}\n\n/** The metrics of the job's last run that went over their ceilings. */\nfunction overCeilings(job: JobSummary): string[] {\n const metrics = job.lastRun?.metrics ?? {};\n return Object.entries(job.definition.budget ?? {}).filter(([k, limit]) => (metrics[k] ?? -Infinity) > limit).map(([k]) => k);\n}\n\n/** What is worth saying about the job in a few words, or null when all is well. */\nexport function laneNote(job: JobSummary, missed: number | null, now: number): string | null {\n const last = job.lastRun;\n if (job.silencedUntil !== null && job.silencedUntil > now) return `silenced until ${when(job.silencedUntil, now)}`;\n if (job.open.includes(\"missed\")) return missed !== null ? `due ${when(missed, now)}, nothing ran` : \"overdue, nothing ran\";\n if (last?.status === \"running\") {\n const stuck = safely(() => isStuck(job.definition, last, now), false);\n return stuck ? `running since ${when(last.startedAt, now)}, past its ${timeoutText(job)} timeout` : `running since ${when(last.startedAt, now)}`;\n }\n if (last?.status === \"failed\") return `failed at ${when(last.startedAt, now)}${job.consecutiveFailures > 1 ? `, ${job.consecutiveFailures} in a row` : \"\"}`;\n if (last?.status === \"timeout\") return `timed out at ${when(last.startedAt, now)}`;\n if (job.open.includes(\"stuck\")) return \"stuck\";\n if (job.open.includes(\"over_budget\") && last) {\n const over = overCeilings(job);\n return `went over budget${over.length ? ` on ${over.join(\" and \")}` : \"\"} at ${when(last.startedAt, now)}`;\n }\n if (job.open.includes(\"slow\") && last?.durationMs != null) return `slow: took ${formatDuration(last.durationMs)}`;\n if (job.open.includes(\"failed\")) return \"failing\";\n if (!last && job.nextExpectedAt !== null) return `no runs yet, first due ${when(job.nextExpectedAt, now)}`;\n return null;\n}\n\n/** Everything one lane shows: the marks, the note, and the same in words. */\nexport interface LaneInput {\n job: JobSummary;\n /** The job's runs, any order. Only those overlapping the span are drawn. */\n runs: Run[];\n /** False when older runs exist that were not read; the lane says so before its oldest run. */\n complete: boolean;\n}\n\ninterface LaneParts {\n svg: string;\n note: string;\n words: string;\n}\n\nconst f = (n: number) => n.toFixed(1);\n\n/** Animation delay for a mark at x, so marks arrive in time order, left to right. */\nconst delay = (x: number, base = 80, perUnit = 0.75) => `--d:${Math.round(base + Math.max(0, x) * perUnit)}ms`;\n\nfunction lane(input: LaneInput, span: Span, options: { nowInLane: boolean; label: string }): LaneParts {\n const { job } = input;\n const { from, to, now } = span;\n const x = (t: number) => Math.min(W, Math.max(0, ((t - from) / (to - from)) * W));\n const parsed = parsedSchedule(job);\n const due = dueTimes(job, parsed, input.runs, from, to);\n const missed = missedAt(job, parsed, due.times, now);\n const grace = safely(() => graceMs(job.definition), 0);\n const name = options.label;\n const busy: [number, number][] = [];\n\n let s = `<svg class=\"marks\" viewBox=\"0 0 ${W} 24\" preserveAspectRatio=\"none\" aria-hidden=\"true\" focusable=\"false\">`;\n if (options.nowInLane && now > from && now < to) s += `<rect class=\"ahead\" x=\"${f(x(now))}\" y=\"0\" width=\"${f(W - x(now))}\" height=\"24\"/>`;\n s += `<line class=\"base\" x1=\"0\" y1=\"12\" x2=\"${W}\" y2=\"12\"/>`;\n\n const inSpan = input.runs.filter((r) => r.startedAt <= to && (r.finishedAt ?? now) >= from).sort((a, b) => a.startedAt - b.startedAt);\n if (!input.complete) {\n const oldest = Math.min(...input.runs.map((r) => r.startedAt));\n if (Number.isFinite(oldest) && oldest > from) {\n s += `<rect class=\"unloaded\" x=\"0\" y=\"4\" width=\"${f(x(oldest))}\" height=\"16\"><title>${h(`${name}: runs before ${when(oldest, now)} UTC are not loaded here`)}</title></rect>`;\n }\n }\n\n if (due.dense) {\n s += `<line class=\"cadence\" x1=\"0\" y1=\"12\" x2=\"${W}\" y2=\"12\"><title>${h(`${name}: due ${job.definition.schedule ?? \"\"}, too often to mark each time`)}</title></line>`;\n }\n for (const t of due.times) {\n const tx = x(t);\n s += `<line class=\"tick${t > now ? \" ahead\" : \"\"}\" x1=\"${f(tx)}\" y1=\"6\" x2=\"${f(tx)}\" y2=\"18\" style=\"${delay(tx, 0, 0.45)}\"/>`;\n }\n\n // Missed slots: the reported one and every later one whose grace has run out.\n if (missed !== null && missed <= to) {\n const slots = due.dense ? [] : due.times.filter((t) => t >= missed && t + grace < now);\n if (!slots.includes(missed) && missed >= from) slots.unshift(missed);\n const title = h(`${name}: due ${when(missed, now)} UTC, nothing started${slots.length > 1 ? ` (${slots.length} slots in this span)` : \"\"}`);\n if (due.dense || slots.length > MAX_BOXES) {\n const x1 = x(Math.max(missed, from)), x2 = Math.max(x(now), x1 + MIN_BOX);\n s += `<rect class=\"missed\" x=\"${f(x1)}\" y=\"5\" width=\"${f(x2 - x1)}\" height=\"14\" style=\"${delay(x1)}\"><title>${title}</title></rect>`;\n busy.push([x1, x2]);\n } else {\n for (const t of slots) {\n if (t < from) continue;\n const x1 = x(t), width = Math.max(x(t + grace) - x1, MIN_BOX);\n s += `<rect class=\"missed\" x=\"${f(x1)}\" y=\"5\" width=\"${f(width)}\" height=\"14\" style=\"${delay(x1)}\"><title>${title}</title></rect>`;\n busy.push([x1, x1 + width]);\n }\n }\n }\n\n for (const run of inSpan) {\n const tone = toneOf(run, job, now);\n // A zero-width rect is not drawn at all; its stroke gives short runs their width.\n const x1 = x(run.startedAt), x2 = Math.max(x(run.finishedAt ?? now), x1 + 0.5);\n s += `<rect class=\"run ${tone}\" x=\"${f(x1)}\" y=\"5\" width=\"${f(x2 - x1)}\" height=\"14\" style=\"${delay(x1)}\"><title>${h(`${name}: ${describeRun(run, tone, job, now)}`)}</title></rect>`;\n busy.push([x1, x2]);\n }\n\n if (options.nowInLane && now > from && now < to) s += `<line class=\"nowline\" x1=\"${f(x(now))}\" y1=\"0\" x2=\"${f(x(now))}\" y2=\"24\"/>`;\n s += `</svg>`;\n\n // The note goes wherever the lane is actually empty, so it never sits on\n // the marks it describes; it is cut short with an ellipsis when narrow.\n const text = laneNote(job, missed, now);\n let note = \"\";\n if (text) {\n const nowX = x(now);\n const lo = busy.length ? Math.min(...busy.map((b) => b[0])) : nowX;\n const hi = busy.length ? Math.max(...busy.map((b) => b[1])) : nowX;\n const right = W - hi >= lo;\n const room = right ? W - hi : lo;\n if (room > 90) {\n const edge = right ? hi + 14 : lo - 14;\n const place = right ? `left:${f(edge / 10)}%` : `right:${f(100 - edge / 10)}%`;\n note = `<span class=\"note${right ? \"\" : \" before\"}\" style=\"${place};max-width:${f((room - 18) / 10)}%\">${h(text)}</span>`;\n }\n }\n\n return { svg: s, note, words: words(job, inSpan, due, missed, span, text) };\n}\n\n/** The lane in words, for anyone who cannot see it. */\nfunction words(job: JobSummary, runs: Run[], due: DueTimes, missed: number | null, span: Span, note: string | null): string {\n const parts: string[] = [];\n if (due.dense) parts.push(`due ${job.definition.schedule}`);\n else if (job.definition.schedule) {\n const n = due.times.filter((t) => t <= span.now).length;\n parts.push(`due ${n === 0 ? \"no times\" : n === 1 ? \"once\" : `${n} times`} so far`);\n }\n const ok = runs.filter((r) => r.status === \"ok\").length;\n parts.push(`${runs.length} ${runs.length === 1 ? \"run\" : \"runs\"} recorded${!runs.length ? \"\" : ok === runs.length ? (ok === 1 ? \", ok\" : \", all ok\") : ok ? `, ${ok} ok` : \"\"}`);\n for (const r of runs.filter((r) => r.status === \"failed\" || r.status === \"timeout\").slice(-5)) {\n parts.push(`${r.status} at ${when(r.startedAt, span.now)} UTC after ${formatDuration(r.durationMs ?? 0)}`);\n }\n if (missed !== null) parts.push(`due at ${when(missed, span.now)} UTC and nothing started`);\n if (note && !/^(due |failed at|timed out)/.test(note)) parts.push(note);\n return parts.join(\"; \");\n}\n\n/** Grid lines and hour labels every `step`, on UTC boundaries. */\nfunction hours(span: Span, step: number, nowLabel: boolean): { lines: string; labels: string } {\n const x = (t: number) => ((t - span.from) / (span.to - span.from)) * W;\n const nowX = x(span.now);\n let lines = \"\", labels = \"\";\n for (let t = Math.ceil(span.from / step) * step; t <= span.to; t += step) {\n const gx = x(t);\n lines += `<i class=\"gl\" style=\"left:${f(gx / 10)}%\"></i>`;\n const nearNow = nowLabel && Math.abs(gx - nowX) < 70;\n if (gx < 25 || gx > W - 25 || nearNow) continue;\n const minor = Math.round(t / HOUR) % 6 !== 0;\n // On a phone the track is too narrow for a label this close to \"now\"; CSS hides it there.\n const near = nowLabel && Math.abs(gx - nowX) < 170;\n const cls = [minor && \"minor\", near && \"near\"].filter(Boolean).join(\" \");\n labels += `<span class=\"${cls}\" style=\"left:${f(gx / 10)}%\">${clock(t)}</span>`;\n }\n if (nowLabel && span.now >= span.from && span.now <= span.to) labels += `<span class=\"nowlabel\" style=\"left:${f(nowX / 10)}%\">now ${clock(span.now)}</span>`;\n return { lines, labels };\n}\n\n/** The key under a timeline: a small sample of each mark and what it means. */\nfunction legend(): string {\n const key = (inner: string) => `<svg class=\"key\" viewBox=\"0 0 16 12\" aria-hidden=\"true\" focusable=\"false\">${inner}</svg>`;\n const box = (cls: string) => key(`<rect class=\"${cls}\" x=\"2\" y=\"1\" width=\"12\" height=\"10\"/>`);\n const items: [string, string][] = [\n [key(`<line class=\"tick\" x1=\"8\" y1=\"1\" x2=\"8\" y2=\"11\"/>`), \"due\"],\n [box(\"run ok\"), \"ran\"],\n [box(\"run bad\"), \"failed\"],\n [box(\"run timeout\"), \"timed out\"],\n [box(\"run warn\"), \"over budget or slow\"],\n [box(\"run running\"), \"running\"],\n [box(\"missed\"), \"missed\"],\n ];\n return `<p class=\"legend\" aria-hidden=\"true\">${items.map(([k, label]) => `<span>${k}${label}</span>`).join(\"\")}</p>`;\n}\n\nfunction stateClass(job: JobSummary): string {\n return ({ healthy: \"ok\", late: \"warn\", failing: \"bad\", stuck: \"bad\", silenced: \"muted\", never_ran: \"muted\" } as const)[job.health];\n}\n\n/**\n * The board's timeline: one lane per job across `span`, with a shared now\n * line and the first BOARD_LANES jobs only. `total` is how many jobs there\n * are in all, for the note when some are left out.\n */\nexport function dayTimeline(lanes: LaneInput[], span: Span, base: string, total: number): string {\n const grid = hours(span, 3 * HOUR, true);\n const nowX = ((span.now - span.from) / (span.to - span.from)) * 100;\n const rows = lanes.map((input) => {\n const { job } = input;\n const parts = lane(input, span, { nowInLane: false, label: job.name });\n return {\n html: `<li class=\"lane\"><div class=\"who\"><i class=\"sq ${stateClass(job)}\" aria-hidden=\"true\"></i><a class=\"name\" href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${h(job.name)}</a><span class=\"sched\">${h(job.definition.schedule ?? \"no schedule\")}</span></div><div class=\"track\">${parts.svg}${parts.note}</div></li>`,\n words: `<li>${h(`${job.name} (${job.definition.schedule ?? \"no schedule\"}): ${parts.words}.`)}</li>`,\n };\n });\n const more = total > lanes.length ? `<p class=\"more\">Showing the first ${lanes.length} of ${total} jobs here; the table below lists them all.</p>` : \"\";\n return `<figure class=\"timeline day\">\n<div class=\"axis\" aria-hidden=\"true\"><span></span><div class=\"hours\">${grid.labels}</div></div>\n<div class=\"field\">\n<div class=\"under\" aria-hidden=\"true\"><span></span><div>${grid.lines}<i class=\"future\" style=\"left:${f(nowX)}%\"></i></div></div>\n<ol class=\"lanes\">${rows.map((r) => r.html).join(\"\")}</ol>\n<div class=\"over\" aria-hidden=\"true\"><span></span><div><i class=\"now\" style=\"left:${f(nowX)}%\"></i></div></div>\n</div>\n${legend()}${more}\n<ul class=\"vh\">${rows.map((r) => r.words).join(\"\")}</ul>\n</figure>`;\n}\n\n/**\n * A job's page: its last WEEK_DAYS UTC days, today first, one lane each.\n * `complete` is false when the runs read do not reach back over the week.\n */\nexport function weekTimeline(job: JobSummary, runs: Run[], complete: boolean, now: number): string {\n const today = Math.floor(now / DAY) * DAY;\n const oldest = runs.length ? Math.min(...runs.map((r) => r.startedAt)) : null;\n const first: Span = { from: today, to: today + DAY, now };\n const grid = hours(first, 3 * HOUR, false);\n const rows: { html: string; words: string }[] = [];\n for (let i = 0; i < WEEK_DAYS; i++) {\n const from = today - i * DAY;\n const span: Span = { from, to: from + DAY, now };\n const dayRuns = runs.filter((r) => r.startedAt < span.to && (r.finishedAt ?? now) >= from);\n const known = complete || (oldest !== null && oldest <= from);\n const label = i === 0 ? \"today\" : dayLabel(from);\n const parts = lane({ job, runs, complete: known }, span, { nowInLane: i === 0, label: `${job.name}, ${label}` });\n const count = `${dayRuns.length} ${dayRuns.length === 1 ? \"run\" : \"runs\"}`;\n rows.push({\n html: `<li class=\"lane${i === 0 ? \" today\" : \"\"}\"><div class=\"who\"><span class=\"name\">${h(i === 0 ? `Today, ${dayLabel(from).slice(4)}` : dayLabel(from))}</span><span class=\"sched\">${h(count)}</span></div><div class=\"track\">${parts.svg}${i === 0 ? parts.note : \"\"}</div></li>`,\n words: `<li>${h(`${i === 0 ? \"Today\" : dayLabel(from)}: ${parts.words}.`)}</li>`,\n });\n }\n return `<figure class=\"timeline week\">\n<div class=\"axis\" aria-hidden=\"true\"><span></span><div class=\"hours\">${grid.labels}</div></div>\n<div class=\"field\">\n<div class=\"under\" aria-hidden=\"true\"><span></span><div>${grid.lines}</div></div>\n<ol class=\"lanes\">${rows.map((r) => r.html).join(\"\")}</ol>\n</div>\n${legend()}\n<ul class=\"vh\">${rows.map((r) => r.words).join(\"\")}</ul>\n</figure>`;\n}\n\n/**\n * How many runs a job's page reads so its week is drawn in full: roughly how\n * often the schedule was due over the week, with room to spare, from 50 (what\n * the run list shows) to 500 (the most runs() returns).\n */\nexport function weekRunsLimit(job: JobSummary, now: number): number {\n const parsed = parsedSchedule(job);\n if (!parsed) return 50;\n const from = Math.floor(now / DAY) * DAY - (WEEK_DAYS - 1) * DAY;\n const span = now + DAY - from;\n // A cron's fires over one day, times the week: close enough, and cheap.\n const expected = parsed.kind === \"interval\"\n ? span / parsed.everyMs!\n : (() => {\n const due = dueTimes(job, parsed, [], now - DAY, now);\n return due.dense ? Infinity : (due.times.length * span) / DAY;\n })();\n return Math.min(500, Math.max(50, Math.ceil(expected * 1.2) + 10));\n}\n","import { formatDuration, formatRelative } from \"../duration.js\";\nimport type { JobSummary, Run } from \"../types.js\";\nimport { escapeHtml } from \"./escape.js\";\nimport { THEME_COLOR, THEME_COLOR_DARK } from \"./pwa.js\";\nimport { BOARD_LANES, BOARD_AHEAD_MS, BOARD_BEHIND_MS, clock, dayTimeline, laneNote, missedAt, parsedSchedule, weekTimeline, when, type LaneInput } from \"./timeline.js\";\n\nexport { escapeHtml };\n\nconst h = escapeHtml;\n\n/*\n * Set like cronwatch.dev: a printed sheet on grey paper, a serif for what a\n * person reads, a mono for what a machine printed, neutral greys, and colour\n * only for the states CronWatch reports. The page loads nothing but its own\n * app shell (its CSP is default-src 'none' plus 'self' for the script, the\n * manifest, the worker and images), so the fonts are system stacks that echo\n * the site's Newsreader and IBM Plex Mono, and use them when they are installed.\n *\n * Installed as an app (display-mode: standalone) the header stays at the top\n * as the app's bar, and the page keeps clear of notches and the home\n * indicator with the safe-area insets (the viewport is viewport-fit=cover).\n *\n * Motion is CSS only and says something: marks arrive in time order, the now\n * line drops in last, and open problems (a missed slot, a running bar) breathe\n * slowly. prefers-reduced-motion turns all of it off. Only opacity and\n * transform move, so nothing shifts the layout.\n */\nconst CSS = `\n:root{color-scheme:light dark;--paper:#f4f4f5;--sheet:#fff;--sunk:#fafafa;--rule:#e4e4e7;--rule-2:#d4d4d8;--tick:#909098;--ink:#000;--body:#18181b;--muted:#71717a;--ok:#15803d;--warn:#a16207;--bad:#b91c1c;--serif:\"Newsreader\",ui-serif,Georgia,Cambria,\"Times New Roman\",serif;--mono:\"IBM Plex Mono\",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;--who:200px}\n@media(prefers-color-scheme:dark){:root{--paper:#09090b;--sheet:#111113;--sunk:#18181b;--rule:#27272a;--rule-2:#3f3f46;--tick:#66666f;--ink:#fff;--body:#e4e4e7;--muted:#a1a1aa;--ok:#4ade80;--warn:#fbbf24;--bad:#f87171}}\n*{box-sizing:border-box}html{-webkit-text-size-adjust:100%}\nbody{margin:0;background:var(--paper);color:var(--ink);font:400 16px/1.55 var(--serif);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}\na{color:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.16em;text-decoration-color:var(--rule-2)}a:hover{text-decoration-color:currentColor}\n:focus-visible{outline:2px solid var(--ink);outline-offset:2px}\ncode,pre,.mono{font-family:var(--mono)}\n.vh{position:absolute!important;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n.sheet{max-width:1180px;min-height:100vh;margin:0 auto;background:var(--sheet);border-inline:1px solid var(--rule);padding:0 clamp(16px,4vw,48px)}\n.top{display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap;padding:18px 0 17px;border-bottom:1px solid var(--rule)}\n.brand{display:flex;align-items:center;gap:10px;margin:0;font:600 18px/1.2 var(--serif);letter-spacing:-.01em;min-width:0}\n.brand a{display:inline-flex;align-items:center;gap:10px;text-decoration:none}.brand svg{width:24px;height:24px;flex:none;color:var(--ink)}\n.brand .crumb{font:500 15px/1.2 var(--mono);color:var(--body);overflow-wrap:anywhere}.brand .slash{color:var(--rule-2);font-weight:400}\n.actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}\n.meta{font:400 12px/1.4 var(--mono);color:var(--muted)}\nbutton,select,details.confirm>summary{font:500 12.5px/1 var(--mono);color:var(--ink);background:var(--sheet);border:1px solid var(--rule-2);border-radius:3px;padding:8px 11px;cursor:pointer}\nselect{padding:7px 8px}\nbutton:hover,select:hover,details.confirm>summary:hover{border-color:var(--muted)}\nbutton.primary{background:var(--ink);border-color:var(--ink);color:var(--sheet)}button.primary:hover{opacity:.86}\nform.inline{display:inline-flex;align-items:center;gap:6px;margin:0}\ndetails.confirm{display:inline-flex;align-items:center;gap:8px;margin:0}details.confirm>summary{list-style:none;display:inline-block}\ndetails.confirm>summary::-webkit-details-marker{display:none}details.confirm[open]>summary{border-color:var(--muted)}\ndetails.confirm form{margin-left:8px;font-size:14px;color:var(--muted)}\n.sec{display:grid;grid-template-columns:150px minmax(0,1fr);gap:10px 40px;padding:30px 0;border-top:1px solid var(--rule)}\n.top+main>.sec:first-child{border-top:0}\n.sec>h2{margin:0;font:500 11px/1.5 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding-top:5px}\n.sec>.wide{grid-column:1/-1;min-width:0}\n.lede{margin:0;color:var(--muted);font-size:16px;max-width:64ch;text-wrap:pretty}\n.headline{margin:0;font:400 clamp(24px,3.2vw,32px)/1.2 var(--serif);letter-spacing:-.01em;text-wrap:balance}\n.headline b{font-weight:600}\n.state{font:500 12.5px/1.4 var(--mono);white-space:nowrap}.state+.state::before{content:\" \\\\00b7 \";color:var(--muted);font-weight:400}\n.ok{color:var(--ok)}.warn{color:var(--warn)}.bad{color:var(--bad)}.muted{color:var(--muted)}.info{color:var(--ink)}\n.sq{display:inline-block;width:8px;height:8px;border-radius:1.5px;background:currentColor;margin-right:7px;vertical-align:1px;flex:none}\n.sq.muted{background:none;box-shadow:inset 0 0 0 1.5px var(--tick)}\n.figures{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:0;margin:22px 0 0;border-top:1px solid var(--rule)}\n.figures>div{display:flex;flex-direction:column-reverse;justify-content:flex-end;gap:4px;padding:14px 16px 2px 0}\n.figures dt{font:500 11px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:flex;align-items:center}\n.figures dd{margin:0;font:400 30px/1.1 var(--serif);font-variant-numeric:tabular-nums;color:var(--ink)}\n.figures dd small{font-size:17px;color:var(--muted)}\n.figures .zero dd{color:var(--rule-2)}\n.figures .bad dd{color:var(--bad)}.figures .warn dd{color:var(--warn)}\n.stateline{margin:12px 0 0;display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px}\n.stateline .why{font-style:italic;color:var(--muted)}\n.jobname{margin:0;font:500 clamp(22px,3vw,28px)/1.2 var(--mono);letter-spacing:-.01em;overflow-wrap:anywhere}\n.desc{margin:6px 0 0;color:var(--body);max-width:64ch}\n.intro .actions{margin-top:18px}\ntable{width:100%;border-collapse:collapse}\nth{text-align:left;font:500 10.5px/1.2 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted);padding:0 14px 10px 0;border-bottom:1px solid var(--rule);white-space:nowrap}\ntd{padding:12px 14px 12px 0;border-bottom:1px solid var(--rule);vertical-align:top;font:400 12.5px/1.5 var(--mono);color:var(--body)}\ntbody tr:last-child td{border-bottom:0}\ntd.job{font-family:var(--serif);font-size:15px;min-width:180px}\ntd.job .name{font:500 13.5px/1.5 var(--mono);color:var(--ink)}\ntd.job .desc{display:block;margin:2px 0 0;font-size:14px;color:var(--muted);line-height:1.4}\ntd .tz,td .sub{display:block;color:var(--muted);font-size:11.5px}\n.nowrap{white-space:nowrap}\n.spark{display:block;overflow:visible}.spark rect{fill:var(--tick)}.spark rect.bad{fill:var(--bad)}.spark rect.warn{fill:var(--warn)}.spark rect.running{fill:none;stroke:var(--ink);stroke-width:1}\n.runs td{padding-top:11px;padding-bottom:11px}.runs tr.has-detail td{border-bottom:0;padding-bottom:4px}.runs tr.detail td{padding-top:0}\n.metrics{display:flex;flex-wrap:wrap;gap:2px 14px}.metrics .k{color:var(--muted)}\npre{margin:6px 0 0;padding:12px 14px;background:var(--sunk);border:1px solid var(--rule);border-radius:3px;font:400 12.5px/1.55 var(--mono);color:var(--body);white-space:pre-wrap;overflow-wrap:anywhere;max-height:340px;overflow:auto}\ndetails.out{margin-top:4px}details.out>summary{cursor:pointer;font:400 12px/1.6 var(--mono);color:var(--muted)}details.out>summary:hover{color:var(--ink)}\ndetails.out.error>summary{color:var(--bad)}\ndl.def{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 28px;margin:0}\ndl.def dt{font:500 11px/1.9 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\ndl.def dd{margin:0;font:400 13.5px/1.7 var(--mono);color:var(--body);overflow-wrap:anywhere}dl.def dd.prose{font:400 16px/1.55 var(--serif)}\n.empty{padding:28px 0 8px;color:var(--muted);max-width:60ch}\n.empty code{font-size:.86em;color:var(--ink)}\n.message{padding:clamp(56px,12vh,120px) 0;text-align:center}\n.message h1{margin:0;font:400 clamp(28px,4vw,40px)/1.15 var(--serif);letter-spacing:-.015em}\n.message p{margin:14px auto 0;max-width:52ch;color:var(--muted);text-wrap:pretty}\n.signin{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin:28px auto 0;max-width:420px}\n.signin label{font:500 11px/1.4 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\n.signin input{flex:1 1 180px;min-width:0;font:400 16px/1.2 var(--mono);color:var(--ink);background:var(--sheet);border:1px solid var(--rule-2);border-radius:3px;padding:8px 10px}\nfooter{display:flex;flex-wrap:wrap;gap:6px 18px;padding:20px 0 40px;border-top:1px solid var(--rule);font:400 12px/1.5 var(--mono);color:var(--muted)}\n.timeline{margin:18px 0 0}\n.timeline .axis,.timeline .under,.timeline .over,.timeline .lane{display:grid;grid-template-columns:var(--who) minmax(0,1fr)}\n.timeline .hours{position:relative;height:22px;font:400 11px/1 var(--mono);color:var(--muted);letter-spacing:.04em}\n.timeline .hours span{position:absolute;top:2px;transform:translateX(-50%);white-space:nowrap}\n.timeline .hours .nowlabel{color:var(--ink);font-weight:500;animation:cw-fade .5s 1s both}\n.timeline .field{position:relative}\n.timeline .under,.timeline .over{position:absolute;inset:0;pointer-events:none}\n.timeline .under>div,.timeline .over>div{position:relative}\n.timeline .gl{position:absolute;top:0;bottom:0;width:1px;background:var(--rule)}\n.timeline .future{position:absolute;top:0;bottom:0;right:0;background:var(--sunk)}\n.timeline .now{position:absolute;top:-6px;bottom:0;width:1.5px;margin-left:-.75px;background:var(--ink);transform-origin:top;animation:cw-drop .6s .85s cubic-bezier(.2,.8,.2,1) both}\n.timeline .lanes{position:relative;list-style:none;margin:0;padding:0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}\n.timeline .lane{align-items:center;min-height:40px}\n.timeline .who{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;column-gap:0;padding:6px 14px 6px 0;min-width:0}\n.timeline .who .sched{grid-column:2}\n.timeline.week .who{display:flex;align-items:baseline;gap:10px}\n.timeline .who .name{font:500 13px/1.35 var(--mono);color:var(--ink);overflow-wrap:anywhere}\n.timeline .who .sched{font:400 11px/1.35 var(--mono);color:var(--muted);white-space:nowrap}\n.timeline .track{position:relative;height:24px}\n.timeline .marks{display:block;width:100%;height:24px;overflow:visible}\n.timeline .note{position:absolute;top:50%;transform:translateY(-50%);font:italic 400 14px/1.2 var(--serif);color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 3px;text-shadow:0 0 3px var(--sheet),0 0 3px var(--sheet),0 0 6px var(--sheet);animation:cw-fade .6s 1.1s both}\n.timeline .note.before{text-align:right}\n.timeline .legend{display:flex;flex-wrap:wrap;gap:6px 18px;margin:14px 0 0;padding-left:var(--who);font:400 11.5px/1.4 var(--mono);color:var(--muted)}\n.timeline .legend span{display:inline-flex;align-items:center;gap:7px}\n.timeline .more{margin:10px 0 0;padding-left:var(--who);font-size:14px;color:var(--muted);font-style:italic}\n.key{width:16px;height:12px;overflow:visible}\n.marks *{vector-effect:non-scaling-stroke}\nsvg .base{stroke:var(--rule);stroke-width:1}\nsvg .tick{stroke:var(--tick);stroke-width:1.5}svg .tick.ahead{stroke-dasharray:2 2;opacity:.75}\nsvg .cadence{stroke:var(--tick);stroke-width:2;stroke-dasharray:1 3}\nsvg .run{stroke-width:2;stroke-linejoin:round}\nsvg .run.ok{fill:var(--ok);stroke:var(--ok)}\nsvg .run.bad{fill:var(--bad);stroke:var(--bad)}\nsvg .run.timeout{fill:var(--bad);fill-opacity:.28;stroke:var(--bad);stroke-width:1.5}\nsvg .run.warn{fill:var(--warn);stroke:var(--warn)}\nsvg .run.running{fill:none;stroke:var(--ink);stroke-width:1.5}\nsvg .run.stuck{fill:var(--bad);fill-opacity:.12;stroke:var(--bad);stroke-width:1.5}\nsvg .missed{fill:none;stroke:var(--bad);stroke-width:1.5;stroke-dasharray:3 2.5}\nsvg .unloaded{fill:var(--sunk)}\nsvg .ahead{fill:var(--sunk)}\nsvg .nowline{stroke:var(--ink);stroke-width:1.5}\n.marks .tick{animation:cw-fade .4s var(--d,0ms) both}\n.marks .run,.marks .missed{transform-box:fill-box;transform-origin:0 50%;animation:cw-grow .55s cubic-bezier(.2,.8,.2,1) var(--d,0ms) both}\n.marks .missed,.marks .run.running,.marks .run.stuck{animation:cw-grow .55s cubic-bezier(.2,.8,.2,1) var(--d,0ms) both,cw-breathe 2.6s ease-in-out calc(var(--d,0ms) + .6s) infinite alternate}\n.figures>div{animation:cw-rise .5s cubic-bezier(.2,.8,.2,1) both}\n.figures>div:nth-child(2){animation-delay:40ms}.figures>div:nth-child(3){animation-delay:80ms}.figures>div:nth-child(4){animation-delay:120ms}.figures>div:nth-child(5){animation-delay:160ms}.figures>div:nth-child(6){animation-delay:200ms}\n@keyframes cw-fade{from{opacity:0}}\n@keyframes cw-grow{from{opacity:0;transform:scaleX(0)}}\n@keyframes cw-drop{from{opacity:0;transform:scaleY(0)}}\n@keyframes cw-rise{from{opacity:0;transform:translateY(4px)}}\n@keyframes cw-breathe{to{opacity:.38}}\nbody{padding:0 env(safe-area-inset-right) 0 env(safe-area-inset-left)}\nfooter{padding-bottom:calc(40px + env(safe-area-inset-bottom))}\n@media(display-mode:standalone){\n.top{position:sticky;top:0;z-index:2;background:var(--sheet);padding-top:calc(14px + env(safe-area-inset-top));padding-bottom:13px;-webkit-user-select:none;user-select:none}\n.message{padding-top:clamp(40px,8vh,80px)}\n}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}\n@media(max-width:760px){\n.sec{grid-template-columns:minmax(0,1fr);gap:10px;padding:24px 0}\n.hide-sm{display:none}\n:root{--who:0px}\n.timeline .lane{grid-template-columns:minmax(0,1fr);padding:6px 0 8px}\n.timeline .who{padding:0 0 4px}\n.timeline .who .name{background:var(--sheet);padding-right:4px}\n.timeline .hours .minor,.timeline .hours .near{display:none}\n.timeline .note{font-size:13px}\ntd.job{min-width:0}\ntable.board thead{display:none}\ntable.board tr{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:14px;padding:12px 0;border-bottom:1px solid var(--rule)}\ntable.board tbody tr:last-child{border-bottom:0}\ntable.board td{border:0;padding:0}\ntable.board td.last{grid-column:1/-1;margin-top:4px;white-space:normal}\ntable.board td.last .sub{display:inline;margin-left:8px}\n.runs td.nowrap{white-space:normal}\ndl.def{grid-template-columns:minmax(0,1fr);gap:0}dl.def dd{margin-bottom:10px}\n}\n`;\n\n/** The clock face from cronwatch.dev, in the text colour. */\nconst MARK = `<svg viewBox=\"0 0 40 40\" aria-hidden=\"true\" focusable=\"false\"><rect x=\"1\" y=\"1\" width=\"38\" height=\"38\" rx=\"9.5\" fill=\"none\" stroke=\"currentColor\" stroke-opacity=\".22\" stroke-width=\"1.5\"/><circle cx=\"20\" cy=\"20\" r=\"10.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"/><path d=\"M20 12.5V20h6\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;\n\n/**\n * A page. `base` is where the dashboard is mounted (\"\" at the root): the head\n * links the web app manifest, the icons and app.js, the one script, which\n * only registers the service worker (routes/pwa.ts). Everything works\n * without it.\n */\nexport function layout(title: string, body: string, base: string, options: { refresh?: number } = {}): string {\n const b = h(base);\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">\n<meta name=\"robots\" content=\"noindex,nofollow\">\n<meta name=\"color-scheme\" content=\"light dark\">\n${options.refresh ? `<meta http-equiv=\"refresh\" content=\"${options.refresh}\">` : \"\"}\n<title>${h(title)}</title>\n<meta name=\"theme-color\" content=\"${THEME_COLOR}\" media=\"(prefers-color-scheme: light)\">\n<meta name=\"theme-color\" content=\"${THEME_COLOR_DARK}\" media=\"(prefers-color-scheme: dark)\">\n<meta name=\"mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-title\" content=\"CronWatch\">\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"default\">\n<link rel=\"manifest\" href=\"${b}/manifest.webmanifest\">\n<link rel=\"icon\" href=\"${b}/icons/icon.svg\" type=\"image/svg+xml\">\n<link rel=\"apple-touch-icon\" href=\"${b}/icons/apple-touch-icon.png\">\n<script src=\"${b}/app.js\" defer></script>\n<style>${CSS}</style>\n</head>\n<body><div class=\"sheet\">${body}</div></body>\n</html>`;\n}\n\nfunction brand(base: string, crumb?: string): string {\n const home = `<a href=\"${h(base)}/\">${MARK}<span>CronWatch</span></a>`;\n return crumb === undefined\n ? `<p class=\"brand\">${home}</p>`\n : `<p class=\"brand\">${home}<span class=\"slash\" aria-hidden=\"true\">/</span><span class=\"crumb\">${h(crumb)}</span></p>`;\n}\n\nconst HEALTH: Record<JobSummary[\"health\"], [string, string]> = {\n failing: [\"bad\", \"failing\"],\n stuck: [\"bad\", \"stuck\"],\n late: [\"warn\", \"late\"],\n healthy: [\"ok\", \"healthy\"],\n silenced: [\"muted\", \"silenced\"],\n never_ran: [\"muted\", \"never ran\"],\n};\n\n/** The job's health, with any open condition it does not already say (over budget, slow) after it. */\nfunction healthState(job: JobSummary): string {\n const [cls, label] = HEALTH[job.health];\n const extras = job.open.filter((c) => ![\"missed\", \"failed\", \"stuck\"].includes(c)).map((c) => `<span class=\"state warn\">${h(c.replace(\"_\", \" \"))}</span>`).join(\"\");\n return `<span class=\"state ${cls}\"><i class=\"sq ${cls}\" aria-hidden=\"true\"></i>${label}</span>${extras}`;\n}\n\nfunction runState(run: Run): string {\n const cls = run.status === \"ok\" ? \"ok\" : run.status === \"running\" ? \"info\" : \"bad\";\n return `<span class=\"state ${cls}\">${h(run.status)}</span>`;\n}\n\n/** The last twenty runs, oldest first, as bars as tall as they took; grey unless something went wrong. */\nfunction sparkline(runs: Run[]): string {\n const points = [...runs].slice(0, 20).reverse();\n if (points.length < 2) return \"\";\n const bar = 4, gap = 1.5, hgt = 22;\n const max = Math.max(...points.map((r) => r.durationMs ?? 0), 1);\n const bars = points.map((r, i) => {\n const x = (i * (bar + gap)).toFixed(1);\n if (r.status === \"running\") return `<rect class=\"running\" x=\"${x}\" y=\"${hgt - 6.5}\" width=\"${bar - 1}\" height=\"6\"/>`;\n const tall = Math.max(r.status === \"ok\" ? 2 : 6, ((r.durationMs ?? 0) / max) * hgt);\n const cls = r.status === \"ok\" ? \"\" : ` class=\"bad\"`;\n return `<rect${cls} x=\"${x}\" y=\"${(hgt - tall).toFixed(1)}\" width=\"${bar}\" height=\"${tall.toFixed(1)}\" rx=\".5\"/>`;\n }).join(\"\");\n const w = points.length * (bar + gap) - gap;\n return `<svg class=\"spark\" width=\"${w.toFixed(1)}\" height=\"${hgt}\" viewBox=\"0 0 ${w.toFixed(1)} ${hgt}\" aria-hidden=\"true\" focusable=\"false\">${bars}</svg>`;\n}\n\nfunction stamp(at: number | null, now: number): string {\n if (at === null) return `<span class=\"muted\">never</span>`;\n const iso = new Date(at).toISOString();\n return `<time class=\"nowrap\" datetime=\"${iso}\" title=\"${iso.replace(\"T\", \" \").slice(0, 19)} UTC\">${h(formatRelative(at, now))}</time>`;\n}\n\n/** Counts by health, the ones needing attention first; a zero is set faint rather than left out, so the row keeps its shape. */\nfunction healthFigures(jobs: JobSummary[]): string {\n return `<dl class=\"figures\">${(Object.keys(HEALTH) as JobSummary[\"health\"][]).map((health) => {\n const [cls, label] = HEALTH[health];\n const n = jobs.filter((j) => j.health === health).length;\n return `<div class=\"${n === 0 ? \"zero\" : cls}\"><dt><i class=\"sq ${cls}\" aria-hidden=\"true\"></i>${label}</dt><dd>${n}</dd></div>`;\n }).join(\"\")}</dl>`;\n}\n\nexport function dashboardPage(\n jobs: JobSummary[],\n runsByJob: Map<string, Run[]>,\n now: number,\n base: string,\n checkedAt: number | null,\n lanes: LaneInput[] = jobs.slice(0, BOARD_LANES).map((job) => ({ job, runs: runsByJob.get(job.name) ?? [], complete: true })),\n): string {\n const attention = jobs.filter((j) => j.health !== \"healthy\").length;\n const headline = jobs.length === 0\n ? \"No jobs yet.\"\n : attention === 0\n ? `${jobs.length === 1 ? \"The one job is\" : `All ${jobs.length} jobs are`} healthy.`\n : `${jobs.length} job${jobs.length === 1 ? \"\" : \"s\"}, <b>${attention} needing attention</b>.`;\n\n const rows = jobs.map((job) => {\n const last = job.lastRun;\n const d = job.definition;\n return `<tr>\n<td class=\"job\"><a class=\"name\" href=\"${h(base)}/jobs/${encodeURIComponent(job.name)}\">${h(job.name)}</a>${d.description ? `<span class=\"desc\">${h(d.description)}</span>` : \"\"}</td>\n<td class=\"health\">${healthState(job)}</td>\n<td class=\"nowrap hide-sm\">${d.schedule ? `${h(d.schedule)}${d.timezone ? `<span class=\"tz\">${h(d.timezone)}</span>` : \"\"}` : `<span class=\"muted\">no schedule</span>`}</td>\n<td class=\"nowrap last\">${last ? `${runState(last)} ${stamp(last.startedAt, now)}${last.durationMs !== null ? `<span class=\"sub\">took ${h(formatDuration(last.durationMs))}</span>` : \"\"}` : `<span class=\"muted\">never</span>`}</td>\n<td class=\"nowrap hide-sm\">${job.nextExpectedAt !== null ? `${job.nextExpectedAt < now ? `<span class=\"state warn\">overdue</span> ` : \"\"}${stamp(job.nextExpectedAt, now)}<span class=\"sub\">${h(when(job.nextExpectedAt, now))} UTC</span>` : `<span class=\"muted\">not scheduled</span>`}</td>\n<td class=\"hide-sm\">${sparkline(runsByJob.get(job.name) ?? [])}</td>\n</tr>`;\n }).join(\"\\n\");\n\n const span = { from: now - BOARD_BEHIND_MS, to: now + BOARD_AHEAD_MS, now };\n const body = `\n<header class=\"top\">\n ${brand(base)}\n <div class=\"actions\">\n <span class=\"meta\">${h(clock(now))} UTC${checkedAt ? `, checked ${h(formatRelative(checkedAt, now))}` : \"\"}</span>\n <form class=\"inline\" method=\"post\" action=\"${h(base)}/check\"><button class=\"primary\" type=\"submit\">Run check now</button></form>\n </div>\n</header>\n<main>\n<section class=\"sec\" aria-label=\"Health\">\n <h2>Health</h2>\n <div>\n <p class=\"headline\">${headline}</p>\n ${jobs.length ? healthFigures(jobs) : `<p class=\"empty\">Declare one with <code>cw.job(\"name\", { schedule: \"0 2 * * *\" })</code> and run it once, and it shows up here.</p>`}\n </div>\n</section>\n${jobs.length ? `<section class=\"sec\" aria-label=\"Last 24 hours\">\n <h2>Last 24 hours</h2>\n <p class=\"lede\">One lane per job. Faint ticks mark when it was due, bars the runs it recorded, as long as they took. A dashed box is a slot nothing ran in. Times are UTC.</p>\n <div class=\"wide\">${dayTimeline(lanes, span, base, jobs.length)}</div>\n</section>\n<section class=\"sec\" aria-label=\"Jobs\">\n <h2>Jobs</h2>\n <p class=\"lede\">Every job in the store. Open one for its week, its runs and their output.</p>\n <div class=\"wide\"><table class=\"board\">\n<thead><tr><th>Job</th><th>Health</th><th class=\"hide-sm\">Schedule</th><th>Last run</th><th class=\"hide-sm\">Next due</th><th class=\"hide-sm\">Recent runs</th></tr></thead>\n<tbody>${rows}</tbody></table></div>\n</section>` : \"\"}\n</main>\n<footer><span>Refreshes every minute. Times are UTC.</span><a href=\"${h(base)}/api/jobs\">JSON</a></footer>`;\n return layout(\"CronWatch\", body, base, { refresh: 60 });\n}\n\n/**\n * One job: its state and figures, its last seven days, its runs with their\n * output, and its definition. `complete` is false when `runs` does not reach\n * back over the whole week (the run list shows the newest fifty).\n */\nexport function jobPage(job: JobSummary, runs: Run[], now: number, base: string, complete = true): string {\n const d = job.definition;\n const okRate = `${Math.round(job.stats.okRate * 100)}%`;\n const listed = runs.slice(0, 50);\n const runRows = listed.map((run) => {\n const detail = [\n run.error ? `<details class=\"out error\" open><summary>error</summary><pre>${h(run.error)}</pre></details>` : \"\",\n run.output ? `<details class=\"out\"${run.status === \"ok\" ? \"\" : \" open\"}><summary>output</summary><pre>${h(run.output)}</pre></details>` : \"\",\n ].join(\"\");\n const metrics = Object.entries(run.metrics).map(([k, v]) => `<span><span class=\"k\">${h(k)}</span> ${h(Number.isInteger(v) ? v : v.toFixed(4))}</span>`).join(\"\");\n return `<tr${detail ? ` class=\"has-detail\"` : \"\"}>\n<td class=\"nowrap\">${runState(run)}</td>\n<td class=\"nowrap\">${h(when(run.startedAt, now))} <span class=\"muted\">UTC</span><span class=\"sub\">${stamp(run.startedAt, now)}</span></td>\n<td class=\"nowrap\">${run.durationMs !== null ? h(formatDuration(run.durationMs)) : `<span class=\"muted\">running</span>`}</td>\n<td class=\"hide-sm\">${metrics ? `<span class=\"metrics\">${metrics}</span>` : \"\"}</td>\n<td class=\"hide-sm muted\">${h(run.trigger)}</td>\n</tr>${detail ? `<tr class=\"detail\"><td colspan=\"5\">${detail}</td></tr>` : \"\"}`;\n }).join(\"\\n\");\n\n const silenced = job.silencedUntil !== null && job.silencedUntil > now;\n const path = `${h(base)}/jobs/${encodeURIComponent(job.name)}`;\n const parsed = parsedSchedule(job);\n const why = laneNote(job, missedAt(job, parsed, [], now), now);\n const body = `\n<header class=\"top\">\n ${brand(base, job.name)}\n <div class=\"actions\"><span class=\"meta\">${h(clock(now))} UTC</span></div>\n</header>\n<main>\n<section class=\"sec intro\" aria-label=\"Job\">\n <h2>Job</h2>\n <div>\n <h1 class=\"jobname\">${h(job.name)}</h1>\n ${d.description ? `<p class=\"desc\">${h(d.description)}</p>` : \"\"}\n <p class=\"stateline\">${healthState(job)}${why ? `<span class=\"why\">${h(why)}</span>` : \"\"}</p>\n <div class=\"actions\">\n ${silenced\n ? `<form class=\"inline\" method=\"post\" action=\"${path}/unsilence\"><button type=\"submit\">Unsilence (until ${h(formatRelative(job.silencedUntil!, now))})</button></form>`\n : `<form class=\"inline\" method=\"post\" action=\"${path}/silence\"><select name=\"for\" aria-label=\"Silence for\"><option value=\"1h\">1 hour</option><option value=\"4h\">4 hours</option><option value=\"1d\">1 day</option><option value=\"7d\">1 week</option></select><button type=\"submit\">Silence</button></form>`}\n <details class=\"confirm\"><summary>Forget</summary><form class=\"inline\" method=\"post\" action=\"${path}/forget\"><span>Remove this job and its runs from the store?</span> <button type=\"submit\">Forget</button></form></details>\n </div>\n <dl class=\"figures\">\n <div><dt>Last run</dt><dd>${job.lastRun ? h(formatRelative(job.lastRun.startedAt, now)) : \"never\"}</dd></div>\n <div><dt>Next due</dt><dd>${job.nextExpectedAt !== null ? h(formatRelative(job.nextExpectedAt, now)) : `<small>no schedule</small>`}</dd></div>\n <div><dt>Success, last ${h(job.stats.runs)}</dt><dd>${h(okRate)}</dd></div>\n <div><dt>p50 / p95</dt><dd>${job.stats.p50Ms !== null ? h(formatDuration(job.stats.p50Ms)) : \"?\"} <small>/ ${job.stats.p95Ms !== null ? h(formatDuration(job.stats.p95Ms)) : \"?\"}</small></dd></div>\n </dl>\n </div>\n</section>\n<section class=\"sec\" aria-label=\"Last 7 days\">\n <h2>Last 7 days</h2>\n <p class=\"lede\">A lane per UTC day, today first. Faint ticks mark when the job was due, bars its runs, as long as they took.</p>\n <div class=\"wide\">${weekTimeline(job, runs, complete, now)}</div>\n</section>\n<section class=\"sec\" aria-label=\"Runs\">\n <h2>Runs</h2>\n ${listed.length === 0 ? `<p class=\"lede\">No runs yet.</p>` : `<p class=\"lede\">The newest ${listed.length === 1 ? \"run\" : `${listed.length} runs`}, with any error and output.</p>\n <div class=\"wide\"><table class=\"runs\">\n<thead><tr><th>Status</th><th>Started</th><th>Took</th><th class=\"hide-sm\">Metrics</th><th class=\"hide-sm\">Trigger</th></tr></thead>\n<tbody>${runRows}</tbody></table></div>`}\n</section>\n<section class=\"sec\" aria-label=\"Definition\">\n <h2>Definition</h2>\n <dl class=\"def\">\n <dt>Schedule</dt><dd>${d.schedule ? h(d.schedule) + (d.timezone ? ` <span class=\"muted\">${h(d.timezone)}</span>` : \"\") : `<span class=\"muted\">none</span>`}</dd>\n <dt>Grace</dt><dd>${h(d.grace ?? \"10m\")}</dd>\n <dt>Timeout</dt><dd>${h(d.timeout ?? \"1h\")}</dd>\n ${d.maxDuration ? `<dt>Max duration</dt><dd>${h(d.maxDuration)}</dd>` : \"\"}\n ${d.budget ? `<dt>Budget</dt><dd>${h(Object.entries(d.budget).map(([k, v]) => `${k} ≤ ${v}`).join(\", \"))}</dd>` : \"\"}\n ${d.expect ? `<dt>Expect</dt><dd>${h(d.expect)}</dd>` : \"\"}\n ${d.failuresBeforeAlert && d.failuresBeforeAlert > 1 ? `<dt>Alert after</dt><dd>${h(d.failuresBeforeAlert)} consecutive failures</dd>` : \"\"}\n ${d.tags?.length ? `<dt>Tags</dt><dd>${d.tags.map((t) => h(t)).join(\", \")}</dd>` : \"\"}\n ${job.open.length ? `<dt>Open</dt><dd>${job.open.map((c) => `<span class=\"state ${c === \"failed\" || c === \"stuck\" ? \"bad\" : \"warn\"}\">${h(c.replace(\"_\", \" \"))}</span>`).join(\"\")}</dd>` : \"\"}\n ${job.consecutiveFailures > 0 ? `<dt>Failures in a row</dt><dd>${h(job.consecutiveFailures)}</dd>` : \"\"}\n </dl>\n</section>\n</main>\n<footer><span>Refreshes every minute. Times are UTC.</span><a href=\"${h(base)}/api/jobs/${encodeURIComponent(job.name)}\">JSON</a></footer>`;\n return layout(`${job.name}: CronWatch`, body, base, { refresh: 60 });\n}\n\n/**\n * A page with one message. With `signIn`, a form under it takes the token\n * and sends it as ?token=, which the routes move into the cookie: the way in\n * where there is no address bar to open a link with, such as an app on an\n * iPhone's home screen, which keeps its cookies apart from Safari's.\n */\nexport function messagePage(title: string, message: string, base: string, signIn = false): string {\n const form = signIn ? `<form class=\"signin\" method=\"get\" action=\"${h(base)}/\"><label for=\"token\">Token</label><input id=\"token\" name=\"token\" type=\"password\" autocomplete=\"current-password\" autocapitalize=\"off\" spellcheck=\"false\" required><button class=\"primary\" type=\"submit\">Sign in</button></form>` : \"\";\n return layout(title, `<header class=\"top\">${brand(base)}</header><main class=\"message\"><h1>${h(title)}</h1><p>${h(message)}</p>${form}</main>`, base);\n}\n","import type { CronWatch } from \"../client.js\";\nimport { isDevelopment, readEnv } from \"../env.js\";\nimport { constantTimeEqual, json } from \"../http.js\";\nimport { parseDuration } from \"../duration.js\";\nimport type { Duration, JobSummary, Run } from \"../types.js\";\nimport { dashboardPage, jobPage, messagePage } from \"./html.js\";\nimport { staticAsset, type StaticAsset } from \"./pwa.js\";\nimport { BOARD_BEHIND_MS, BOARD_LANES, BOARD_RUNS, weekRunsLimit, type LaneInput } from \"./timeline.js\";\n\nexport interface RoutesOptions {\n /**\n * Required to reach anything. Send it as `Authorization: Bearer <token>`,\n * or open the dashboard once with `?token=<token>` and a cookie is set.\n * Defaults to process.env.CRONWATCH_TOKEN (on Cloudflare Workers, which\n * have no process, pass env.CRONWATCH_TOKEN); an empty string counts as unset.\n * With no token while NODE_ENV is \"development\" or \"test\", the routes make\n * a random one and print a sign-in link to the server log on their first\n * request; with no token otherwise they answer 503. Pass `null` to opt out\n * and serve them open everywhere, for example behind your own auth.\n *\n * The check endpoint (/api/check) also accepts the client's cronSecret, so\n * a platform cron that sends `Authorization: Bearer <CRON_SECRET>` can\n * trigger checks without knowing the dashboard token.\n */\n token?: string | null;\n /** Where the routes are mounted, so links resolve. Default \"/cronwatch\". */\n basePath?: string;\n /**\n * The public origin the dashboard is served from, such as\n * \"https://app.example.com\", for an app behind a proxy whose request URLs\n * carry an internal host or scheme. Used in place of the request URL's\n * origin for the cross-site check on writes, the sign-in redirect (its\n * cookie is Secure when this is https, and the redirect back after a form\n * follows a Referer on this origin) and the development sign-in line.\n * Takes precedence over trustProxy.\n */\n origin?: string;\n /**\n * Take the public origin from X-Forwarded-Proto and X-Forwarded-Host (the\n * first value of each, falling back to the request URL's scheme or host\n * for whichever is missing) when a request carries either. Only for an app\n * whose proxy sets or overwrites both headers: a client can send them too.\n * Default false, which ignores them.\n */\n trustProxy?: boolean;\n}\n\nexport type FetchHandler = (request: Request) => Promise<Response>;\n\nexport interface Routes {\n handler: FetchHandler;\n GET: FetchHandler;\n POST: FetchHandler;\n DELETE: FetchHandler;\n}\n\nconst COOKIE = \"cronwatch_token\";\n\n/**\n * The cookie holds a digest of the token, so a leaked cookie does not reveal\n * the bearer token itself: the SHA-256 of \"cronwatch-cookie:<token>\", as hex.\n * Web Crypto, so the routes need nothing from node: and run on Workers too.\n */\nasync function cookieValue(token: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(`cronwatch-cookie:${token}`));\n return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nconst DEFAULT_RUNS = 20;\nconst MAX_RUNS = 500;\n/** Runs per job the board reads in one go: the table's sparkline, and most jobs' lanes. */\nconst BOARD_PAGE_RUNS = 20;\n\n/**\n * The board's timeline lanes, the first BOARD_LANES jobs. The runs already\n * read for the table usually cover the last day; only a job whose twenty\n * newest runs all fall inside it (one that runs more often than every hour or so) is\n * read again, deeper, and those reads go out together.\n */\nasync function boardLanes(cw: CronWatch, entries: { job: JobSummary; runs: Run[] }[], now: number): Promise<LaneInput[]> {\n const from = now - BOARD_BEHIND_MS;\n return Promise.all(entries.slice(0, BOARD_LANES).map(async ({ job, runs }) => {\n const short = runs.length >= BOARD_PAGE_RUNS && runs[runs.length - 1]!.startedAt > from;\n if (!short) return { job, runs, complete: true };\n const deeper = await cw.runs(job.name, BOARD_RUNS);\n return { job, runs: deeper, complete: deeper.length < BOARD_RUNS };\n }));\n}\n\n// 'self' only for what the app shell needs: app.js (which registers the\n// service worker and nothing else), the manifest, the worker and the icons.\n// No inline script, and the pages work without any.\nconst CSP = \"default-src 'none'; script-src 'self'; style-src 'unsafe-inline'; img-src 'self' data:; manifest-src 'self'; worker-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'\";\n/** For the SVG icons, should one be opened on its own. */\nconst ASSET_CSP = \"default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'\";\n// same-origin rather than no-referrer: under no-referrer browsers send\n// `Origin: null` on form posts, which the CSRF check would refuse, and the\n// forms redirect back to the page named by the same-origin Referer.\nconst SECURITY_HEADERS = { \"x-content-type-options\": \"nosniff\", \"referrer-policy\": \"same-origin\", \"x-robots-tag\": \"noindex\" };\n\n/**\n * A token for one routes instance in development, when none is configured:\n * 32 random bytes, base64url (43 characters).\n */\nfunction developmentToken(): string {\n const bytes = crypto.getRandomValues(new Uint8Array(32));\n return btoa(String.fromCharCode(...bytes)).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\n/**\n * The line a development token is announced with, printed once with\n * console.info on the routes' first request:\n *\n * [cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: <origin><base>/?token=<token>\n *\n * <origin> is the first request's public origin (scheme, host and any\n * port): the `origin` option when set, the forwarded one under trustProxy,\n * otherwise the request URL's,\n * <base> the base path without a trailing slash (\"\" when mounted at the\n * root), and <token> the token as generated (base64url, so nothing needs\n * escaping).\n */\nfunction developmentSignInLine(origin: string, base: string, token: string): string {\n return `[cronwatch] CRONWATCH_TOKEN is not set, so this development server made a token for the dashboard. Sign in: ${origin}${base}/?token=${token}`;\n}\n\nfunction safeDecode(value: string): string | null {\n try {\n return decodeURIComponent(value);\n } catch {\n return null;\n }\n}\n\nfunction readCookie(request: Request, name: string): string | null {\n const header = request.headers.get(\"cookie\");\n if (!header) return null;\n for (const part of header.split(\";\")) {\n const [k, ...rest] = part.trim().split(\"=\");\n // A malformed escape counts as no cookie.\n if (k === name) return safeDecode(rest.join(\"=\"));\n }\n return null;\n}\n\n/** The first entry of a comma-separated header, trimmed, or null when there is none. */\nfunction firstValue(value: string | null): string | null {\n const first = value?.split(\",\")[0]?.trim();\n return first ? first : null;\n}\n\n/**\n * The origin configured with `origin`, normalised, or null. Throws on a value\n * that is not an http or https origin, so a typo fails at startup.\n */\nfunction configuredOrigin(value: string | undefined): string | null {\n if (value === undefined || value === \"\") return null;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n throw new Error(`routes: origin must be an absolute URL such as \"https://app.example.com\", got ${JSON.stringify(value)}`);\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error(`routes: origin must be http or https, got ${JSON.stringify(value)}`);\n return url.origin;\n}\n\n/**\n * The origin a browser sees for this request, with trustProxy: the forwarded\n * scheme and host when present and well formed, otherwise the request URL's own.\n */\nfunction forwardedOrigin(request: Request, url: URL): string {\n const proto = firstValue(request.headers.get(\"x-forwarded-proto\"))?.toLowerCase() ?? null;\n const host = firstValue(request.headers.get(\"x-forwarded-host\"));\n if (proto === null && host === null) return url.origin;\n if (proto !== null && proto !== \"http\" && proto !== \"https\") return url.origin;\n try {\n const built = new URL(`${proto ?? url.protocol.slice(0, -1)}://${host ?? url.host}`);\n // A \"host\" carrying a path, credentials, a query or a fragment is not a host.\n if (built.pathname !== \"/\" || built.username || built.password || built.search || built.hash) return url.origin;\n return built.origin;\n } catch {\n return url.origin;\n }\n}\n\nfunction stripBase(pathname: string, base: string): string {\n let path = pathname.startsWith(base) ? pathname.slice(base.length) : pathname;\n if (path === \"\") path = \"/\";\n if (path.length > 1 && path.endsWith(\"/\")) path = path.slice(0, -1);\n return path;\n}\n\nasync function readBody(request: Request): Promise<Record<string, string>> {\n const type = request.headers.get(\"content-type\") ?? \"\";\n try {\n if (type.includes(\"application/json\")) {\n const data = await request.json();\n return typeof data === \"object\" && data !== null ? Object.fromEntries(Object.entries(data).map(([k, v]) => [k, String(v)])) : {};\n }\n if (type.includes(\"application/x-www-form-urlencoded\") || type.includes(\"multipart/form-data\")) {\n const form = await request.formData();\n const out: Record<string, string> = {};\n for (const [k, v] of form.entries()) out[k] = String(v);\n return out;\n }\n } catch {\n return {};\n }\n return {};\n}\n\n/**\n * A browser attaches Origin or Sec-Fetch-Site to a cross-site form post, and\n * a page cannot forge either. Non-browser clients send neither.\n */\nfunction crossSite(request: Request, publicOrigin: string): boolean {\n const origin = request.headers.get(\"origin\");\n if (origin !== null && origin !== publicOrigin) return true;\n const site = request.headers.get(\"sec-fetch-site\");\n return site !== null && site !== \"same-origin\" && site !== \"none\";\n}\n\n/** Absent means one hour; a number or numeric string is milliseconds. Throws on anything else. */\nfunction silenceDuration(value: string | null | undefined): Duration {\n if (value === undefined || value === null) return \"1h\";\n const text = value.trim();\n const duration: Duration = /^\\d+(\\.\\d+)?$/.test(text) ? Number(text) : text;\n parseDuration(duration, \"silence duration\");\n return duration;\n}\n\nfunction runsLimit(value: string | null): number {\n const n = value === null || value.trim() === \"\" ? NaN : Math.trunc(Number(value));\n return Number.isFinite(n) ? Math.min(MAX_RUNS, Math.max(1, n)) : DEFAULT_RUNS;\n}\n\n/**\n * A fetch-style handler serving the dashboard and a small JSON API. Mount it\n * in a Next.js app at app/cronwatch/[[...path]]/route.ts:\n *\n * export const { GET, POST, DELETE } = cw.routes();\n */\nexport function createRoutes(cw: CronWatch, options: RoutesOptions = {}): Routes {\n const optedOut = options.token === null;\n const configured = optedOut ? null : (options.token || readEnv(\"CRONWATCH_TOKEN\") || null);\n const base = (options.basePath ?? \"/cronwatch\").replace(/\\/+$/, \"\");\n const developing = isDevelopment();\n const fixedOrigin = configuredOrigin(options.origin);\n const trustProxy = options.trustProxy === true;\n const originOf = (request: Request, url: URL): string =>\n fixedOrigin ?? (trustProxy ? forwardedOrigin(request, url) : url.origin);\n // A fetch handler cannot tell a local caller from a remote one (proxies,\n // tunnels and `next dev` listening on every interface all look alike), so\n // development gets a token too: made here, and shown only in the server log.\n const generated = !configured && !optedOut && developing;\n const token = generated ? developmentToken() : configured;\n let announced = false;\n // Worked out on the first request that needs it, then kept.\n let cookie: Promise<string> | null = null;\n const expectedCookie = (value: string) => (cookie ??= cookieValue(value));\n\n const serve = async (request: Request, url: URL, path: string, wantsHtml: boolean): Promise<Response> => {\n const method = request.method.toUpperCase();\n const publicOrigin = originOf(request, url);\n\n if (generated && !announced) {\n announced = true;\n console.info(developmentSignInLine(publicOrigin, base, token!));\n }\n\n // The app shell: the manifest, icons, service worker, app.js and the\n // offline page. Served to anyone, since a browser fetches some of it\n // without cookies and none of it says anything about the jobs.\n if (method === \"GET\" || method === \"HEAD\") {\n if (path === \"/offline\") {\n return html(messagePage(\"You are offline\", \"CronWatch shows live data from your app, so it needs a connection.\", base), 200, \"no-cache\");\n }\n const asset = staticAsset(path, base);\n if (asset) return shell(asset, base);\n }\n\n // No token outside development: fail closed.\n if (!token && !optedOut) {\n return wantsHtml\n ? html(messagePage(\"CronWatch routes are locked\", \"Set CRONWATCH_TOKEN (or pass token to cw.routes()), or pass token: null to serve them open behind your own auth.\", base), 503)\n : api({ ok: false, error: \"CRONWATCH_TOKEN is not set\" }, 503);\n }\n\n if (method !== \"GET\" && method !== \"HEAD\" && crossSite(request, publicOrigin)) {\n return wantsHtml\n ? html(messagePage(\"Cross-site request refused\", \"Changes can only be made from the dashboard itself.\", base), 403)\n : api({ ok: false, error: \"Cross-site request refused\" }, 403);\n }\n\n const bearer = request.headers.get(\"authorization\")?.replace(/^Bearer\\s+/i, \"\") ?? null;\n if (token) {\n // ?token= is only the sign-in that moves the token into a cookie.\n const query = wantsHtml && method === \"GET\" ? url.searchParams.get(\"token\") : null;\n const sent = readCookie(request, COOKIE);\n const isCheck = path === \"/api/check\";\n const cronSecretOk = isCheck && bearer !== null && cw.cronSecret !== null && constantTimeEqual(bearer, cw.cronSecret);\n const tokenOk =\n bearer !== null ? constantTimeEqual(bearer, token)\n : query !== null ? constantTimeEqual(query, token)\n : sent !== null && constantTimeEqual(sent, await expectedCookie(token));\n if (!cronSecretOk && !tokenOk) {\n if (generated) {\n return wantsHtml\n ? html(messagePage(\"Sign in\", \"CRONWATCH_TOKEN is not set, so this development server made a token. The sign-in link is in the server log: open it once and this browser stays signed in.\", base, true), 401)\n : api({ ok: false, error: \"Unauthorized: CRONWATCH_TOKEN is not set, so this development server made a token; it is in the server log\" }, 401);\n }\n return wantsHtml\n ? html(messagePage(\"Sign in\", `Open this page with ?token=<your CRONWATCH_TOKEN> once and it will stay signed in.`, base, true), 401)\n : api({ ok: false, error: \"Unauthorized\" }, 401);\n }\n if (query !== null) {\n // Move the token from the URL into a cookie so it is not in history or logs.\n url.searchParams.delete(\"token\");\n const secure = publicOrigin.startsWith(\"https:\") ? \"; Secure\" : \"\";\n return redirect(url.pathname + (url.search || \"\"), {\n \"set-cookie\": `${COOKIE}=${await expectedCookie(token)}; Path=${base || \"/\"}; HttpOnly; SameSite=Lax; Max-Age=${60 * 60 * 24 * 30}${secure}`,\n });\n }\n }\n\n const redirectBack = () => {\n const referer = request.headers.get(\"referer\") ?? \"\";\n return redirect(referer.startsWith(publicOrigin + \"/\") ? referer : `${base}/`);\n };\n const decoded = path.split(\"/\").filter(Boolean).map(safeDecode);\n if (decoded.some((part) => part === null)) {\n return wantsHtml ? html(messagePage(\"Bad request\", \"The path is not valid.\", base), 400) : api({ ok: false, error: \"Bad path\" }, 400);\n }\n const parts = decoded as string[];\n\n // HTML\n if (method === \"GET\" && path === \"/\") {\n const entries = await cw.jobsWithRuns(BOARD_PAGE_RUNS);\n const now = cw.now();\n const runsByJob = new Map<string, Run[]>(entries.map((entry) => [entry.job.name, entry.runs]));\n return html(dashboardPage(entries.map((entry) => entry.job), runsByJob, now, base, null, await boardLanes(cw, entries, now)));\n }\n if (method === \"GET\" && parts[0] === \"jobs\" && parts.length === 2) {\n const job = await cw.jobSummary(parts[1]!);\n if (!job) return html(messagePage(\"No such job\", `${parts[1]} is not in the store.`, base), 404);\n const now = cw.now();\n // Enough runs to draw the job's week; the page lists the newest fifty.\n const limit = weekRunsLimit(job, now);\n const runs = await cw.runs(job.name, limit);\n return html(jobPage(job, runs, now, base, runs.length < limit));\n }\n if (method === \"POST\" && path === \"/check\") {\n await cw.check();\n return redirectBack();\n }\n if (method === \"POST\" && parts[0] === \"jobs\" && parts.length === 3) {\n const name = parts[1]!;\n if (parts[2] === \"forget\") {\n await cw.forget(name);\n return redirect(`${base}/`);\n }\n if (parts[2] !== \"silence\" && parts[2] !== \"unsilence\") return html(messagePage(\"Not found\", path, base), 404);\n if (!(await cw.jobSummary(name))) return html(messagePage(\"No such job\", `${name} is not in the store.`, base), 404);\n if (parts[2] === \"silence\") {\n let duration: Duration;\n try {\n duration = silenceDuration((await readBody(request)).for);\n } catch (e) {\n return html(messagePage(\"Not silenced\", (e as Error).message, base), 400);\n }\n await cw.silence(name, duration);\n } else await cw.unsilence(name);\n return redirectBack();\n }\n\n // JSON API\n if (parts[0] === \"api\") {\n const rest = parts.slice(1);\n if (method === \"GET\" && rest[0] === \"jobs\" && rest.length === 1) {\n return api({ ok: true, jobs: await cw.jobs() });\n }\n if (rest[0] === \"jobs\" && rest.length === 2) {\n const name = rest[1]!;\n if (method === \"GET\") {\n const job = await cw.jobSummary(name);\n if (!job) return api({ ok: false, error: \"No such job\" }, 404);\n return api({ ok: true, job, runs: await cw.runs(name, runsLimit(url.searchParams.get(\"runs\"))) });\n }\n if (method === \"DELETE\") {\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n await cw.forget(name);\n return api({ ok: true });\n }\n }\n if (method === \"POST\" && rest[0] === \"jobs\" && rest.length === 3) {\n const name = rest[1]!;\n if (!(await cw.jobSummary(name))) return api({ ok: false, error: \"No such job\" }, 404);\n if (rest[2] === \"silence\") {\n const body = await readBody(request);\n let duration: Duration;\n try {\n duration = silenceDuration(body.for ?? url.searchParams.get(\"for\"));\n } catch (e) {\n return api({ ok: false, error: (e as Error).message }, 400);\n }\n return api({ ok: true, state: await cw.silence(name, duration) });\n }\n if (rest[2] === \"unsilence\") return api({ ok: true, state: await cw.unsilence(name) });\n }\n if (rest[0] === \"check\" && rest.length === 1) {\n // A page cannot send an Authorization header cross-site, so a GET\n // may only run the check when it carries a bearer (token or cron secret).\n if (method === \"GET\" && bearer === null) {\n return api({ ok: false, error: \"Use POST, or GET with an Authorization bearer\" }, 405, { allow: \"POST\" });\n }\n if (method === \"GET\" || method === \"POST\") {\n const result = await cw.check();\n return api({ ok: true, ...result });\n }\n }\n if (method === \"GET\" && rest[0] === \"runs\" && rest.length === 2) {\n const run = await cw.getRun(rest[1]!);\n return run ? api({ ok: true, run }) : api({ ok: false, error: \"No such run\" }, 404);\n }\n return api({ ok: false, error: \"Not found\" }, 404);\n }\n\n return html(messagePage(\"Not found\", path, base), 404);\n };\n\n const handler: FetchHandler = async (request) => {\n let wantsHtml = true;\n try {\n const url = new URL(request.url);\n const path = stripBase(url.pathname, base);\n wantsHtml = !path.startsWith(\"/api\");\n return await serve(request, url, path, wantsHtml);\n } catch (e) {\n try {\n cw.onError(e, \"routes\");\n } catch {\n // An onError that throws must not turn a 500 into an unhandled rejection.\n }\n return wantsHtml\n ? html(messagePage(\"Something went wrong\", \"The request failed and the error was reported.\", base), 500)\n : api({ ok: false, error: \"Internal error\" }, 500);\n }\n };\n\n return { handler, GET: handler, POST: handler, DELETE: handler };\n}\n\nfunction api(body: unknown, status = 200, headers: Record<string, string> = {}): Response {\n return json(body, status, { ...SECURITY_HEADERS, ...headers });\n}\n\nfunction redirect(location: string, headers: Record<string, string> = {}): Response {\n return new Response(null, { status: 303, headers: { location, \"cache-control\": \"no-store\", ...SECURITY_HEADERS, ...headers } });\n}\n\n/**\n * An app shell file. The worker may be scoped to the base (it is served from\n * there anyway); the SVGs get a CSP of their own.\n */\nfunction shell(asset: StaticAsset, base: string): Response {\n const headers: Record<string, string> = { \"content-type\": asset.type, \"cache-control\": asset.cache, ...SECURITY_HEADERS };\n if (asset.type === \"image/svg+xml\") headers[\"content-security-policy\"] = ASSET_CSP;\n if (asset.worker) headers[\"service-worker-allowed\"] = `${base}/`;\n return new Response(asset.body, { status: 200, headers });\n}\n\nfunction html(body: string, status = 200, cache = \"no-store\"): Response {\n return new Response(body, {\n status,\n headers: {\n \"content-type\": \"text/html; charset=utf-8\",\n \"cache-control\": cache,\n \"content-security-policy\": CSP,\n \"x-frame-options\": \"DENY\",\n ...SECURITY_HEADERS,\n },\n });\n}\n","import type { JobState, Run, Store, StoredJob, StoredJobDefinition } from \"../types.js\";\n\n/**\n * Keeps everything in process memory. The default when no store is given,\n * good for tests and for trying the library out. State is gone on restart,\n * so a missed run cannot be noticed across one.\n */\nexport function memory(): Store {\n const jobs = new Map<string, StoredJob>();\n const runs = new Map<string, Run>();\n const order = new Map<string, number>();\n const states = new Map<string, JobState>();\n let seq = 0;\n\n const clone = <T>(v: T): T => JSON.parse(JSON.stringify(v));\n // Code unit order, as the SQL stores sort by bytes rather than by locale.\n const byName = (a: StoredJob, b: StoredJob) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0);\n\n return {\n async upsertJob(definition: StoredJobDefinition, now: number) {\n const existing = jobs.get(definition.name);\n jobs.set(definition.name, {\n name: definition.name,\n definition: clone(definition),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n });\n },\n async getJob(name) {\n const j = jobs.get(name);\n return j ? clone(j) : null;\n },\n async listJobs() {\n return [...jobs.values()].map(clone).sort(byName);\n },\n async deleteJob(name) {\n jobs.delete(name);\n states.delete(name);\n for (const [id, run] of runs) if (run.job === name) { runs.delete(id); order.delete(id); }\n },\n async insertRun(run) {\n // Like SQL's primary key: an id already recorded is refused, never overwritten.\n if (runs.has(run.id)) throw new Error(`run ${run.id} already exists`);\n runs.set(run.id, clone(run));\n order.set(run.id, ++seq);\n },\n async updateRun(run) {\n // Like SQL's UPDATE: a run that is gone (its job was forgotten) stays gone, and only these fields change.\n const existing = runs.get(run.id);\n if (!existing) return;\n const { status, finishedAt, durationMs, error, output, metrics } = clone(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n },\n async updateRunIf(run, fromStatuses) {\n const existing = runs.get(run.id);\n if (!existing || !fromStatuses.includes(existing.status)) return false;\n const { status, finishedAt, durationMs, error, output, metrics } = clone(run);\n runs.set(run.id, { ...existing, status, finishedAt, durationMs, error, output, metrics });\n return true;\n },\n async getRun(id) {\n const r = runs.get(id);\n return r ? clone(r) : null;\n },\n async listRuns(job, limit) {\n return [...runs.values()]\n .filter((r) => r.job === job)\n .sort((a, b) => b.startedAt - a.startedAt || order.get(b.id)! - order.get(a.id)!)\n .slice(0, limit)\n .map(clone);\n },\n async lastRun(job) {\n const list = await this.listRuns(job, 1);\n return list[0] ?? null;\n },\n async runningRuns() {\n return [...runs.values()]\n .filter((r) => r.status === \"running\")\n .sort((a, b) => a.startedAt - b.startedAt || order.get(a.id)! - order.get(b.id)!)\n .map(clone);\n },\n async getState(job) {\n const s = states.get(job);\n return s ? clone(s) : null;\n },\n async setState(state) {\n states.set(state.job, clone(state));\n },\n async compareAndSetState(state, expectedVersion) {\n if ((states.get(state.job)?.version ?? 0) !== expectedVersion) return false;\n states.set(state.job, clone(state));\n return true;\n },\n async prune(before) {\n // Each job's newest run is kept whatever its age: without it, a job\n // that runs less often than the retention looks like it never ran.\n const newest = new Map<string, number>();\n for (const run of runs.values()) newest.set(run.job, Math.max(newest.get(run.job) ?? -Infinity, run.startedAt));\n let n = 0;\n for (const [id, run] of runs) {\n if (run.status !== \"running\" && run.startedAt < before && run.startedAt < newest.get(run.job)!) {\n runs.delete(id);\n order.delete(id);\n n++;\n }\n }\n return n;\n },\n };\n}\n","import { formatDuration, parseDuration } from \"./duration.js\";\nimport { isDevelopment, readEnv } from \"./env.js\";\nimport {\n applySilence,\n BASELINE_WINDOW,\n emptyState,\n hasFullBaseline,\n isSilenced,\n isStuck,\n normalizeState,\n onCheck,\n onRunFinish,\n onRunStart,\n staleAlert,\n summarize,\n timeoutMs,\n unevaluableSummary,\n} from \"./evaluate.js\";\nimport { composeAlert } from \"./format.js\";\nimport { constantTimeEqual, json } from \"./http.js\";\nimport { createRecorder } from \"./job.js\";\nimport type { JobContext } from \"./job.js\";\nimport { capOutput, errorMessage, OUTPUT_CAP, redactSecrets, stripNul } from \"./output.js\";\nimport { parseSchedule } from \"./schedule.js\";\nimport { checkExpectation, toStored } from \"./serialize.js\";\nimport { createRoutes } from \"./routes/index.js\";\nimport type { Routes, RoutesOptions } from \"./routes/index.js\";\nimport { memory } from \"./stores/memory.js\";\nimport type {\n Alert,\n AlertChannel,\n AlertDraft,\n CheckResult,\n Condition,\n Duration,\n JobDefinition,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageFn,\n} from \"./types.js\";\n\nexport type JobFn<T> = (job: JobContext) => Promise<T> | T;\nexport type HandlerFn<T> = (job: JobContext, request: Request) => Promise<T> | T;\n\nexport interface HandlerOptions {\n /**\n * Callers must send `Authorization: Bearer <secret>`. Defaults to the\n * client's cronSecret, which defaults to process.env.CRON_SECRET (what\n * Vercel sends its cron requests with). An empty string counts as unset.\n * With no secret at all the handler answers 503 unless NODE_ENV is\n * \"development\" or \"test\". Pass null to allow anyone.\n */\n secret?: string | null;\n}\n\nexport interface JobHandle {\n readonly name: string;\n readonly definition: JobDefinition;\n /** Run the function now, recording the run. Rethrows whatever the function throws. */\n run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T>;\n /** A fetch-style request handler (Next.js route, Hono, Bun, Deno) that runs the function and records the run. */\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions): (request: Request) => Promise<Response>;\n /**\n * Record a running run now and finish it later, perhaps from another\n * process (see resume()). Store failures go to onError; it never throws for\n * them. A run that is never finished is marked stuck by the first check\n * after the job's timeout.\n */\n start(options?: StartOptions): Promise<RunHandle>;\n /** A handle on a run this job started elsewhere, by its id, so this process can log to it and finish it. */\n resume(runId: string): Promise<RunHandle>;\n}\n\nexport interface StartOptions {\n /** What started the run, as with run(). Default \"start\". */\n trigger?: string;\n /**\n * Your own stable id for the run, such as an Inngest run id, 1 to 200\n * characters, not starting with \"pgcron:\" (the pg_cron source's). A start\n * with an id already recorded for this job records nothing and returns a\n * handle on that run instead; an id recorded for another job throws,\n * whether that job's start is still in flight or long done.\n */\n id?: string;\n}\n\n/**\n * How a started run ended. `{ error }` is a failure, recorded like an error\n * run() caught. Otherwise the run succeeded, and `result` (or a string\n * passed on its own) is treated like the value run()'s function returns:\n * a string is the output when nothing was logged, `expect` is checked, and\n * a Response with status 400 or above is a failure.\n */\nexport type RunOutcome = { status?: \"ok\"; result?: unknown } | { error: unknown };\n\n/** A run recorded by job.start() or found by job.resume(), to finish later. */\nexport interface RunHandle {\n readonly id: string;\n readonly job: string;\n /** When the run started; null when a resumed run could not be read. */\n readonly startedAt: number | null;\n /** False once finished, and from the start for a resumed run that already finished or does not exist. */\n readonly active: boolean;\n /** Add a line of output. Kept in the handle until flush() or finish(). */\n log(...parts: unknown[]): void;\n /** Report a number for this run. A later value for the same name replaces an earlier one. */\n metric(name: string, value: number): void;\n metrics(values: Record<string, number>): void;\n /**\n * Append the lines and metrics added so far to the stored run, which must\n * still be running and belong to this job. A read, change and write of the\n * run's row, written only while it is still running: two processes\n * appending to one run at the same moment can lose one's lines, but a flush\n * never undoes a finish. The first 16 KB of everything flushed stay in the\n * handle, so an expect rule at finish() sees an early line as run() would.\n */\n flush(): Promise<void>;\n /**\n * Finish the run, judge it like any other and send what that produces.\n * Resolves to the run as recorded, or null when nothing was recorded: the\n * run was already finished (here or elsewhere), was not found, or belongs\n * to another job, which is reported to onError. When several processes\n * finish one run, only the one whose write lands judges it. Never throws\n * for the store: a store that fails is reported, nothing is recorded, and\n * the handle stays active so finish() can be called again.\n */\n finish(outcome?: RunOutcome | string): Promise<Run | null>;\n /** finish({ error }). */\n fail(error: unknown): Promise<Run | null>;\n}\n\n/**\n * What a Source may use of the client: declare jobs, read the store, and\n * record runs it found elsewhere. A CronWatch is one.\n */\nexport interface SourceHost {\n /** Declare a job, as CronWatch.job(). Throws for an invalid name or option. */\n job(name: string, options?: JobOptions): unknown;\n /** See CronWatch.recordRun(). */\n recordRun(run: Run, options?: RecordRunOptions): Promise<Alert[]>;\n readonly store: Store;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n}\n\n/**\n * Runs that happen somewhere CronWatch cannot wrap, such as inside the\n * database (see @cronwatch/sdk/pg-cron). check() calls sync() on each source\n * first, so what it records is evaluated in the same check.\n */\nexport interface Source {\n name: string;\n /** Declare the jobs and record their new runs. Returns the alerts recording them sent. */\n sync(host: SourceHost): Promise<Alert[] | void>;\n}\n\nexport interface RecordRunOptions {\n /** False stores the run without evaluating it, for history imported on first sight. Default true. */\n evaluate?: boolean;\n}\n\nexport interface CronWatchOptions {\n /** Where jobs, runs and state live. Defaults to an in-memory store that forgets on restart. */\n store?: Store;\n /**\n * Where runs this process does not wrap come from, such as pg_cron jobs.\n * Each is synced at the start of every check(); one that throws is\n * reported to onError and the check carries on.\n */\n sources?: Source[];\n /** Where alerts go. Defaults to the console. */\n alerts?: AlertChannel[];\n /** Adds a short diagnosis to every alert except recoveries. See @cronwatch/sdk/anthropic. */\n triage?: TriageFn;\n /**\n * Shared secret that handler() requests must carry. Defaults to\n * process.env.CRON_SECRET (on Cloudflare Workers, which have no process,\n * pass env.CRON_SECRET); an empty string counts as unset. Pass null to\n * let handlers run without one.\n */\n cronSecret?: string | null;\n /** How long finished runs are kept. Default \"30d\". */\n retention?: Duration;\n /** Applied to every job unless the job sets its own. */\n defaults?: Pick<JobOptions, \"grace\" | \"timeout\" | \"timezone\" | \"failuresBeforeAlert\">;\n /**\n * Applied to every run's output and error before it is stored, shown or\n * sent to an alert channel or triage. The default blanks values that look\n * like secrets (password=..., Authorization headers, URL credentials, bearer\n * tokens, JWTs, PEM private keys, webhook URLs, AWS, GitHub, Slack, Stripe,\n * Google and API key formats). Pass your own function, or false to keep\n * output exactly as logged. A function that throws or returns something\n * other than a string is reported to onError and the default is used.\n */\n redact?: ((text: string) => string) | false;\n /**\n * \"now\" (the default) sends alerts from this process. \"check\" sends nothing\n * from here: each alert is queued in the store and the next check, in a\n * process that delivers now, sends it (with triage). For a process that\n * records runs but cannot reach the network, such as a sandboxed backup job.\n * Its `alerts` and `triage` are not used.\n */\n deliver?: \"now\" | \"check\";\n /** Called with anything that goes wrong outside a job: the store failing, an alert channel failing, a triage timeout. */\n onError?: (error: unknown, where: string) => void;\n /** The clock. Tests use this. */\n now?: () => number;\n}\n\ninterface ExecuteResult<T> {\n run: Run;\n result: T | undefined;\n error: unknown;\n threw: boolean;\n}\n\nconst NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,119}$/;\nconst TRIAGE_TIMEOUT_MS = 25_000;\n/** How long one channel may take to send one alert. */\nconst CHANNEL_TIMEOUT_MS = 15_000;\nconst PRUNE_INTERVAL_MS = 60 * 60_000;\n/** Undelivered alerts kept per job for retry; the oldest go first. */\nconst MAX_UNDELIVERED = 20;\n/**\n * Wall-clock time one check spends retrying undelivered alerts, across every\n * job. Once it is spent the rest wait for the next check.\n */\nconst RETRY_BUDGET_MS = 20_000;\n/** Reads and writes of one job's state before an update gives up on a store that keeps changing under it. */\nconst STATE_ATTEMPTS = 10;\n/** Runs read for a baseline, and the most read when failures crowd out the successes. */\nconst HISTORY_PAGE = BASELINE_WINDOW + 5;\nconst HISTORY_MAX = 200;\n\n/** Throws a clear error for options that would otherwise quietly turn a check off. */\nfunction validateDefinition(def: JobDefinition): void {\n const name = def.name;\n if (def.schedule !== undefined) {\n if (typeof def.schedule !== \"string\" || def.schedule.trim() === \"\") throw new Error(`job \"${name}\": schedule must be a non-empty string`);\n parseSchedule(def.schedule, def.timezone);\n }\n if (def.timezone !== undefined) {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: def.timezone });\n } catch {\n throw new Error(`job \"${name}\": timezone \"${def.timezone}\" is not an IANA timezone`);\n }\n }\n if (def.grace !== undefined) parseDuration(def.grace, \"grace\");\n if (def.timeout !== undefined && parseDuration(def.timeout, \"timeout\") <= 0) throw new Error(`job \"${name}\": timeout must be longer than zero`);\n if (def.maxDuration !== undefined && parseDuration(def.maxDuration, \"maxDuration\") <= 0) {\n throw new Error(`job \"${name}\": maxDuration must be longer than zero`);\n }\n if (def.failuresBeforeAlert !== undefined && !(Number.isInteger(def.failuresBeforeAlert) && def.failuresBeforeAlert >= 1)) {\n throw new Error(`job \"${name}\": failuresBeforeAlert must be a whole number, 1 or more (got ${String(def.failuresBeforeAlert)})`);\n }\n if (def.budget !== undefined) {\n if (typeof def.budget !== \"object\" || def.budget === null) throw new Error(`job \"${name}\": budget must be an object of { metric: ceiling }`);\n for (const [metric, ceiling] of Object.entries(def.budget)) {\n if (typeof ceiling !== \"number\" || !Number.isFinite(ceiling) || ceiling < 0) {\n throw new Error(`job \"${name}\": budget.${metric} must be a finite number, 0 or more (got ${String(ceiling)})`);\n }\n }\n }\n if (def.expect !== undefined && typeof def.expect !== \"string\" && !(def.expect instanceof RegExp) && typeof def.expect !== \"function\") {\n throw new Error(`job \"${name}\": expect must be a string, a RegExp or a function`);\n }\n}\n\nfunction sameState(a: JobState, b: JobState): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/** Identifies an alert across retries. */\nfunction alertKey(alert: Alert): string {\n return `${alert.type}|${alert.at}|${alert.run?.id ?? \"\"}`;\n}\n\nexport class CronWatch {\n readonly store: Store;\n readonly alerts: AlertChannel[];\n readonly triage: TriageFn | undefined;\n readonly sources: Source[];\n /** The secret handler() requests must carry, or null when none is set. */\n readonly cronSecret: string | null;\n readonly retentionMs: number;\n readonly now: () => number;\n readonly onError: (error: unknown, where: string) => void;\n /** cronSecret was passed as null: handlers may run without a secret. */\n private readonly secretOptOut: boolean;\n private readonly redact: (text: string) => string;\n /** \"check\": queue alerts for another process's check instead of sending them. See CronWatchOptions.deliver. */\n private readonly deferDelivery: boolean;\n private readonly defaults: NonNullable<CronWatchOptions[\"defaults\"]>;\n private readonly definitions = new Map<string, JobDefinition>();\n private readonly synced = new Set<string>();\n /** The tail of each job's queue of state updates. See serial(). */\n private readonly queues = new Map<string, Promise<void>>();\n /** start() calls with an id still in flight, so two at once in this process record one run. */\n private readonly starting = new Map<string, Promise<RunHandle>>();\n private ready: Promise<void> | null = null;\n private checking: Promise<CheckResult> | null = null;\n private lastPruneAt = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private firstTick: ReturnType<typeof setTimeout> | null = null;\n private usingDefaultStore = false;\n private warnedNoSecret = false;\n private warnedDeferredStart = false;\n\n constructor(options: CronWatchOptions = {}) {\n this.store = options.store ?? (this.usingDefaultStore = true, memory());\n this.alerts = options.alerts ?? [consoleChannel()];\n this.triage = options.triage;\n this.sources = options.sources ?? [];\n const secret = options.cronSecret === undefined ? readEnv(\"CRON_SECRET\") : options.cronSecret;\n this.cronSecret = secret ? secret : null;\n this.secretOptOut = options.cronSecret === null;\n this.retentionMs = parseDuration(options.retention ?? \"30d\", \"retention\");\n this.defaults = options.defaults ?? {};\n this.now = options.now ?? (() => Date.now());\n const redact = options.redact;\n this.redact = redact === false ? (text) => text\n : typeof redact === \"function\" ? (text) => {\n try {\n const out: unknown = redact(text);\n if (typeof out !== \"string\") throw new TypeError(`redact must return a string, not ${out === null ? \"null\" : typeof out}`);\n return out;\n } catch (e) {\n // A broken redact must not stop the run finishing, nor leak what it was given.\n this.report(e, \"redact\");\n return redactSecrets(text);\n }\n }\n : redactSecrets;\n if (options.deliver !== undefined && options.deliver !== \"now\" && options.deliver !== \"check\") {\n throw new Error(`deliver must be \"now\" or \"check\", not ${JSON.stringify(options.deliver)}`);\n }\n this.deferDelivery = options.deliver === \"check\";\n this.onError = options.onError ?? ((error, where) => console.error(`[cronwatch] ${where}:`, error));\n }\n\n /** Declare a job. Call it once, at module level, and keep the handle. */\n job(name: string, options: JobOptions = {}): JobHandle {\n if (!NAME_RE.test(name)) {\n throw new Error(`job name \"${name}\" must be 1 to 120 characters of letters, digits, \".\", \"_\", \":\" or \"-\"`);\n }\n const definition: JobDefinition = { ...this.defaults, ...options, name };\n validateDefinition(definition);\n this.definitions.set(name, definition);\n this.synced.delete(name);\n return this.handle(definition);\n }\n\n /** Run a job by name without keeping a handle. Defines it on first use. */\n run<T>(name: string, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, options: JobOptions, fn: JobFn<T>): Promise<T>;\n run<T>(name: string, optionsOrFn: JobOptions | JobFn<T>, maybeFn?: JobFn<T>): Promise<T> {\n const fn = typeof optionsOrFn === \"function\" ? optionsOrFn : maybeFn!;\n const options = typeof optionsOrFn === \"function\" ? undefined : optionsOrFn;\n const handle = options || !this.definitions.has(name) ? this.job(name, options) : this.handle(this.definitions.get(name)!);\n return handle.run(fn);\n }\n\n /** The definitions declared in this process. */\n definedJobs(): JobDefinition[] {\n return [...this.definitions.values()];\n }\n\n /** A handle on a run started elsewhere, as job(name).resume(runId). The job must be declared in this process. */\n resumeRun(name: string, runId: string): Promise<RunHandle> {\n const definition = this.definitions.get(name);\n if (!definition) return Promise.reject(new Error(`resumeRun: job \"${name}\" is not declared; call job() first`));\n return this.resumeHandle(definition, runId);\n }\n\n private handle(definition: JobDefinition): JobHandle {\n const self = this;\n return {\n name: definition.name,\n definition,\n async run<T>(fn: JobFn<T>, options?: { trigger?: string }): Promise<T> {\n const outcome = await self.execute(definition, fn, options?.trigger ?? \"run\");\n if (outcome.threw) throw outcome.error;\n return outcome.result as T;\n },\n handler<T>(fn: HandlerFn<T>, options?: HandlerOptions) {\n const own = options?.secret;\n const secret = own === null ? null : own ? own : self.cronSecret;\n const optedOut = own === null || (!own && self.secretOptOut);\n return async (request: Request): Promise<Response> => {\n if (!secret && !optedOut && !isDevelopment()) {\n self.warnNoSecret();\n return json({ ok: false, error: \"CRON_SECRET is not set, so this job will not run for an unauthenticated request. Set it, or pass secret: null to handler() to allow anyone.\" }, 503);\n }\n if (secret) {\n const header = request.headers.get(\"authorization\") ?? \"\";\n if (!constantTimeEqual(header, `Bearer ${secret}`)) {\n return json({ ok: false, error: \"Unauthorized\" }, 401);\n }\n }\n const outcome = await self.execute(definition, (job) => fn(job, request), \"handler\");\n if (outcome.result instanceof Response) return outcome.result;\n const body = {\n ok: outcome.run.status === \"ok\",\n job: definition.name,\n run: outcome.run.id,\n status: outcome.run.status,\n durationMs: outcome.run.durationMs,\n // Error text only goes to a caller who proved they hold the secret.\n ...(secret && outcome.run.error ? { error: outcome.run.error.split(\"\\n\")[0] } : {}),\n };\n return json(body, outcome.run.status === \"ok\" ? 200 : 500);\n };\n },\n start(options?: StartOptions): Promise<RunHandle> {\n return self.startRun(definition, options ?? {});\n },\n resume(runId: string): Promise<RunHandle> {\n return self.resumeHandle(definition, runId);\n },\n };\n }\n\n private warnNoSecret(): void {\n if (this.warnedNoSecret) return;\n this.warnedNoSecret = true;\n this.onError(new Error(\"handler() refused a request because no CRON_SECRET is set; pass secret: null to allow unauthenticated requests\"), \"handler\");\n }\n\n /** onError, for places that must carry on even when onError itself throws. */\n private report(error: unknown, where: string): void {\n try {\n this.onError(error, where);\n } catch {\n // Nothing more can be done with it.\n }\n }\n\n private async ensureReady(): Promise<void> {\n if (!this.ready) {\n this.ready = (async () => {\n if (this.store.init) await this.store.init();\n if (this.usingDefaultStore && readEnv(\"NODE_ENV\") === \"production\") {\n console.warn(\"[cronwatch] using the in-memory store: runs and state are lost on restart. Pass a store from @cronwatch/sdk/sqlite or @cronwatch/sdk/postgres.\");\n }\n })().catch((error: unknown) => {\n // Let the next call try again rather than failing forever.\n this.ready = null;\n throw error;\n });\n }\n await this.ready;\n }\n\n private async sync(definition: JobDefinition): Promise<void> {\n await this.ensureReady();\n if (this.synced.has(definition.name)) return;\n await this.store.upsertJob(toStored(definition), this.now());\n this.synced.add(definition.name);\n }\n\n /**\n * Runs `fn` after every earlier state update for the same job has settled,\n * so two runs (or a run and a check) in this process never read and write\n * the job's state over each other. Other processes are coordinated by\n * updateState() instead.\n */\n private serial<T>(job: string, fn: () => Promise<T>): Promise<T> {\n const result = (this.queues.get(job) ?? Promise.resolve()).then(fn);\n const tail = result.then(() => {}, () => {});\n this.queues.set(job, tail);\n void tail.then(() => {\n if (this.queues.get(job) === tail) this.queues.delete(job);\n });\n return result;\n }\n\n private async readState(job: string): Promise<JobState> {\n return normalizeState(await this.store.getState(job), job);\n }\n\n /**\n * Every read-modify-write of a job's state goes through here. In turn with\n * this process's other updates to the job (serial()), it reads the state,\n * asks `change` for the next one, and writes it with the version one\n * higher, only if the stored version is still the one read. When another\n * process wrote in between, the write is refused and it starts again from\n * a fresh read, up to STATE_ATTEMPTS times. So `change` may run more than\n * once and must only compute: whatever it returns from the attempt that\n * was written is the result. Nothing is written when the state is\n * unchanged. Returns the state as stored.\n */\n private updateState<T>(\n job: string,\n change: (current: JobState) => { state: JobState; result: T } | Promise<{ state: JobState; result: T }>,\n ): Promise<{ state: JobState; result: T }> {\n return this.serial(job, async () => {\n for (let attempt = 1; ; attempt++) {\n const current = await this.readState(job);\n const { state, result } = await change(current);\n if (sameState(state, current)) return { state: current, result };\n const version = current.version ?? 0;\n const next: JobState = { ...state, version: version + 1 };\n if (await this.writeState(next, version)) return { state: next, result };\n if (attempt >= STATE_ATTEMPTS) {\n throw new Error(`the state of ${job} changed under ${STATE_ATTEMPTS} attempts in a row to update it; gave up`);\n }\n }\n });\n }\n\n /** A conditional write, or for a store without compareAndSetState, a plain one that always succeeds. */\n private async writeState(state: JobState, expectedVersion: number): Promise<boolean> {\n if (typeof this.store.compareAndSetState === \"function\") return this.store.compareAndSetState(state, expectedVersion);\n await this.store.setState(state);\n return true;\n }\n\n /**\n * Runs a function as a recorded run. The function always runs, whatever\n * the store is doing: store errors go to onError, and the result is the\n * function's own outcome. Never throws for the job's own error; see `threw`.\n */\n private async execute<T>(definition: JobDefinition, fn: JobFn<T>, trigger: string): Promise<ExecuteResult<T>> {\n const name = definition.name;\n const startedAt = this.now();\n const run: Run = {\n id: crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt,\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n this.onError(e, `recording ${name}`);\n }\n // Closing missed and stuck happens beside the job, which never waits on it.\n const started = recorded\n ? this.updateState(name, (before) => ({ state: onRunStart(before), result: undefined }))\n .then(() => {}, (e) => this.onError(e, `starting ${name}`))\n : Promise.resolve();\n\n const recorder = createRecorder(run);\n const timer = setTimeout(() => recorder.abort(), timeoutMs(definition));\n if (typeof timer === \"object\" && \"unref\" in timer) timer.unref();\n\n let result: T | undefined;\n let error: unknown;\n let threw = false;\n try {\n result = await fn(recorder.context);\n } catch (e) {\n error = e;\n threw = true;\n } finally {\n clearTimeout(timer);\n }\n\n const finishedAt = this.now();\n run.finishedAt = finishedAt;\n run.durationMs = Math.max(0, finishedAt - startedAt);\n run.metrics = recorder.metrics();\n run.output = recorder.output() ?? (typeof result === \"string\" ? capOutput(result) : null);\n this.conclude(definition, run, result, error, threw, recorder.expectText() ?? (typeof result === \"string\" ? result : null));\n\n await started;\n try {\n const ignored = await this.recordFinish(definition, run, recorded, finishedAt);\n if (ignored) this.report(new Error(`run ${run.id} of ${name} ${ignored}; ignored`), `finishing ${name}`);\n } catch (e) {\n this.onError(e, `recording ${name}`);\n }\n return { run, result, error, threw };\n }\n\n /**\n * Sets a finished run's status and error from how it ended, then redacts\n * its output and error. Shared by execute() and RunHandle.finish().\n */\n private conclude(definition: JobDefinition, run: Run, result: unknown, error: unknown, threw: boolean, expectText: string | null): void {\n if (threw) {\n run.status = \"failed\";\n run.error = errorMessage(error);\n } else if (result instanceof Response && result.status >= 400) {\n run.status = \"failed\";\n run.error = `HTTP ${result.status}${result.statusText ? ` ${result.statusText}` : \"\"}`;\n } else {\n const unmet = checkExpectation(definition.expect, expectText);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n } else {\n run.status = \"ok\";\n }\n }\n // Redacted after the expect check, so a rule can still match what was\n // logged. NULs go last, so not even a custom redact can store one.\n if (run.output !== null) run.output = stripNul(this.redact(run.output));\n if (run.error !== null) run.error = stripNul(this.redact(run.error));\n }\n\n /**\n * Writes a finished run and evaluates it. `recorded` says whether its\n * start was written; if not, it is inserted now. Returns why nothing was\n * recorded (another process finished the run first, say), or null. Throws\n * when the store does, so a handle can be finished again. Shared by\n * execute() and RunHandle.finish().\n */\n private async recordFinish(definition: JobDefinition, run: Run, recorded: boolean, finishedAt: number): Promise<string | null> {\n if (!recorded) {\n // The start was never written; the store may be back by now.\n await this.sync(definition);\n try {\n await this.store.insertRun(run);\n await this.finishRun(toStored(definition), run, finishedAt);\n return null;\n } catch (e) {\n // Another process may have recorded a run with this id meanwhile.\n const stored = await this.store.getRun(run.id).catch(() => null);\n if (!stored) throw e;\n if (stored.job !== run.job) return `belongs to job \"${stored.job}\"`;\n }\n }\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) return claim.ignored;\n if (!claim.lateAfterTimeout || run.status === \"ok\") await this.finishRun(toStored(definition), run, finishedAt);\n return null;\n }\n\n /** A conditional write (Store.updateRunIf), or for a store without one, a read then a plain write. */\n private async writeRunIf(run: Run, fromStatuses: Run[\"status\"][]): Promise<boolean> {\n if (typeof this.store.updateRunIf === \"function\") return this.store.updateRunIf(run, fromStatuses);\n const stored = await this.store.getRun(run.id);\n if (!stored || !fromStatuses.includes(stored.status)) return false;\n await this.store.updateRun(run);\n return true;\n }\n\n /**\n * Writes a finished run over its stored row, only while that row is still\n * running, or else still marked timeout by a check. Only the process whose\n * write lands goes on to evaluate the run; for the others it returns why\n * nothing was written. `lateAfterTimeout` means a check already counted\n * the run as a stuck failure: a late failure must not count twice, while\n * a late success still closes stuck and recovers. Throws when the store does.\n */\n private async claimFinish(run: Run): Promise<{ lateAfterTimeout: boolean } | { ignored: string }> {\n if (await this.writeRunIf(run, [\"running\"])) return { lateAfterTimeout: false };\n if (await this.writeRunIf(run, [\"timeout\"])) return { lateAfterTimeout: true };\n const stored = await this.store.getRun(run.id);\n return { ignored: stored ? `was already finished as ${stored.status}` : \"was not found\" };\n }\n\n /** job.start(): records a running run and returns a handle to finish it. See JobHandle.start. */\n private async startRun(definition: JobDefinition, options: StartOptions): Promise<RunHandle> {\n const id = options.id;\n if (id === undefined) return this.recordStart(definition, options.trigger);\n checkRunId(definition.name, id, \"start\");\n // Keyed by job as well, so another job's start with the same id is not\n // handed this job's run: it fails as it would one call later.\n const key = `${definition.name}\\n${id}`;\n const inFlight = this.starting.get(key);\n if (inFlight) return inFlight;\n const started = this.recordStart(definition, options.trigger, id).finally(() => {\n if (this.starting.get(key) === started) this.starting.delete(key);\n });\n this.starting.set(key, started);\n return started;\n }\n\n /**\n * The start of execute() without the function: the run is inserted and\n * missed and stuck close (onRunStart). A store that fails is reported and\n * the handle inserts the finished run instead, as execute() does.\n */\n private async recordStart(definition: JobDefinition, trigger = \"start\", id?: string): Promise<RunHandle> {\n const name = definition.name;\n if (id !== undefined) {\n let stored: Run | null = null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(id);\n } catch (e) {\n this.onError(e, `recording ${name}`);\n }\n if (stored) return this.existingHandle(definition, stored);\n }\n const run: Run = {\n id: id ?? crypto.randomUUID(),\n job: name,\n status: \"running\",\n startedAt: this.now(),\n finishedAt: null,\n durationMs: null,\n error: null,\n output: null,\n metrics: {},\n trigger,\n };\n let recorded = false;\n try {\n await this.sync(definition);\n await this.store.insertRun({ ...run });\n recorded = true;\n } catch (e) {\n // Another process may have started a run with this id first.\n const stored = id === undefined ? null : await this.store.getRun(id).catch(() => null);\n if (stored) return this.existingHandle(definition, stored);\n this.onError(e, `recording ${name}`);\n }\n if (recorded) {\n await this.updateState(name, (before) => ({ state: onRunStart(before), result: undefined }))\n .catch((e: unknown) => this.onError(e, `starting ${name}`));\n }\n return this.runHandle(definition, run.id, run, recorded, null);\n }\n\n /** job.resume() and cw.resumeRun(). A store that cannot be read is reported, and finish() reads it again. */\n private async resumeHandle(definition: JobDefinition, runId: string): Promise<RunHandle> {\n checkRunId(definition.name, runId, \"resume\");\n let stored: Run | null;\n try {\n await this.ensureReady();\n stored = await this.store.getRun(runId);\n } catch (e) {\n this.onError(e, `resuming ${definition.name}`);\n return this.runHandle(definition, runId, null, true, null);\n }\n if (!stored) return this.runHandle(definition, runId, null, true, \"was not found\");\n return this.existingHandle(definition, stored);\n }\n\n /** A handle on a stored run. One still running, or marked timeout by a check, can be finished. */\n private existingHandle(definition: JobDefinition, stored: Run): RunHandle {\n if (stored.job !== definition.name) {\n throw new Error(`run \"${stored.id}\" belongs to job \"${stored.job}\", not \"${definition.name}\"`);\n }\n const finished = stored.status === \"ok\" || stored.status === \"failed\";\n return this.runHandle(definition, stored.id, stored, true, finished ? `already finished as ${stored.status}` : null);\n }\n\n /**\n * The handle itself. `base` is the run as last known here, `recorded`\n * whether its start is in the store, and `inactive` why finish() has\n * nothing to do, or null. Lines and metrics wait in the handle until\n * flush() or finish() merges them onto a fresh read of the stored run.\n */\n private runHandle(definition: JobDefinition, id: string, base: Run | null, recorded: boolean, inactive: string | null): RunHandle {\n const self = this;\n const name = definition.name;\n const fresh = () => createRecorder({ id, job: name, startedAt: base?.startedAt ?? 0 } as Run);\n let recorder = fresh();\n let finished = inactive !== null;\n let finishCalled = false;\n /**\n * The first OUTPUT_CAP characters of every line flushed from this\n * handle, unredacted, or null before the first flush. The stored output\n * keeps only the tail, so without it an expect rule at finish() would\n * miss a line logged early, which run() would have seen.\n */\n let head: string | null = null;\n let queue: Promise<unknown> = Promise.resolve();\n const inTurn = <T>(fn: () => Promise<T>): Promise<T> => {\n const result = queue.then(fn);\n queue = result.catch(() => {});\n return result;\n };\n const ignored = (why: string) => self.report(new Error(`run ${id} of ${name} ${why}; ignored`), `finishing ${name}`);\n\n const finish = (outcome?: RunOutcome | string): Promise<Run | null> => {\n if (finishCalled) {\n ignored(\"was already finished by this handle\");\n return Promise.resolve(null);\n }\n finishCalled = true;\n const wasInactive = finished;\n finished = true;\n // The store failed part way and nothing was recorded, so the handle can be finished again.\n const retryable = (error: unknown): null => {\n finishCalled = false;\n finished = false;\n self.report(error, `finishing ${name}`);\n return null;\n };\n return inTurn(async () => {\n if (wasInactive) {\n ignored(inactive!);\n return null;\n }\n let from = base;\n if (recorded) {\n try {\n from = (await self.store.getRun(id)) ?? base;\n } catch (e) {\n return retryable(e);\n }\n }\n if (!from) {\n ignored(\"was not found\");\n return null;\n }\n if (from.job !== name) {\n ignored(`belongs to job \"${from.job}\"`);\n return null;\n }\n if (from.status === \"ok\" || from.status === \"failed\") {\n ignored(`was already finished as ${from.status}`);\n return null;\n }\n const failed = typeof outcome === \"object\" && outcome !== null && \"error\" in outcome;\n const result = typeof outcome === \"string\" ? outcome : failed ? undefined : outcome?.result;\n const error = failed ? (outcome as { error: unknown }).error : undefined;\n const finishedAt = self.now();\n const added = recorder.output() ?? (typeof result === \"string\" ? capOutput(result) : null);\n const run: Run = {\n ...from,\n status: \"running\",\n finishedAt,\n durationMs: Math.max(0, finishedAt - from.startedAt),\n error: null,\n output: joinOutput(from.output, added),\n metrics: { ...from.metrics, ...recorder.metrics() },\n };\n const expectText = joinLines(head, joinLines(from.output, recorder.expectText() ?? (typeof result === \"string\" ? result : null)));\n self.conclude(definition, run, result, error, failed, expectText);\n let why: string | null;\n try {\n why = await self.recordFinish(definition, run, recorded, finishedAt);\n } catch (e) {\n return retryable(e);\n }\n if (why) {\n ignored(why);\n return null;\n }\n return run;\n });\n };\n\n return {\n id,\n job: name,\n startedAt: base?.startedAt ?? null,\n get active() {\n return !finished;\n },\n log: (...parts: unknown[]) => recorder.context.log(...parts),\n metric: (metric: string, value: number) => recorder.context.metric(metric, value),\n metrics: (values: Record<string, number>) => recorder.context.metrics(values),\n flush: () => inTurn(async () => {\n if (finished || !recorded) return;\n const lines = recorder.output();\n const metrics = recorder.metrics();\n if (lines === null && Object.keys(metrics).length === 0) return;\n // Lines logged while this waits on the store go to a new recorder.\n const taken = recorder;\n recorder = fresh();\n const putBack = () => {\n const later = recorder;\n recorder = fresh();\n for (const text of [taken.expectText(), later.expectText()]) if (text !== null) recorder.context.log(text);\n recorder.context.metrics({ ...taken.metrics(), ...later.metrics() });\n };\n try {\n const stored = await self.store.getRun(id);\n // Not running: the lines stay here for finish(), which reports why it cannot record them.\n if (!stored || stored.status !== \"running\") return putBack();\n if (stored.job !== name) {\n putBack();\n self.report(new Error(`run ${id} of ${name} belongs to job \"${stored.job}\"; ignored`), `flushing ${name}`);\n return;\n }\n const output = lines === null ? stored.output : joinOutput(stored.output, stripNul(self.redact(lines)));\n // Only over a row still running, so a flush never undoes a finish written meanwhile.\n if (!(await self.writeRunIf({ ...stored, output, metrics: { ...stored.metrics, ...metrics } }, [\"running\"]))) return putBack();\n const text = taken.expectText();\n if (text !== null && (head === null || head.length < OUTPUT_CAP)) head = (joinLines(head, text) ?? \"\").slice(0, OUTPUT_CAP);\n } catch (e) {\n putBack();\n self.report(e, `flushing ${name}`);\n }\n }),\n finish,\n fail: (error: unknown) => finish({ error }),\n };\n }\n\n /**\n * Record a run that happened outside this process, for a Source. Its job\n * must be declared with job() first. Runs are keyed by id: a new one is\n * inserted, a stored one still running (or marked timeout by a check) is\n * finished when this one is not running, and anything else is left alone,\n * so recording the same run twice changes nothing. Finishing is\n * conditional (see Store.updateRunIf): when two processes record the same\n * finish, only the one whose write lands evaluates it, and the other\n * reports it as already finished. A stored run of another job is left\n * alone and reported. A finished run is judged as if it had been wrapped\n * here (expect, failures, duration, budgets) and its output and error are\n * redacted the same way; one finishing after a check marked it timeout is\n * judged only when it succeeded, as RunHandle.finish() does. Returns the\n * alerts it sent.\n */\n async recordRun(input: Run, options: RecordRunOptions = {}): Promise<Alert[]> {\n const declared = this.definitions.get(input.job);\n if (!declared) throw new Error(`recordRun: job \"${input.job}\" is not declared; call job() first`);\n await this.sync(declared);\n const run: Run = { ...input, metrics: { ...input.metrics } };\n if (run.status === \"ok\") {\n const unmet = checkExpectation(declared.expect, run.output);\n if (unmet) {\n run.status = \"failed\";\n run.error = unmet;\n }\n }\n if (run.output !== null) run.output = stripNul(this.redact(capOutput(run.output)));\n if (run.error !== null) run.error = stripNul(this.redact(capOutput(run.error)));\n const evaluate = options.evaluate !== false;\n const definition = toStored(declared);\n\n const stored = await this.store.getRun(run.id);\n if (stored) return this.recordOver(definition, stored, run, evaluate);\n try {\n await this.store.insertRun(run);\n } catch (e) {\n // Another process recorded it first.\n const again = await this.store.getRun(run.id).catch(() => null);\n if (again) return this.recordOver(definition, again, run, evaluate);\n throw e;\n }\n if (!evaluate) return [];\n await this.updateState(run.job, (before) => ({ state: onRunStart(before), result: undefined }));\n if (run.status === \"running\") return [];\n return this.finishRun(definition, run, this.now());\n }\n\n /** recordRun() for a run already stored. */\n private async recordOver(definition: StoredJobDefinition, stored: Run, run: Run, evaluate: boolean): Promise<Alert[]> {\n if (stored.job !== run.job) {\n this.report(new Error(`run ${run.id} of ${run.job} belongs to job \"${stored.job}\"; ignored`), `recording ${run.job}`);\n return [];\n }\n if ((stored.status !== \"running\" && stored.status !== \"timeout\") || run.status === \"running\") return [];\n const claim = await this.claimFinish(run);\n if (\"ignored\" in claim) {\n this.report(new Error(`run ${run.id} of ${run.job} ${claim.ignored}; ignored`), `recording ${run.job}`);\n return [];\n }\n if (!evaluate || (claim.lateAfterTimeout && run.status !== \"ok\")) return [];\n return this.finishRun(definition, run, this.now());\n }\n\n /**\n * Evaluate a finished run (ok, failed, or timed out by a check), already\n * written, against the job's state and send what that produces. Never throws.\n */\n private async finishRun(definition: StoredJobDefinition, run: Run, now: number): Promise<Alert[]> {\n let drafts: AlertDraft[];\n try {\n let history: Run[] | null = null;\n ({ result: drafts } = await this.updateState(run.job, async (previous) => {\n history ??= await this.history(run);\n const settled = applySilence(previous, onRunFinish(definition, run, previous, history, now), now);\n return { state: settled.state, result: settled.alerts };\n }));\n } catch (e) {\n this.onError(e, `evaluating ${run.job}`);\n return [];\n }\n return this.dispatch(drafts, definition, now);\n }\n\n /**\n * The runs before `run`, newest first, with up to BASELINE_WINDOW\n * successful ones when the store has them. One small read normally; a\n * larger one only when failures crowd the successes out of it.\n */\n private async history(run: Run): Promise<Run[]> {\n let runs = await this.store.listRuns(run.job, HISTORY_PAGE);\n if (runs.length === HISTORY_PAGE && !hasFullBaseline(runs.filter((r) => r.id !== run.id))) {\n runs = await this.store.listRuns(run.job, HISTORY_MAX);\n }\n return runs.filter((r) => r.id !== run.id);\n }\n\n /**\n * Look for missed and stuck runs across every job, send alerts, retry\n * alerts no channel accepted, and prune old runs. Call it from an interval\n * (start()), a cron hitting the mounted routes, or by hand. Concurrent\n * calls share one check.\n */\n check(): Promise<CheckResult> {\n if (!this.checking) {\n this.checking = this.runCheck().finally(() => {\n this.checking = null;\n });\n }\n return this.checking;\n }\n\n private async runCheck(): Promise<CheckResult> {\n await this.ensureReady();\n const alerts: Alert[] = [];\n for (const source of this.sources) {\n try {\n alerts.push(...((await source.sync(this)) ?? []));\n } catch (e) {\n this.onError(e, `source ${source.name}`);\n }\n }\n for (const definition of this.definitions.values()) await this.sync(definition);\n const now = this.now();\n\n // Runs that never reported back. One that cannot be judged (its job's\n // stored timeout no longer parses, say) is reported and skipped.\n for (const run of await this.store.runningRuns()) {\n try {\n const declared = this.definitions.get(run.job);\n const definition = declared ? toStored(declared) : (await this.store.getJob(run.job))?.definition;\n if (!definition || !isStuck(definition, run, now)) continue;\n const timeout = timeoutMs(definition);\n run.status = \"timeout\";\n run.finishedAt = now;\n run.durationMs = now - run.startedAt;\n run.error = `Still running after ${formatDuration(timeout)}; marked as timed out`;\n // Only over a row still running: a finish that landed meanwhile wins.\n if (!(await this.writeRunIf(run, [\"running\"]))) continue;\n alerts.push(...(await this.finishRun(definition, run, now)));\n } catch (e) {\n this.onError(e, `checking ${run.job}`);\n }\n }\n\n // Each job on its own: one that cannot be evaluated is reported, shown\n // as failing (see unevaluableSummary) and does not stop the others.\n const jobs: JobSummary[] = [];\n const retries = { spentMs: 0 };\n for (const stored of await this.store.listJobs()) {\n try {\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW);\n let nextExpectedAt: number | null = null;\n const { state, result: drafts } = await this.updateState(stored.name, (previous) => {\n const evaluation = onCheck(stored.definition, stored, recent[0] ?? null, previous, now);\n nextExpectedAt = evaluation.nextExpectedAt;\n const settled = applySilence(previous, evaluation, now);\n return { state: settled.state, result: settled.alerts };\n });\n alerts.push(...(await this.retryUndelivered(stored.name, state, now, retries)));\n alerts.push(...(await this.dispatch(drafts, stored.definition, now)));\n jobs.push(summarize(stored, recent, state, nextExpectedAt, now));\n } catch (e) {\n this.onError(e, `checking ${stored.name}`);\n jobs.push(await this.unevaluable(stored, now));\n }\n }\n\n let pruned = 0;\n if (now - this.lastPruneAt > PRUNE_INTERVAL_MS) {\n this.lastPruneAt = now;\n try {\n pruned = await this.store.prune(now - this.retentionMs);\n } catch (e) {\n this.onError(e, \"pruning\");\n }\n }\n\n return { checkedAt: now, jobs, alerts, pruned };\n }\n\n /** A job's summary and its newest runs, without alerting. A job that cannot be evaluated is reported and shown as failing. */\n private async snapshot(stored: StoredJob, now: number, runs: number): Promise<{ job: JobSummary; runs: Run[] }> {\n let recent: Run[] = [];\n try {\n recent = await this.store.listRuns(stored.name, Math.max(runs, BASELINE_WINDOW));\n const state = await this.readState(stored.name);\n const { nextExpectedAt } = onCheck(stored.definition, stored, recent[0] ?? null, state, now);\n return { job: summarize(stored, recent, state, nextExpectedAt, now), runs: recent.slice(0, runs) };\n } catch (e) {\n this.onError(e, `reading ${stored.name}`);\n return { job: await this.unevaluable(stored, now), runs: recent.slice(0, runs) };\n }\n }\n\n /** The summary of a job whose evaluation failed, from whatever can still be read. */\n private async unevaluable(stored: StoredJob, now: number): Promise<JobSummary> {\n const recent = await this.store.listRuns(stored.name, BASELINE_WINDOW).catch((): Run[] => []);\n const state = await this.readState(stored.name).catch(() => emptyState(stored.name));\n return unevaluableSummary(stored, recent, state, now);\n }\n\n /** Every job the store knows about, with its health. Does not send alerts. */\n async jobs(): Promise<JobSummary[]> {\n return (await this.jobsWithRuns(0)).map((entry) => entry.job);\n }\n\n /** Every job's summary with its newest `limit` runs, read together. What the dashboard shows. */\n async jobsWithRuns(limit = 20): Promise<{ job: JobSummary; runs: Run[] }[]> {\n await this.ensureReady();\n for (const definition of this.definitions.values()) await this.sync(definition);\n const now = this.now();\n const out: { job: JobSummary; runs: Run[] }[] = [];\n for (const stored of await this.store.listJobs()) out.push(await this.snapshot(stored, now, clampLimit(limit, 20, 0)));\n return out;\n }\n\n async jobSummary(name: string): Promise<JobSummary | null> {\n await this.ensureReady();\n const definition = this.definitions.get(name);\n if (definition) await this.sync(definition);\n const stored = await this.store.getJob(name);\n if (!stored) return null;\n return (await this.snapshot(stored, this.now(), 0)).job;\n }\n\n /** A job's runs, newest first. `limit` is a whole number from 1 to 500. */\n async runs(name: string, limit = 50): Promise<Run[]> {\n await this.ensureReady();\n return this.store.listRuns(name, clampLimit(limit, 50, 1));\n }\n\n async getRun(id: string): Promise<Run | null> {\n await this.ensureReady();\n return this.store.getRun(id);\n }\n\n /** Stop alerts for a job for a while. State keeps updating underneath. */\n async silence(name: string, duration: Duration): Promise<JobState> {\n const ms = parseDuration(duration, \"silence duration\");\n return this.patchState(name, (state) => { state.silencedUntil = this.now() + ms; });\n }\n\n async unsilence(name: string): Promise<JobState> {\n return this.patchState(name, (state) => { state.silencedUntil = null; });\n }\n\n /** Read, change and write one job's state, in turn with every other update to it. */\n private async patchState(name: string, change: (state: JobState) => void): Promise<JobState> {\n await this.ensureReady();\n const { state } = await this.updateState(name, (current) => {\n const next = normalizeState(current, name);\n change(next);\n return { state: next, result: undefined };\n });\n return state;\n }\n\n /** Remove a job and its runs from the store. A job still declared in code comes back on its next run. */\n async forget(name: string): Promise<void> {\n await this.ensureReady();\n this.definitions.delete(name);\n this.synced.delete(name);\n await this.store.deleteJob(name);\n }\n\n /** The dashboard and JSON API as fetch-style handlers. See createRoutes(). */\n routes(options?: RoutesOptions): Routes {\n return createRoutes(this, options);\n }\n\n /**\n * Check on an interval, for long-running servers. Default every minute.\n * Not for serverless functions or Cloudflare Workers, where nothing runs\n * between requests: call check() from a cron there instead.\n */\n start(every: Duration = \"1m\"): void {\n if (this.timer) return;\n const ms = Math.max(5_000, parseDuration(every, \"check interval\"));\n if (this.deferDelivery && !this.warnedDeferredStart) {\n this.warnedDeferredStart = true;\n console.warn('[cronwatch] start() was called with deliver: \"check\", so these checks send no alerts. Another process must run checks with deliver: \"now\" (the default) to send them.');\n }\n const tick = () => this.check().catch((e) => this.onError(e, \"check\"));\n this.timer = setInterval(tick, ms);\n if (typeof this.timer === \"object\" && \"unref\" in this.timer) this.timer.unref();\n this.firstTick = setTimeout(() => {\n this.firstTick = null;\n void tick();\n }, 1_000);\n if (typeof this.firstTick === \"object\" && \"unref\" in this.firstTick) this.firstTick.unref();\n }\n\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n if (this.firstTick) clearTimeout(this.firstTick);\n this.timer = null;\n this.firstTick = null;\n }\n\n async close(): Promise<void> {\n this.stop();\n if (this.store.close) await this.store.close();\n }\n\n /**\n * Compose, triage and send each draft. The state was saved before this\n * (updateState), so a slow channel holds up nothing else; afterwards only\n * the delivery fields are written back, onto a fresh read of the state.\n */\n private async dispatch(drafts: AlertDraft[], definition: StoredJobDefinition, now: number): Promise<Alert[]> {\n if (drafts.length === 0) return [];\n const composed: Alert[] = [];\n const delivered: Alert[] = [];\n const failed: Alert[] = [];\n for (const draft of drafts) {\n const alert = composeAlert(draft, definition, now);\n if (this.deferDelivery) {\n failed.push(alert);\n } else {\n if (this.triage && alert.type !== \"recovered\") await this.addTriage(alert, TRIAGE_TIMEOUT_MS);\n (await this.deliver(alert) ? delivered : failed).push(alert);\n }\n composed.push(alert);\n }\n await this.recordDelivery(definition.name, delivered, failed, [], now);\n return composed;\n }\n\n /**\n * Send the alerts that no channel accepted last time, once each, oldest\n * first. `state` is the job's state as this check left it: an alert that\n * no longer describes it (staleAlert) is dropped instead. Retries across a\n * check share RETRY_BUDGET_MS of wall-clock time; once it is spent the rest\n * stay queued for the next check.\n */\n private async retryUndelivered(name: string, state: JobState, now: number, budget: { spentMs: number }): Promise<Alert[]> {\n const pending = state.undelivered ?? [];\n if (pending.length === 0 || isSilenced(state, now) || this.deferDelivery) return [];\n const delivered: Alert[] = [];\n const failed: Alert[] = [];\n const dropped = pending.filter((alert) => staleAlert(alert, state));\n for (const alert of pending) {\n if (dropped.includes(alert)) continue;\n const left = RETRY_BUDGET_MS - budget.spentMs;\n if (left <= 0) break;\n const started = Date.now();\n // An alert queued by a process that delivers at check time was never\n // triaged. One that was tried (triage: null) is not tried again.\n if (this.triage && alert.type !== \"recovered\" && alert.triage === undefined) await this.addTriage(alert, Math.min(TRIAGE_TIMEOUT_MS, left));\n (await this.deliver(alert) ? delivered : failed).push(alert);\n budget.spentMs += Math.max(0, Date.now() - started);\n }\n await this.recordDelivery(name, delivered, failed, dropped, now);\n return delivered;\n }\n\n /**\n * Mark delivered alerts done, drop stale ones, and keep failed ones for the\n * next check. A failed alert replaces its stored copy, so a triage made on\n * this attempt is kept. lastAlertAt moves only on a delivery.\n */\n private async recordDelivery(name: string, delivered: Alert[], failed: Alert[], dropped: Alert[], now: number): Promise<void> {\n try {\n const { result: trimmed } = await this.updateState(name, (previous) => {\n const state = normalizeState(previous, name);\n const done = new Set([...delivered, ...dropped].map(alertKey));\n const retried = new Map(failed.map((a) => [alertKey(a), a]));\n const kept = state.undelivered!.filter((a) => !done.has(alertKey(a))).map((a) => retried.get(alertKey(a)) ?? a);\n const known = new Set(kept.map(alertKey));\n kept.push(...failed.filter((a) => !known.has(alertKey(a))));\n state.undelivered = kept.slice(-MAX_UNDELIVERED);\n if (delivered.length > 0) state.lastAlertAt = now;\n return { state, result: Math.max(0, kept.length - MAX_UNDELIVERED) };\n });\n if (trimmed > 0) {\n this.onError(\n new Error(`${trimmed} undelivered alert${trimmed === 1 ? \"\" : \"s\"} for ${name} dropped: only the newest ${MAX_UNDELIVERED} are kept for retry`),\n `alert queue for ${name}`,\n );\n }\n } catch (e) {\n this.onError(e, `recording alert delivery for ${name}`);\n }\n }\n\n /** Send to every channel at once. True when at least one accepted it, or there are none. */\n private async deliver(alert: Alert): Promise<boolean> {\n if (this.alerts.length === 0) return true;\n const results = await Promise.all(\n this.alerts.map(async (channel) => {\n try {\n await withTimeout(channel.send(alert, { onError: (e) => this.report(e, `alert channel ${channel.name}`) }), CHANNEL_TIMEOUT_MS);\n return true;\n } catch (e) {\n this.onError(e, `alert channel ${channel.name}`);\n return false;\n }\n }),\n );\n return results.includes(true);\n }\n\n /** Sets alert.triage to the diagnosis, or to null when there is none, so it is tried once per alert. */\n private async addTriage(alert: Alert, timeout: number): Promise<void> {\n const controller = new AbortController();\n try {\n const recentRuns = await this.store.listRuns(alert.job, 5);\n const diagnosis = await withTimeout(this.triage!({ alert, recentRuns, signal: controller.signal }), timeout);\n alert.triage = typeof diagnosis === \"string\" && diagnosis !== \"\" ? diagnosis : null;\n } catch (e) {\n controller.abort();\n alert.triage = null;\n this.onError(e, `triage for ${alert.job}`);\n }\n }\n}\n\n/** Run ids that start with this belong to the pg_cron source (see @cronwatch/sdk/pg-cron). */\nexport const RESERVED_RUN_ID_PREFIX = \"pgcron:\";\n\n/** Throws for a run id no store could hold, or one reserved for the pg_cron source. */\nfunction checkRunId(job: string, id: unknown, method: string): void {\n if (typeof id !== \"string\" || id.length === 0 || id.length > 200) {\n throw new Error(`job \"${job}\": ${method}() needs a run id of 1 to 200 characters (got ${typeof id === \"string\" ? `${id.length} characters` : typeof id})`);\n }\n if (id.startsWith(RESERVED_RUN_ID_PREFIX)) {\n throw new Error(`job \"${job}\": ${method}() cannot take a run id starting with \"${RESERVED_RUN_ID_PREFIX}\", which the pg_cron source uses for its runs`);\n }\n}\n\n/** Two stretches of text as one, a line apart; either may be null. */\nfunction joinLines(before: string | null, after: string | null): string | null {\n if (before === null || before === \"\") return after;\n if (after === null) return before;\n return `${before}\\n${after}`;\n}\n\n/** Output appended to stored output, capped like any run's. */\nfunction joinOutput(before: string | null, after: string | null): string | null {\n const joined = joinLines(before, after);\n return joined === null ? null : capOutput(joined);\n}\n\n/** A whole number in range, or the fallback for anything that is not a number. */\nfunction clampLimit(limit: number, fallback: number, min: number): number {\n const n = typeof limit === \"number\" && Number.isFinite(limit) ? Math.trunc(limit) : fallback;\n return Math.min(500, Math.max(min, n));\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const t = setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms);\n if (typeof t === \"object\" && \"unref\" in t) t.unref();\n promise.then((v) => { clearTimeout(t); resolve(v); }, (e) => { clearTimeout(t); reject(e); });\n });\n}\n\n/** Writes alerts to the console. The default channel. */\nexport function consoleChannel(): AlertChannel {\n return {\n name: \"console\",\n async send(alert) {\n const line = `[cronwatch] ${alert.title}\\n${alert.message}${alert.triage ? `\\nTriage: ${alert.triage}` : \"\"}`;\n if (alert.type === \"recovered\") console.info(line);\n else console.error(line);\n },\n };\n}\n\n/** Wrap any function as an alert channel. */\nexport function custom(name: string, send: (alert: Alert) => Promise<void> | void): AlertChannel {\n return { name, send: async (alert) => { await send(alert); } };\n}\n\nexport type { Condition };\n","import { CronWatch } from \"./client.js\";\nimport type { CronWatchOptions } from \"./client.js\";\n\n/**\n * Create a CronWatch client. One per app, at module level:\n *\n * export const cw = cronwatch({ store: sqlite({ path: \"./data/cronwatch.db\" }), alerts: [slack({ webhookUrl })] });\n * export const nightly = cw.job(\"nightly-report\", { schedule: \"0 2 * * *\", grace: \"15m\" });\n */\nexport function cronwatch(options: CronWatchOptions = {}): CronWatch {\n return new CronWatch(options);\n}\n\nexport { CronWatch, consoleChannel, custom } from \"./client.js\";\nexport type { CronWatchOptions, HandlerFn, HandlerOptions, JobFn, JobHandle, RecordRunOptions, RunHandle, RunOutcome, Source, SourceHost, StartOptions } from \"./client.js\";\nexport type { JobContext } from \"./job.js\";\nexport { memory } from \"./stores/memory.js\";\nexport { createRoutes } from \"./routes/index.js\";\nexport type { FetchHandler, Routes, RoutesOptions } from \"./routes/index.js\";\nexport { parseDuration, formatDuration } from \"./duration.js\";\nexport { parseSchedule, nextFire } from \"./schedule.js\";\nexport type { ParsedSchedule } from \"./schedule.js\";\nexport { composeAlert } from \"./format.js\";\nexport type {\n Alert,\n AlertChannel,\n AlertDetails,\n AlertDraft,\n AlertType,\n BudgetBreach,\n ChannelContext,\n CheckResult,\n Condition,\n Duration,\n ExpectRule,\n JobDefinition,\n JobHealth,\n JobOptions,\n JobState,\n JobSummary,\n Run,\n RunStatus,\n Store,\n StoredJob,\n StoredJobDefinition,\n TriageContext,\n TriageFn,\n} from \"./types.js\";\n"]}