home / skills / tkersey / dotfiles / cron

cron skill

/codex/skills/cron

This skill helps you manage Codex automations by editing the local SQLite store and filesystem configs, enabling fast creation, updates, and runs.

npx playbooks add skill tkersey/dotfiles --skill cron

Review the files below or copy the command above to add this skill to your agents.

Files (8)
SKILL.md
6.6 KB
---
name: cron
description: Create and manage Codex app automations stored in the local SQLite database (~/.codex/sqlite/codex-dev.db). Use when you need to add, list, update, enable/disable, delete, or run-now automations; edit automation names, prompts, RRULE schedules, or cwd scopes; or inspect automation records while troubleshooting app automation behavior.
---

# Cron

## Overview
Use this skill to manage Codex automations by editing the local SQLite database and synced filesystem automation configs. Use `run_cron_tool` to prefer the Zig CLI with script fallback and keep changes minimal and explicit.

## Zig CLI Iteration Repos

When iterating on the Zig-backed `cron` helper CLI path, use these two repos:

- `skills-zig` (`/Users/tk/workspace/tk/skills-zig`): source for the `cron` Zig binary, build/test wiring, and release tags.
- `homebrew-tap` (`/Users/tk/workspace/tk/homebrew-tap`): Homebrew formula updates/checksum bumps for released `cron` binaries.

## Quick Start
```bash
CODEX_SKILLS_HOME="${CODEX_HOME:-$HOME/.codex}"
CLAUDE_SKILLS_HOME="${CLAUDE_HOME:-$HOME/.claude}"
CRON_SCRIPT="$CODEX_SKILLS_HOME/skills/cron/scripts/cron.py"
[ -f "$CRON_SCRIPT" ] || CRON_SCRIPT="$CLAUDE_SKILLS_HOME/skills/cron/scripts/cron.py"

run_cron_tool() {
  if command -v cron >/dev/null 2>&1 && cron --help 2>&1 | grep -q "cron.zig"; then
    cron "$@"
    return
  fi
  if [ "$(uname -s)" = "Darwin" ] && command -v brew >/dev/null 2>&1; then
    if ! brew install tkersey/tap/cron; then
      echo "brew install tkersey/tap/cron failed; refusing silent fallback." >&2
      return 1
    fi
    if command -v cron >/dev/null 2>&1 && cron --help 2>&1 | grep -q "cron.zig"; then
      cron "$@"
      return
    fi
    echo "brew install tkersey/tap/cron did not produce a compatible cron binary." >&2
    return 1
  fi
  if [ -f "$CRON_SCRIPT" ]; then
    uv run python "$CRON_SCRIPT" "$@"
    return
  fi
  echo "cron binary missing and fallback script not found: $CRON_SCRIPT" >&2
  return 1
}
```

- List automations: `run_cron_tool list`
- 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>` or `run_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 (headless): `scripts/automation_runner.py --once`
- Install and start user LaunchAgent scheduler: `scripts/install_launch_agent.sh`
- Stop and remove scheduler: `scripts/uninstall_launch_agent.sh`

Runtime bootstrap policy for `cron` mirrors `seq`/`cas`/`lift`: prefer the Zig `cron` binary; on macOS with `brew`, treat `brew install tkersey/tap/cron` failure (or incompatible binary) as a hard error; otherwise fallback to `uv run python "$CRON_SCRIPT"`.

## Workflow
1. Choose the working directories (`cwds`). Default to the current repo if not specified.
2. Write the automation prompt. Use `--prompt-file` for multi-line prompts.
3. Provide an RFC5545 RRULE string (see schedule guidance below).
4. Create or update the automation with `run_cron_tool`.
5. If you want hands-off execution without the desktop app, install the LaunchAgent with `scripts/install_launch_agent.sh`.

## Headless Runner
- `scripts/automation_runner.py` executes due automations by calling `codex exec` and updates:
  - `automations.last_run_at`
  - `automations.next_run_at`
  - `automation_runs` rows for each execution
