<< All versions

Skill v1.0.0

currentAutomated scan95/100
flagdizero/jenny-android-ai-agent/cron
──Details
PublishedSeptember 30, 2026 at 05:11 AM
Content Hashsha256:84f15dcdfcc30a6a...
Git SHAb87cee5b4687
──Files
Files (1 file, 5.2 KB)
SKILL.md5.2 KBactive
SKILL.md · 119 lines · 5.2 KB

version: "1.0.0" name: cron description: Schedule reminders, recurring checks and conditional alerts. locked: true user_summary: it: "Promemoria, controlli ricorrenti e avvisi condizionati: chiedi a Jenny di ricordarti qualcosa a un'ora precisa, di ripetere un'azione nel tempo, o di avvertirti solo se una certa condizione si verifica." en: "Reminders, recurring checks and conditional alerts: ask Jenny to remind you of something at a specific time, to repeat an action over time, or to warn you only when a condition is met."


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.

modeSpeaksSessionUse when
reminder (default)Every run, automaticallythis conversationthe user wants to hear from it every time it fires
monitorOnly if you call the message toolits own isolated sessionthe 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 soil humidity of all plants; if any is below 15%, 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 saysParameters
every 20 minutesevery_seconds: 1200
every hourevery_seconds: 3600
every day at 8amcron_expr: "0 8 *"
weekdays at 5pmcron_expr: "0 17 1-5"
9am Vancouver time dailycron_expr: "0 9 *", tz: "America/Vancouver"
at a specific timeat: 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.

All versions