# Reminder

> Set reminders and manage todos with natural language. Uses built-in cron scheduling, no external service needed.

- Skill: `fuyuxiang/reminder` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add fuyuxiang/reminder`
- Raw SKILL.md: https://api.skillmd.com/api/skills/fuyuxiang/reminder/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: fuyuxiang (https://skillmd.com/u/fuyuxiang)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/fuyuxiang/reminder

---


# Reminder

Set timed reminders and manage todos.

## IMPORTANT: how a reminder actually fires

A row in `reminders.db` is just a note — nothing scans it or delivers it. To make
a reminder that *actually fires and gets delivered*, you MUST create a scheduled
job with the **`cronjob` tool**, which persists to the scheduler and is delivered
through the active channel by Echo Agent's scheduler service:

```
cronjob(action="create", name="weekly-report",
        schedule="0 9 * * 1", command="提醒你写周报")
```

The `reminder_store.py` script below is only a lightweight local note-taking
list (list/done/delete). It has NO delivery path on its own. If the user wants
to be reminded at a time, use `cronjob` — optionally also recording a note via
the script. For a background one-off that must take effect, `spawn_task` can run
the `cronjob` call for you.

### Jobs that produce a file (audio/image/document)

When the scheduled command generates an artifact the user must receive (e.g. a
voice briefing), make the delivery happen inside the same tool call — do not
assume a later step will send it. For audio use `text_to_speech(..., deliver=true)`
(see the tts-voice skill); for other files call `send_file` explicitly with the
target channel/chat. An unattended cron run may end right after producing the
file, so "generate then hope it gets sent" silently drops the artifact.

### After creating a job: confirm, then stop

Once `cronjob(action="create")` returns, you are done. Send the user ONE
confirmation with the concrete facts and end the turn:

- job id, the schedule, and the next fire time (from the create result)
- if a delivery target was inferred, say so; if the create result carried the
  "⚠️ 无法确定投递目标" warning, relay it and ask for target_channel/target_chat_id.

Do NOT try to "prove delivery works" by exercising the agent's own plumbing —
reading `gateway/server.py`, `a2a/server.py`, or curling internal endpoints like
`/v1/chat` or `/api/v1/message` is not verification, it's a rabbit hole that
burns the turn and leaves the user with no reply. If you genuinely need to sanity
-check the schedule, use `cronjob(action="list")`; trigger a real run at most
once and only if the user asked. The scheduled job itself is the delivery test —
it will fire on schedule.

## Quick Commands

| Action | Example |
|--------|---------|
| Set reminder | "提醒我明天9点开会" |
| Recurring | "每周一早上8点提醒我写周报" |
| List | "显示我的所有提醒" |
| Complete | "完成提醒 #3" |
| Delete | "删除提醒 #5" |

## Time Parsing

Natural language to cron expression mapping. Feed the resulting expression into
the `cronjob` tool's `schedule` argument:

| Input | Cron Expression |
|-------|----------------|
| 明天9点 | `0 9 {tomorrow} * *` |
| 每天早上8点 | `0 8 * * *` |
| 每周一 | `0 9 * * 1` |
| 每月1号 | `0 9 1 * *` |
| 2小时后 | one-shot timer |
| 工作日下午5点 | `0 17 * * 1-5` |

## Local note storage (no delivery)

The script keeps a local note list in SQLite: `~/.echo-agent/reminders.db`.
This is bookkeeping only — creating a row here does NOT schedule or deliver
anything. Timed delivery is the `cronjob` tool's job (see top of this doc).

```sql
CREATE TABLE reminders (
    id INTEGER PRIMARY KEY,
    content TEXT NOT NULL,
    cron_expr TEXT,
    next_fire DATETIME,
    is_recurring BOOLEAN DEFAULT 0,
    is_done BOOLEAN DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

## Script Usage (local notes only — does not schedule delivery)

```bash
python3 scripts/reminder_store.py add "写周报" --cron "0 9 * * 1"
python3 scripts/reminder_store.py list
python3 scripts/reminder_store.py done 3
python3 scripts/reminder_store.py delete 5
python3 scripts/reminder_store.py due  # show due reminders
```

## Delivery

Delivery is handled by the scheduler, not by this script. When you create a job
with the `cronjob` tool, the scheduler fires it on schedule and routes the
message through the active channel (Telegram/WeChat/etc). The `reminder_store.py`
script never delivers anything by itself.