- The runner uses `python-dateutil` via `uv` in the shebang and does not require a persistent venv.
- `--codex-bin` accepts either an absolute path or executable name; default resolves `$CODEX_BIN` or `codex` from `PATH`.
- `scripts/launchd_wrapper.sh` uses `lockf` to prevent overlapping runs.
- `scripts/install_launch_agent.sh` is idempotent and installs `~/Library/LaunchAgents/com.openai.codex.automation-runner.plist` with a 60-second interval by default.
  - Optional overrides:
    - `--label <reverse-dns-label>` (or env `CRON_LAUNCHD_LABEL`)
    - `--interval-seconds <n>` (or env `CRON_LAUNCHD_INTERVAL_SECONDS`)
    - `--path <PATH>` (or env `CRON_LAUNCHD_PATH`)
- `scripts/uninstall_launch_agent.sh` is idempotent and accepts optional `--label`.
- Logs: `~/Library/Logs/codex-automation-runner/out.log` and `~/Library/Logs/codex-automation-runner/err.log`.
- Service status:
  - `launchctl print gui/$(id -u)/com.openai.codex.automation-runner`

## 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:
1. Automation name.
2. Prompt content (single line or file path).
3. Schedule as an RFC5545 RRULE string (include `RRULE:` prefix).
4. Working directories (`cwds`), default to the current repo if not specified.
5. Status if explicitly requested; otherwise default to `ACTIVE`.

When ambiguous, ask for the missing details. Examples:
- If the user says “daily” or “weekly” without a time, ask for time and day-of-week when relevant.
- If the user says “run it for this repo” but does not specify paths, confirm the repo root as the only `cwd`.
- If the user asks “set it up like the app” without a schedule, ask for the RRULE or offer a concrete example to confirm.

## Schedule (RRULE)
- Accept only RFC5545 RRULE strings. Cron expressions are not supported.
- The app stores `RRULE:`-prefixed strings; include the prefix to match existing records. Both forms are accepted.
- Prefer explicit `BYHOUR`/`BYMINUTE` for stable schedules.

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 the database schema and field notes.

Overview

This skill manages Codex app automations stored in the local SQLite DB (~/.codex/sqlite/codex-dev.db) and the synced filesystem automation configs. It provides commands to add, list, update, enable/disable, delete, and run automations immediately, plus utilities to run due jobs headless via a LaunchAgent or single-run runner.

How this skill works

Operations are performed via the bundled scripts/cron.py which edits the automations table and syncs minimal filesystem config. Scheduling uses RFC5545 RRULE strings (prefixed with RRULE:), and a headless runner scripts/automation_runner.py executes due automations and records last_run_at/next_run_at and individual automation_runs rows. Installable LaunchAgent wrappers provide periodic execution without the desktop app.

When to use it

  • Add a new periodic automation with a prompt and RRULE schedule
  • Inspect automation records when a scheduled job didn't run or produced unexpected output
  • Update schedule, prompt, name, or working directories (cwd) for an existing automation
  • Enable or disable automations during testing or deployment windows
  • Run a specific automation immediately for debugging or one-off needs

Best practices

  • Always supply RFC5545 RRULE strings including BYHOUR and BYMINUTE for stable schedules
  • Use --prompt-file for multi-line prompts to avoid shell quoting issues
  • Keep cwds explicit; default is the repo root—confirm paths when ambiguous
  • Make minimal, explicit edits so filesystem and DB stay in sync
  • Use run-now and the headless runner to validate behavior before relying on the scheduler

Example use cases

  • Create a daily standup summary: create with prompt file and RRULE:FREQ=DAILY;BYHOUR=9;BYMINUTE=0
  • Draft weekly release notes: create or update an automation with RRULE:FREQ=WEEKLY;BYDAY=FR;BYHOUR=9;BYMINUTE=0
  • Temporarily disable an automation during a freeze using disable --id <id>
  • Force immediate execution of a flaky automation with run-now --id <id> to collect logs
  • Install the LaunchAgent for unattended execution and check logs at ~/Library/Logs/codex-automation-runner

FAQ

Do schedules accept cron expressions?

No. Only RFC5545 RRULE strings are supported. Include the RRULE: prefix to match stored records.

How do I provide multi-line prompts?

Use --prompt-file pointing to a file containing the full prompt to avoid quoting issues.

Can I run automations without the desktop app?

Yes. Install the LaunchAgent via scripts/install_launch_agent.sh or run scripts/automation_runner.py --once for headless execution.