agentsclimarketplace

Cron to launchd macos

Skill bokuwalily/claude-code-skills/skills/cron-to-launchd-macos

macOS Sequoia/Tahoe で crontab に登録したジョブが一度も走っていない (system.log の cron 件数 0) ことを検知したとき、launchd plist に移行する手順。From its SKILL.md

Install
npx -y skills add bokuwalily/claude-code-skills --skill cron-to-launchd-macos

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.5 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it

Procedure

  1. 死活確認: log show --predicate 'process == "cron"' --last 7d で 0 件なら cron daemon が動いていない。
  2. plist 自動生成: ~/.claude/scripts/cron-to-launchd.sh dry~/.claude/scripts/launchd-proposed/ に crontab 各行 → com.<user>.<job>.plist を出力。bash 3.2 互換 (while read ループ、mapfile 不使用)。
  3. 適用: cron-to-launchd.sh apply~/Library/LaunchAgents/ に配置 + launchctl bootstrap gui/$(id -u) <plist>
  4. 即時動作確認: launchctl kickstart gui/$(id -u)/com.<user>.<job> で強制実行 → 対応する log file の mtime と PID を確認。
  5. 並走防止: cron 行は残置 (macOS の cron daemon が動いていないので二重実行リスクなし)。ユーザーに crontab -e で後日削除を推奨。

Pitfalls

  • */N 周期 (例: */5 * * * *) は StartCalendarInterval に直接マップできない → 配列で N 個の Minute entry に展開するか StartInterval (秒数) を使う。
  • launchctl list は legacy API。modern は launchctl print gui/$(id -u)/<label> / launchctl kickstart
  • Labelcom.<user>.<name> 形式。dot を含まない label は load 拒否される。
  • plist の ProgramArguments は配列必須 (string 単体は弾かれる)。StandardOutPath / StandardErrorPath は絶対パスで明示しないと /dev/null に消える。
  • gui/<uid> domain は GUI セッション必須。ヘッドレス常駐は system/ domain + /Library/LaunchDaemons/ 配置 (root 権限必要)。
  • ⚠️TCC保護領域に書けない: launchd起動プロセスは ~/Desktop ~/Documents ~/Downloads へ書くと PermissionError: Operation not permitted(exit 1)。Full Disk Access付与は対象が /bin/bash/python3 等になり広すぎ&手動GUI操作要。→ 実体を非保護パス(HOME直下 ~/foo 等)に置き、保護領域には symlink を張るのが定石(プロセスは実体パスに書く=TCC回避、ユーザーはDesktopから symlink で見える)。スクリプト内のパス定数は symlink でなく実体パスを参照させること。
  • ⚠️**env -i での再現テストは誤検知する**: 素環境で claude -p を回すと「Not logged in」やKeychainアクセス失敗で落ちるが、本物のlaunchd GUIエージェントはセキュリティセッションを保持してKeychainから認証が通る。検証は env -i でなく launchctl kickstart -k gui/$(id -u)/<label>本物のエージェントを実走させてログ&last exit codeを見る。
  • claude CLI認証(~/.local/bin/claude -p)はtoken/env不要。PATHに ~/.local/bin とnode(nvm)を通せば、login keychainの "Claude Code-credentials" から自動で認証される(本物launchd下で実績あり)。

Verification

  • launchctl list | grep com.<user> で全 plist が load 状態。
  • launchctl kickstart gui/$(id -u)/com.<user>.<name> 実行直後に log file の mtime が更新されている。
  • automation-health.sh の cron 死活セクションが ALL GREEN。
  • 1 週間後に各 log file の mtime が想定スケジュール通り進んでいる。

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,569. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.