cron
Cron
Overview
Use this skill to manage Codex automations through the native Zig cron CLI. Runtime paths are Zig-only (no Python fallback, no shell launchd wrappers).
Zig CLI Iteration Repos
When iterating on cron, use these two repos:
skills-zig(/Users/tk/workspace/tk/skills-zig): source for thecronbinary, build/test wiring, release tags.homebrew-tap(/Users/tk/workspace/tk/homebrew-tap): formula/checksum updates for released binaries.
Quick Start
run_cron_tool() {
install_cron_direct() {
local repo="${SKILLS_ZIG_REPO:-$HOME/workspace/tk/skills-zig}"
if ! command -v zig >/dev/null 2>&1; then
echo "zig not found. Install Zig from https://ziglang.org/download/ and retry." >&2
return 1
fi
if [ ! -d "$repo" ]; then
echo "skills-zig repo not found at $repo." >&2
echo "clone it with: git clone https://github.com/tkersey/skills-zig \"$repo\"" >&2
return 1
fi
if ! (cd "$repo" && zig build build-cron -Doptimize=ReleaseFast); then
echo "direct Zig build failed in $repo." >&2
return 1
fi
if [ ! -x "$repo/zig-out/bin/cron" ]; then
echo "direct Zig build did not produce $repo/zig-out/bin/cron." >&2
return 1
fi
mkdir -p "$HOME/.local/bin"
install -m 0755 "$repo/zig-out/bin/cron" "$HOME/.local/bin/cron"
}
local os="$(uname -s)"
if command -v cron >/dev/null 2>&1 && cron --help 2>&1 | grep -q "cron.zig"; then
cron "$@"
return
fi
if [ "$os" = "Darwin" ]; then
if ! command -v brew >/dev/null 2>&1; then
echo "homebrew is required on macOS: https://brew.sh/" >&2
return 1
fi
if ! brew install tkersey/tap/cron; then
echo "brew install tkersey/tap/cron failed." >&2
return 1
fi
elif ! (command -v cron >/dev/null 2>&1 && cron --help 2>&1 | grep -q "cron.zig"); then
if ! install_cron_direct; then
return 1
fi
fi
if command -v cron >/dev/null 2>&1 && cron --help 2>&1 | grep -q "cron.zig"; then
cron "$@"
return
fi
echo "cron binary missing or incompatible after install attempt." >&2
if [ "$os" = "Darwin" ]; then
echo "expected install path: brew install tkersey/tap/cron" >&2
else
echo "expected direct path: SKILLS_ZIG_REPO=<skills-zig-path> zig build build-cron -Doptimize=ReleaseFast" >&2
fi
return 1
}
- List automations:
run_cron_tool list - Show one automation:
run_cron_tool show --id <id> - Create an automation:
run_cron_tool create --name "Weekly release notes" --prompt-file /path/to/prompt.md --rrule "RRULE:FREQ=WEEKLY;BYDAY=FR;BYHOUR=9;BYMINUTE=0" - Update an automation:
run_cron_tool update --id <id> --rrule "RRULE:FREQ=DAILY;BYHOUR=9;BYMINUTE=0" - Enable or disable:
run_cron_tool enable --id <id>orrun_cron_tool disable --id <id> - Run immediately:
run_cron_tool run-now --id <id> - Delete:
run_cron_tool delete --id <id> - Run due automations once:
run_cron_tool run-due - Run due automations dry-run:
run_cron_tool run-due --dry-run - Install/start launchd scheduler (macOS):
run_cron_tool scheduler install - Stop/remove launchd scheduler (macOS):
run_cron_tool scheduler uninstall - Show scheduler status (macOS):
run_cron_tool scheduler status
Runtime bootstrap policy mirrors seq/cas/lift: require the Zig binary, default to Homebrew install on macOS, and fallback to direct Zig install from skills-zig on non-macOS.
Subcommand --help prints top-level usage. For detailed options, use the matrix below.
Workflow
- Choose working directories (
cwds). Default is current repo if omitted oncreate. - Write the automation prompt (use
--prompt-filefor multi-line prompts). - Provide an RFC5545 RRULE string.
- Create or update with
cron. - For unattended execution, install scheduler via
cron scheduler install.
Headless Runner
cron run-dueexecutes due automations by callingcodex execand updates:automations.last_run_atautomations.next_run_atautomation_runsrows
cron run-due --dry-runis read-only:- no
automation_runsrows are inserted/updated - no
automations.last_run_at/next_run_atupdates - no automation files or
memory.mdwrites
- no
--codex-binaccepts executable name or absolute path (default resolves$CODEX_BINorcodexinPATH).- Locking is label-scoped and fail-closed (
--lock-label, or envCRON_LAUNCHD_LABEL). --lock-labeluses strict label validation: only[A-Za-z0-9._-](no slashes/spaces).run-duedefault batch limit is10automations per invocation (--limitoverrides).- Scheduler commands are macOS-only and manage
~/Library/LaunchAgents/<label>.plistdirectly from Zig. - Launchd scheduler runs
run-duewith default DB path and default limit unless you invokecronmanually with overrides. - Logs:
~/Library/Logs/codex-automation-runner/out.logand~/Library/Logs/codex-automation-runner/err.log.
Command Options (High Signal)
list:--status <ACTIVE|PAUSED>,--jsonshow:--id <id>or--name <name>, optional--jsoncreate:--name,--prompt|--prompt-file,--rrule, optional--status,--cwd(repeatable),--cwds-json,--clear-cwds,--next-run-atupdate:--id|--name, optional--new-name,--prompt|--prompt-file,--rrule,--status,--cwd(repeatable),--cwds-json,--clear-cwds,--next-run-at,--clear-next-run-atenable|disable|run-now|delete:--idor--namerun-due: optional--id,--limit,--dry-run,--codex-bin,--lock-label([A-Za-z0-9._-]only)scheduler install: optional--label,--interval-seconds,--path,--codex-binscheduler uninstall|status: optional--label- Scheduler
--labelis strict: only[A-Za-z0-9._-](no slashes/spaces).
Clarify When Ambiguous
Ask questions only when the request is ambiguous or when the user explicitly asks for guidance. Do not block otherwise.
Essential elements to confirm or infer:
- Automation name.
- Prompt content (single line or file path).
- Schedule as an RFC5545 RRULE string (include
RRULE:prefix). - Working directories (
cwds), default to current repo if not specified. - Status if explicitly requested; otherwise default to
ACTIVE.
When ambiguous, ask for missing details. Examples:
- If user says “daily”/“weekly” without time, ask for required time/day fields.
- If user says “run it for this repo” without paths, confirm repo root as
cwd.
Schedule (RRULE)
- Accept only RFC5545 RRULE strings. Cron expressions are unsupported.
- Rules are canonicalized to
RRULE:-prefixed form. - Legacy non-prefixed stored values (
FREQ=...) are still accepted at run time for compatibility. - Validation is fail-closed.
BYHOUR/BYMINUTEare interpreted in UTC.- Supported frequencies:
HOURLYrequiresBYMINUTEDAILYrequiresBYHOURandBYMINUTEWEEKLYrequiresBYDAY,BYHOUR, andBYMINUTE
Example rules:
- Daily at 09:00:
RRULE:FREQ=DAILY;BYHOUR=9;BYMINUTE=0 - Weekly on Friday at 09:00:
RRULE:FREQ=WEEKLY;BYDAY=FR;BYHOUR=9;BYMINUTE=0 - Every 24 hours:
RRULE:FREQ=HOURLY;INTERVAL=24;BYMINUTE=0
Task Examples
Daily standup summary
Name: Summarize yesterday's git activity
Prompt: Summarize yesterday's git activity for standup. Include notable commits, files touched, and any risks or follow-ups.
Schedule: RRULE:FREQ=DAILY;BYHOUR=9;BYMINUTE=0
Weekly release notes
Name: Draft weekly release notes
Prompt: Draft weekly release notes from merged PRs. Include links when available and group by area.
Schedule: RRULE:FREQ=WEEKLY;BYDAY=FR;BYHOUR=9;BYMINUTE=0
CI failure triage
Name: Summarize CI failures
Prompt: Summarize CI failures and flaky tests from the last CI window, group by root cause, and suggest minimal fixes.
Schedule: RRULE:FREQ=DAILY;BYHOUR=8;BYMINUTE=30
Data Model Reference
See references/db.md for schema and field notes.