feat: add persistent cron-based recurring reminders
Replace in-memory-only setTimeout scheduling with a DB-backed system that survives broker restarts. Adds: - `scheduled_message` table in mesh schema (Drizzle + raw CREATE TABLE for zero-downtime deploys) - Minimal 5-field cron parser (no dependencies) with next-fire-time calculation for recurring entries - On broker boot, all non-cancelled entries are loaded from PostgreSQL and timers re-armed automatically - CLI `schedule_reminder` MCP tool accepts optional `cron` expression - CLI `remind` command accepts `--cron` flag - One-shot reminders remain backward compatible — no cron field = same behavior as before Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -568,13 +568,14 @@ export const TOOLS: Tool[] = [
|
||||
{
|
||||
name: "schedule_reminder",
|
||||
description:
|
||||
"Schedule a message for future delivery. Without `to`, it fires back to yourself (a self-reminder). With `to`, it delivers to a peer, @group, or * broadcast. The broker holds it and delivers when the time arrives. Receivers see `subtype: reminder` in the push envelope.",
|
||||
"Schedule a one-shot or recurring message. Without `to`, it fires back to yourself (a self-reminder). With `to`, it delivers to a peer, @group, or * broadcast. For one-shot, provide `deliver_at` or `in_seconds`. For recurring, provide `cron` (standard 5-field expression). The broker persists schedules to the database — they survive restarts. Receivers see `subtype: reminder` in the push envelope.",
|
||||
inputSchema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
message: { type: "string", description: "Message or reminder text" },
|
||||
deliver_at: { type: "number", description: "Unix timestamp (ms) when to deliver" },
|
||||
in_seconds: { type: "number", description: "Alternative to deliver_at: fire after N seconds" },
|
||||
deliver_at: { type: "number", description: "Unix timestamp (ms) when to deliver (one-shot)" },
|
||||
in_seconds: { type: "number", description: "Alternative to deliver_at: fire after N seconds (one-shot)" },
|
||||
cron: { type: "string", description: "Cron expression for recurring reminders (e.g. '0 */2 * * *' for every 2 hours, '30 9 * * 1-5' for 9:30 weekdays)" },
|
||||
to: {
|
||||
type: "string",
|
||||
description: "Recipient: display name, pubkey hex, @group, or * (omit for self-reminder)",
|
||||
|
||||
Reference in New Issue
Block a user