Installs into .claude/skills of the current project.
Are you the author of Cron?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/flagdizero-cron)
---
name: cron
description: Schedule reminders, recurring checks and conditional alerts.
locked: true
---
# Cron
Use the `cron` tool to schedule work. Every scheduled job runs a full agent turn.
## Pick the mode first
`mode` is a real parameter of `action="add"`. It decides whether the job is
**allowed to speak on its own**, and it is the single most important choice here —
getting it wrong is what turns a check into chat spam.
| `mode` | Speaks | Session | Use when |
|---|---|---|---|
| `reminder` (default) | Every run, automatically | this conversation | the user wants to hear from it every time it fires |
| `monitor` | **Only** if you call the `message` tool | its own isolated session | the run should stay silent unless it finds something |
`monitor` requires `every_seconds` or `cron_expr`; it is never valid with `at`.
**Any request phrased as a condition is a `monitor`.** Listen for: "only tell me
if…", "warn me when…", "let me know if it goes below…", "check every 10 minutes
whether it's back up". If the user described *when they want to be interrupted*,
they also described when they do **not** — that is `mode="monitor"`.
In a `monitor` run, silence is a **correct, successful outcome**. Do not call
`message` to report that everything is normal, and never send filler like
"All clear.", "All done." or "nothing to report" — the user asked to be left
alone in exactly that case. A monitor keeps its earlier runs in its own session,
so it can report a *change* instead of repeating itself. Each run costs a full
turn: prefer the loosest interval that still answers the need.
## Examples
Fixed reminder — speaks every time:
```
cron(action="add", message="Time to take a break!", every_seconds=1200, mode="reminder")
```
Conditional alert — speaks only when the condition fires:
```
cron(action="add", message="Check the chance of rain in every city on the list; if any is above 70%, warn me. Otherwise say nothing.", every_seconds=3600, mode="monitor")
```
Recurring check whose result the user always wants:
```
cron(action="add", message="Check GitHub stars and report the count", every_seconds=600, mode="reminder")
```
One-time scheduled task (compute ISO datetime from current time; auto-deletes):
```
cron(action="add", message="Remind me about the meeting", at="<ISO datetime>")
```
Timezone-aware schedule:
```
cron(action="add", message="Morning standup", cron_expr="0 9 * * 1-5", tz="America/Vancouver", mode="reminder")
```
List/remove:
```
cron(action="list")
cron(action="remove", job_id="abc123")
```
`action="list"` reports each job's last status. `silenced` there means a monitor
ran fine and had nothing to say — it is a success, not an error.
## cron or HEARTBEAT.md?
- Ambient check, fine on the shared heartbeat beat → add a line to `HEARTBEAT.md`.
- Must reach the user every time, or needs its own schedule → `cron` with `mode="reminder"`.
- Needs its own schedule *and* should only speak when something is worth
reporting → `cron` with `mode="monitor"`.
`HEARTBEAT.md` has one interval for the whole file: when the user wants a
different cadence for one specific check, that is a `cron` job, not a heartbeat
line. Heartbeat runs are silent by the same contract as a monitor — the only way
they reach the user is the `message` tool — so a conditional check written as a
heartbeat line must say what the condition is, and must not report a normal
result.
Only the lines under `## Active Tasks` are read: a heading inside that section is
kept as context for the lines below it, and everything outside that section never
reaches the model. An HTML comment is dropped when it *starts its own line* (a
multi-line one is dropped whole); a comment written at the end of a task line
stays with the line and is read as part of the task, so put a note you don't want
read on a line of its own. Leaving a comment unclosed hides every line after it,
in the section and outside it, and those tasks stop running.
The gateway registers the heartbeat job itself and protects it: never add a second
cron job that reads `HEARTBEAT.md`, unless the user has disabled the built-in one
and explicitly wants a custom schedule for it.
A file with no task lines is skipped without running a turn, so a finished task
should be deleted rather than crossed out or left in place.
## Time Expressions
| User says | Parameters |
|-----------|------------|
| every 20 minutes | every_seconds: 1200 |
| every hour | every_seconds: 3600 |
| every day at 8am | cron_expr: "0 8 * * *" |
| weekdays at 5pm | cron_expr: "0 17 * * 1-5" |
| 9am Vancouver time daily | cron_expr: "0 9 * * *", tz: "America/Vancouver" |
| at a specific time | at: ISO datetime string (compute from current time) |
## Timezone
Use `tz` with `cron_expr` to schedule in a specific IANA timezone. Without `tz`, the server's local timezone is used.