Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Generate headless Claude Code cron jobs with safety.
.claude/skills/notque-headless-cron-creator/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 31% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 27% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 85% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 81% | 0% |
Generate headless Claude Code cron jobs from a task description and schedule. Creates a wrapper script with safety mechanisms (lockfile, budget cap, dry-run default, logging) and installs crontab entries. All crontab mutations go through scripts/crontab-manager.py, which writes to temp files and creates timestamped backups in ~/.claude/crontab-backups/ before every change -- never pipe directly to crontab - because a mid-stream pipe failure wipes the entire crontab.
Extract job parameters from the user's request.
Required parameters:
reddit-automod, feed-health-check)Optional parameters (with defaults):
cd before running (default: current repo root)2.00; user may override)Bash Read; user may override){workdir}/cron-logs/{name})Human-readable schedule conversion -- use off-minutes (7, 23, 47) instead of :00/:30 because every cron job on the system fires at round minutes, creating load spikes:
| Human Input | Cron Expression | |-------------|----------------| | every 12 hours | 7 */12 * * * | | twice daily | 7 8,20 * * * | | hourly | 23 * * * * | | daily at 6am | 7 6 * * * | | weekly on sunday | 7 9 * * 0 | | every 30 minutes | */30 * * * * |
Gate: All required parameters extracted. Proceed to Phase 2.
Create the wrapper script using crontab-manager.py generate-wrapper. Embed the prompt via bash heredoc to avoid escaping issues.
bashpython3 ~/.claude/scripts/crontab-manager.py generate-wrapper \ --name "{name}" \ --prompt "{prompt}" \ --schedule "{schedule}" \ --workdir "{workdir}" \ --budget "{budget}" \ --allowed-tools "{allowed_tools}"
Review the generated script. Verify it contains:
set -euo pipefailflock lockfile -- prevents concurrent runs of the same job--permission-mode auto -- never use --dangerously-skip-permissions (auto is sufficient) or --bare (breaks OAuth/keychain auth)--max-budget-usd -- caps spend per run (default 2.00 USD)--no-session-persistence--allowedToolstee to per-run timestamped log file--executePIPESTATUS[0]Do not use the CronCreate tool -- it is session-scoped (dies when the session ends, auto-expires after 7 days). Use system crontab via crontab-manager.py instead.
Gate: Script generated and reviewed. Proceed to Phase 3.
Verify the generated script meets cron best practices.
bash bash -n scripts/{name}-cron.sh # syntax check
cron-job-auditor checks:set -e)flock)tee, LOG_DIR)cd)claude -- cron has minimal PATH, so all commands must use absolute paths)Gate: All checks pass. Proceed to Phase 4.
Install the crontab entry. Every entry gets a # claude-cron: <tag> marker so crontab-manager.py can identify and manage only its own entries without touching non-Claude crontab lines. All paths in the crontab entry must be absolute because cron has minimal PATH.
bash python3 ~/.claude/scripts/crontab-manager.py add \ --tag "{name}" \ --schedule "{schedule}" \ --command "{absolute_script_path} --execute >> {logdir}/cron.log 2>&1" \ --dry-run
bash python3 ~/.claude/scripts/crontab-manager.py add \ --tag "{name}" \ --schedule "{schedule}" \ --command "{absolute_script_path} --execute >> {logdir}/cron.log 2>&1"
bash python3 ~/.claude/scripts/crontab-manager.py verify --tag "{name}"
Gate: Entry installed and verified. Proceed to Phase 5.
Summarize the created cron job and print the exact commands to test and manage it.
Output:
python3 ~/.claude/scripts/crontab-manager.py list # see all claude cron jobs python3 ~/.claude/scripts/crontab-manager.py verify --tag {name} # health check python3 ~/.claude/scripts/crontab-manager.py remove --tag {name} # uninstall
To modify an existing wrapper script, regenerate it with --force rather than editing in place.
Cause: A cron entry with this tag is already installed. Solution: Either remove --tag {name} first, or choose a different name.
Cause: Cron has minimal PATH; claude isn't in it. Solution: generate-wrapper resolves the absolute path to claude at generation time. If the path changes, regenerate the wrapper with --force.
Cause: System crontab service issue. Solution: Check crontab -l manually. Restore from ~/.claude/crontab-backups/.
scripts/crontab-manager.py -- all crontab mutations (add, remove, list, verify, generate-wrapper)skills/infrastructure/cron-job-auditor/SKILL.md -- validation checks for generated scripts| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-06 | fail→pass | 12,618 | 3,622 | -71% | 1 | 1 | 0% | 1,779 | 2,242 | +26% | 0 | 0 | — |
case-07 | fail→pass | 10,212 | 1,870 | -82% | 1 | 1 | 0% | 1,540 | 2,015 | +31% | 0 | 0 | — |
case-08 | fail→pass | 13,109 | 6,426 | -51% | 1 | 1 | 0% | 2,243 | 2,854 | +27% | 0 | 0 | — |
case-01 | fail→fail | 18,575 | 6,493 | -65% | 1 | 1 | 0% | 3,414 | 2,094 | -39% | 0 | 0 | — |
case-02 | fail→fail | 6,164 | 8,419 | +37% | 1 | 1 | 0% | 291 | 2,472 | +749% | 0 | 0 | — |
case-03 | fail→fail | 23,912 | 4,769 | -80% | 1 | 1 | 0% | 4,634 | 2,302 | -50% | 0 | 0 | — |
case-04 | fail→pass | 7,687 | 5,622 | -27% | 1 | 1 | 0% | 1,457 | 2,694 | +85% | 0 | 0 | — |
case-05 | fail→pass | 10,632 | 7,844 | -26% | 1 | 1 | 0% | 1,719 | 3,114 | +81% | 0 | 0 | — |
case-09 | pass→pass | 12,445 | 5,552 | -55% | 1 | 1 | 0% | 1,972 | 2,625 | +33% | 0 | 0 | — |
case-10 | pass→pass | 12,379 | 5,950 | -52% | 1 | 1 | 0% | 2,003 | 2,514 | +26% | 0 | 0 | — |
case-11 | pass→pass | 11,849 | 6,206 | -48% | 1 | 1 | 0% | 1,955 | 2,653 | +36% | 0 | 0 | — |
case-12 | fail→pass | 12,440 | 5,866 | -53% | 1 | 1 | 0% | 1,867 | 2,620 | +40% | 0 | 0 | — |
case-13 | fail→pass | 10,975 | 4,987 | -55% | 1 | 1 | 0% | 1,826 | 2,601 | +42% | 0 | 0 | — |
case-14 | fail→pass | 11,776 | 5,994 | -49% | 1 | 1 | 0% | 2,013 | 2,823 | +40% | 0 | 0 | — |
case-15 | fail→pass | 12,141 | 2,737 | -77% | 1 | 1 | 0% | 1,889 | 2,045 | +8% | 0 | 0 | — |
case-16 | fail→pass | 14,882 | 3,235 | -78% | 1 | 1 | 0% | 2,279 | 2,252 | -1% | 0 | 0 | — |
case-17 | pass→pass | 3,198 | 1,429 | -55% | 1 | 1 | 0% | 476 | 1,867 | +292% | 0 | 0 | — |
case-18 | fail→pass | 12,032 | 1,594 | -87% | 1 | 1 | 0% | 1,919 | 1,920 | +0% | 0 | 0 | — |
case-19 | fail→pass | 10,432 | 2,258 | -78% | 1 | 1 | 0% | 1,908 | 2,017 | +6% | 0 | 0 | — |
case-20 | pass→pass | 9,733 | 7,355 | -24% | 1 | 1 | 0% | 1,890 | 3,039 | +61% | 0 | 0 | — |
case-21 | fail→pass | 7,335 | 6,639 | -9% | 1 | 1 | 0% | 1,117 | 2,783 | +149% | 0 | 0 | — |
case-22 | pass→pass | 7,369 | 5,526 | -25% | 1 | 1 | 0% | 1,356 | 2,674 | +97% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +59 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.