setup-health-cron
Schedules the daily-health-report skill to run automatically at a user-specified local time. Prefers launchd on macOS. Falls back to cron only when explicitly requested.
When to invoke
Trigger on phrases like: "setup daily health cron", "schedule mac health check", "automate daily report", "cron my mac check".
Inputs
- Time of day (local). Default
09:00. AcceptHH:MMin 24-hour form. - Mode:
launchd(default) orcron.
Procedure (launchd — default)
Confirm with the user before writing anything: "Ready to install
~/Library/LaunchAgents/com.dennisonbertram.mac-guardian.daily.plistto run daily at HH:MM. Proceed?" Abort on "no".Resolve plugin root: prefer
${CLAUDE_PLUGIN_ROOT}. Otherwise, derive it from the current skill path.Build the plist at
~/Library/LaunchAgents/com.dennisonbertram.mac-guardian.daily.plist:<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key><string>com.dennisonbertram.mac-guardian.daily</string> <key>ProgramArguments</key> <array> <string>/bin/bash</string> <string>-lc</string> <string>PLUGIN_ROOT="<ABSOLUTE PATH>"; bash "$PLUGIN_ROOT/scripts/render.sh" && bash "$PLUGIN_ROOT/scripts/open-report.sh"</string> </array> <key>StartCalendarInterval</key> <dict> <key>Hour</key><integer>HH</integer> <key>Minute</key><integer>MM</integer> </dict> <key>StandardOutPath</key><string>/tmp/mac-guardian.daily.out.log</string> <key>StandardErrorPath</key><string>/tmp/mac-guardian.daily.err.log</string> <key>RunAtLoad</key><false/> </dict> </plist>Substitute
<ABSOLUTE PATH>,HH,MM.Houris 0–23.Minuteis 0–59.Load it:
launchctl bootout gui/$UID ~/Library/LaunchAgents/com.dennisonbertram.mac-guardian.daily.plist 2>/dev/null || true launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.dennisonbertram.mac-guardian.daily.plist launchctl enable gui/$UID/com.dennisonbertram.mac-guardian.dailyVerify:
launchctl print gui/$UID/com.dennisonbertram.mac-guardian.daily | head -30Note: the launchd agent runs
render.shandopen-report.shonly. It does not re-run the collection skills automatically — collection requires Claude Code. Tell the user explicitly:"The scheduled job renders and opens a dashboard from whatever JSON has accumulated in ~/.mac-guardian/data. To refresh data, run
/mac-healthmanually."Print the uninstall instructions:
launchctl bootout gui/$UID ~/Library/LaunchAgents/com.dennisonbertram.mac-guardian.daily.plist rm ~/Library/LaunchAgents/com.dennisonbertram.mac-guardian.daily.plist
Procedure (cron — only when asked)
- Confirm with the user before editing crontab.
- Show the line that will be appended:
MM HH * * * /bin/bash -lc 'bash "<PLUGIN_ROOT>/scripts/render.sh" && bash "<PLUGIN_ROOT>/scripts/open-report.sh"' >>/tmp/mac-guardian.cron.log 2>&1 - Append via
(crontab -l 2>/dev/null; echo "<line>") | crontab -. - Print uninstall instructions:
crontab -eand remove the line, orcrontab -l | grep -v mac-guardian | crontab -.
Output contract
Write a JSON envelope to ~/.mac-guardian/data/setup-health-cron-<ISOdate>.json:
{
"skill": "setup-health-cron",
"timestamp": "...",
"severity": "ok",
"summary": "Installed launchd agent for 09:00 daily",
"findings": [],
"raw": { "mode": "launchd", "time": "09:00", "plist_path": "/Users/.../com.dennisonbertram.mac-guardian.daily.plist" }
}
Handoff
- On direct invocation, also render a mini HTML via
bash ${CLAUDE_PLUGIN_ROOT}/scripts/render-single.sh setup-health-cron.
Safety
- Must prompt for confirmation before writing a launchd plist or modifying crontab.
- Never use
sudo— the agent is user-level (gui/$UID). - If the plist already exists, prompt before overwriting.
- On any failure during bootstrap/enable, restore the previous plist (if any) and report the error.