macos-watchdog

Design and deploy macOS launchd watchdogs that self-remediate without becoming disturbances.

1.4k|216|Updated Oct 22, 2025
One-click install
npx skills add https://github.com/daymade/claude-code-skills --skill macos-watchdog
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: macos-watchdog
Source: https://github.com/daymade/claude-code-skills/tree/main/daymade-macos/macos-watchdog
Command: npx skills add https://github.com/daymade/claude-code-skills --skill macos-watchdog

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve?

macOS launchd watchdogs (LaunchAgents/LaunchDaemons) often become new sources of disturbance: they re-launch apps the user quit, spam notifications every interval, re-run full repair ladders on unfixable networks, or silently fail with no logs. This Skill provides the design contract and mechanics to build watchdogs that detect recurring problems, remediate them, and stand down by themselves when they cannot help.

Core Features & Use Cases

  • Quiet-watchdog contract: Four enforceable clauses — premise-state self-check, patient mode (remediate only on sustained failure), escalating auto-cooldown, and never resurrecting user-quit apps.
  • Deployment mechanics: Idempotent LaunchAgent installer script, annotated plist template guidance, bootstrap/bootout/disable semantics, logging via StandardOutPath/StandardErrorPath, and TCC/Full Disk Access pitfalls.
  • Reusable cooldown library: A sourceable bash script providing escalating backoff tiers, manual pause/resume, and exhausted-round counters for any self-healing script.
  • Use Case: A VPN-repair watchdog keeps popping the VPN app to the foreground every 5 minutes on a broken coffee-shop network. Use this Skill to diagnose the three violated clauses and add a process-alive gate, escalating cooldown, and notification throttling.

Quick Start

Ask the assistant to design a launchd watchdog that checks a local service every 10 minutes and restarts it only after sustained failures, with cooldown and quiet notifications.

Frequently Asked Questions about macos-watchdog

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a launchd LaunchAgent that runs a script on a schedule?

Write a plist with Label, ProgramArguments (absolute paths), and StartInterval into ~/Library/LaunchAgents, then load it with launchctl bootstrap gui/$(id -u) <plist>. Always set StandardOutPath and StandardErrorPath so failures are visible, and validate the plist with plutil -lint.

How do I stop a launchd job so it stays stopped?

Use launchctl bootout gui/$(id -u)/<label> to stop now, and launchctl disable user/$(id -u)/<label> to keep it stopped across logins. Never use launchctl unload — it is deprecated and on Ventura+ the job re-loads via RunAtLoad while the plist remains in place.

Why does my watchdog keep re-launching the app I quit?

The open command with a URL scheme launches the target app when it is not running, and without -g it also steals foreground. Gate every such action with a pgrep process-alive check and pass -g, and make cleanup traps honor the same gate.

Does ThrottleInterval prevent a watchdog from spamming repairs?

No. ThrottleInterval only rate-limits process respawn with a fixed delay and no backoff; a job that runs, spams, and exits 0 is outside its reach. Escalating cooldown must be implemented in the script itself using a state file and backoff tiers.

Why does my script work in the terminal but fail under launchd?

launchd jobs do not inherit your shell environment or PATH, so ProgramArguments must use absolute paths and explicit EnvironmentVariables. TCC or Full Disk Access must also be granted to the exact interpreter binary in ProgramArguments, not the one your shell resolves.

When should a watchdog send a notification instead of just logging?

Notify only when the failure persists beyond the self-recovery window, the full remediation ladder has failed, and it is the first notification for that failure sequence. Everything else should be a log line; entering cooldown warrants exactly one message, then silence.