schedule · git:20260611.a647953 · 2026-06-11 · sha256 0fb21314fa68be21
schedule git:20260611.a647953A
Immutable. This exact content is served forever at /api/v1/blob/0fb21314fa68be21.
---
name: schedule
description: >-
Manages recurring and one-off scheduled tasks. Session-scoped scheduling via
CronCreate/CronDelete/CronList. Documents the cloud path for tasks that need
to survive machine sleep or network drops.
user-invocable: true
auto-trigger: false
trigger_keywords:
- schedule
- recurring
- every N minutes
- cron
- set a reminder
- run periodically
last-updated: 2026-03-26
---
# /schedule — Task Scheduling
## Orientation
**Use when:** scheduling a recurring or one-off remote agent run (cron-style, outside the current session).
**Don't use when:** repeating work within the current session (use /loop); continuous unattended campaigns (use /daemon).
## Default execution path (READ FIRST)
**`/schedule add` does NOT call `CronCreate` by default.** It shells out to
`node scripts/local-schedule.js` which installs a native OS entry (Windows
Task Scheduler or Unix cron). Only pass `--remote` to use Anthropic's routine
system, and only after explicit user confirmation.
**Why:** `CronCreate` counts against the account-wide **15 routine runs / 24h**
cap; every fire of the scheduled task counts. See
[docs/ROUTINE-QUOTA.md](../../docs/ROUTINE-QUOTA.md).
### Default flow — `/schedule add "<expr>" "<command>"` (no `--remote`)
Run:
```bash
node scripts/local-schedule.js add "<expr>" "<command>"
```
Then report the returned ID and the removal command. This survives session
end, machine reboot, and consumes zero routine quota. Use
`/schedule list` and `/schedule remove {id}` (which also shell out to
`local-schedule.js`) by default.
### Codex automation lane
When running in Codex and the user wants the schedule to survive the current terminal session, create a Codex Automation plan instead of a local OS entry:
```bash
node scripts/codex-automation.js plan --type schedule --cadence "<expr>" --command "<command>" --write
```
Give the returned `prompt` to the Codex app automation surface and keep the generated `.planning/codex-automations/{id}.json` as the durable Citadel record.
If `.planning/` does not exist, create it before writing automation state.
### Opt-in routine flow — `/schedule add --remote ...`
Only when `--remote` is explicitly passed:
1. Confirm: "This will use `CronCreate`, which counts against your 15 routine
runs / 24h quota and is cleared at session end. Continue? (y/N)"
2. On confirmation, run the `CronCreate`-based flow documented below.
The rest of the protocol documents the full `CronCreate` flow for reference
and for `--remote` invocations.
## When to Route Here
- "run pr-watch every hour"
- "check my PRs automatically"
- "schedule a thing"
- "remind me to run tests every 30 minutes"
- "set up a recurring task"
- "list my scheduled tasks"
- "cancel the PR check"
- Any mention of "schedule", "recurring", "every N minutes/hours", "cron"
## Protocol
### /schedule list
List all currently scheduled tasks using CronList.
Output format:
```
Active schedules (N):
[id] {description} — {cron expression} — next run: {time}
No schedules active.
```
If CronList is not available: output a helpful error (see Fringe Cases).
---
### /schedule add "{description}" {/skill-or-command}
Create a recurring task.
Steps:
1. Parse the user's description to extract:
- Natural language interval: "every 30 minutes", "hourly", "every day at 9am"
- The skill or command to run: `/pr-watch`, `/do status`, etc.
2. Convert natural language to a cron expression (see Conversion Table below)
3. Confirm with user: "I'll run `{command}` {natural-language-interval} (cron: `{expression}`). OK?"
4. If confirmed: call CronCreate with the expression and command
5. Output: "Scheduled. ID: {id}. Use `/schedule remove {id}` to cancel."
**Cron Expression Conversion Table:**
| Natural Language | Cron Expression |
|---|---|
| every minute | `* * * * *` |
| every 5 minutes | `*/5 * * * *` |
| every 15 minutes | `*/15 * * * *` |
| every 30 minutes | `*/30 * * * *` |
| every hour / hourly | `0 * * * *` |
| every 2 hours | `0 */2 * * *` |
| every 6 hours | `0 */6 * * *` |
| every day / daily | `0 9 * * *` (default 9am) |
| every day at {H}am/pm | `0 {H} * * *` |
| every weekday | `0 9 * * 1-5` |
| every Monday | `0 9 * * 1` |
If the user provides a raw cron expression directly, use it as-is without
converting. Validate it has 5 fields before accepting.
---
### /schedule remove {id}
Remove a scheduled task by ID using CronDelete.
If the user doesn't know the ID: run `/schedule list` first, show the list,
and ask which one to remove.
Output: "Removed schedule {id} ({description})."
---
### /schedule status
Show all active schedules and their next run times. Equivalent to `/schedule list`
with additional context about what each task does and when it last ran (if available).
---
## Session-Scoped vs. Cloud-Persistent Scheduling
### Session-Scoped (CronCreate)
CronCreate schedules tasks that run during the **current Claude Code session only**.
When the session ends (Claude Code closes or the conversation is reset), all
session-scoped schedules are cleared.
**Use session-scoped when:**
- Running checks during an active work session ("remind me every 30min to commit")
- Polling for PR feedback while you're at the computer
- Triggering skill runs during a long coding session
### Cloud-Persistent (RemoteTrigger)
For tasks that need to survive machine sleep, network drops, or session restarts,
use **RemoteTrigger** — a one-off cloud trigger that fires from Anthropic's
infrastructure rather than your local session.
**Use cloud-persistent when:**
- The task needs to run overnight or while you're away
- You want notifications when you return to your machine
- The interval spans multiple days or calendar dates
**How to set up a one-off cloud trigger:**
1. Call RemoteTrigger with the desired delay and the command to run
2. Claude Code registers the trigger in Anthropic's cloud scheduler
3. When the trigger fires, it wakes a new Claude Code session and runs the command
4. Results are delivered as a notification
**Note:** RemoteTrigger requires Claude Code with cloud features enabled (Pro or
Team plan). CronCreate works on all plans but is session-scoped only.
---
## Fringe Cases
**CronCreate not available:** Output error; suggest OS cron/Task Scheduler. Never fail silently.
**Ambiguous interval:** Ask for clarification before proceeding.
**Raw cron expression:** Accept without conversion; validate 5 fields.
**Every-minute schedule:** Warn about 60 fires/hour; suggest 5m or 15m instead.
**No schedules when listing:** "No active schedules. Use `/schedule add` to create one."
**Pause requested:** Explain pause isn't supported; remove and recreate instead.
---
## Contextual Gates
**Disclosure:** "Creating schedule: `{command}` at `{cron expression}`. OK?"
**Reversibility:** amber — creates OS cron entries or CronCreate sessions (side effects outside the repo); undo with `/schedule remove {id}`
**Trust gates:**
- Any: confirms before creating; shows cron expression before accepting
## Quality Gates
- Always confirm before creating (CronCreate is a side effect)
- Always show the cron expression alongside the natural-language description
- Always provide the ID after creation so the user can remove it
- Never leave a user unable to remove a schedule they created
## Exit Protocol
/schedule does not produce a HANDOFF block. After each action, output a concise
confirmation or list and wait for the next command.
- After `add`: "Scheduled. ID: {id}. Use `/schedule remove {id}` to cancel."
- After `remove`: "Removed schedule {id}."
- After `list` or `status`: the active schedule list (or "No active schedules.")
- After any error: a clear message and actionable suggestion.