macos-service-management
Manage and troubleshoot macOS launchd services — plist authoring, exit code diagnosis, variable expansion rules, and service lifecycle
Skill by lukemcqueen
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/lukemcqueen-macos-service-management
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/macos-service-management
What's inside
- Skill name
macos-service-management- Description
- Manage and troubleshoot macOS launchd services — plist authoring, exit code diagnosis, variable expansion rules, and service lifecycle
- License
- MIT
- Instructions
- 134 lines in SKILL.md · view on GitHub
Before installing
- Instructions read files in your home folder (~/.ssh, ~/.aws…)
Agent Skills spec issues
- body: contains an absolute path from the author's machine
Files (1)
- SKILL.md
SKILL.md (first lines)
# macOS Service Management (launchd)
Manage and debug launchd-based daemons and user agents on macOS. Launchd is macOS's system-wide service manager — analogous to systemd on Linux but with very different rules for paths, variables, and service configuration.
## Key Differences from systemd
| Concept | systemd (Linux) | launchd (macOS) |
|---------|----------------|-----------------|
| Unit file | `.service` | `.plist` (XML property list) |
| User services | `~/.config/systemd/user/` | `~/Library/LaunchAgents/` |
| System services | `/etc/systemd/system/` | `/Library/LaunchDaemons/` |
| User home variable | `%h` (expanded) | `$HOME` — **only in specific fields** |
| Shell variable expansion | Full (all env vars) | **None** — only `$HOME`, `$USER`, tilde `~` |
| Exit code 78 | N/A | EX_CONFIG — config error, launchd refuses to load |
| Reload | `systemctl daemon-reload` | `launchctl unload` + `load` (or `bootout`/`bootstrap`) |
## Service Lifecycle
```bash
# Load / start
launchctl load ~/Library/LaunchAgents/com.example.service.plist
# Modern form:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.service.plist
# Stop / unload
launchctl unload ~/Library/LaunchAgents/com.example.service.plist
# or
launchctl bootout gui/$(id -u)/com.example.service
# Check status
launchctl list | grep example
# OR status with exit code: launchctl print gui/$(id -u)/com.example.service
```
## Plist Authoring
```xml
<?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.example.service</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/my-service</string>
<string>--flag</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>WorkingDirectory</key><string>/Users/luke/project</string>
<key>StandardOutPath</key><string>/tmp/my-service.log</string>
<key>StandardErrorPath</key><string>/tmp/my-service.err</string>
</dict>
</plist>
```
Validate: `plutil -lint com.example.service.plist`
## Variable Expansion Rules
- `$HOME` and `$USER` **are** expanded — but only in select keys
(ProgramArguments, WorkingDirectory, paths).
- `~` tilde **is** expanded at the start of a path.
- **No other shell variables or `$(...)` are expanded.** A plist is NOT a shell script — write the full path.
- Environment variables for the child process go in an explicit
`<key>EnvironmentVariables</key>` dict.
## Exit Code Diagnosis
| Exit code | Meaning | Action |
|-----------|---------|--------|
| 0 | Clean exit | Normal (if KeepAlive, it restarts) |
| 1 | Generic error | Check the program's own logs |
| 78 | EX_CONFIG — bad plist | `plutil -lint` the plist; fix syntax |
| 126/127 | Command not found / not executable | Fix ProgramArguments path or `chmod +x` |
A service that exits immediately with 78 means **launchd rejected the plist
config itself** — the process never ran. Fix the plist, not the program.
## Restart-on-exit: the exit code must match the KeepAlive condition
launchd defines exactly five KeepAlive conditions — `SuccessfulExit`,
`NetworkState`, `PathState`, `OtherJobEnabled`, `Crashed`. Read them from the man
page (`man 5 launchd.plist`); **anything else in a KeepAlive dict is not a
condition**, so launchd finds no reason to restart the job and falls back to
demand-only launching.
| KeepAlive condition | Relaunches after | A deliberate self-restart must exit |
|---|---|---|
| `<true/>` | any exit | `0` |
| `SuccessfulExit` **true** | exit status 0 only | `0` |
| `SuccessfulExit` **false** | the INVERSE: exit status **non-zero** | non-zero (`75`, EX_TEMPFAIL) |
| `Crashed` true | a signal-terminated death only | n/a — a clean exit is not restarted |
- **`SuccessfulExit=false` does NOT mean "restart after a clean exit".** Apple's
wording is "restarted in the inverse condition": the job comes back on a NON-zero
status and a clean `exit 0` **PARKS** it. A restart command written for systemd
(`os._exit(0)` under `Restart=always`) therefore stops the service silently — the
exact failure the policy was added to fix. `systemctl`-shaped restart logic ported
to launchd without changing the exit code is the trap.
- **`CrashedOrAbnormalExit` is not a launchd key.** It appears in no man page, so a
KeepAlive dict carrying only it gives launchd no reason to restart: the job stays
down after any exit. Replace it with `SuccessfulExit=false` + a non-zero exit code,
or `<true/>` + exit 0.
- **Derive the exit code from the supervisor; never assume 0.** One binary may run
under systemd (`Restart=always` → 0) or launchd (`SuccessfulExit=false` → 75).
Prove which job owns the process with `launchctl list`: its **PID column** showing
OUR pid is the test, because `XPC_SERVICE_NAME` is inherited by every child exactly
as systemd's `INVOCATION_ID` is. Then read the job's OWN plist (`plutil -p` or
`plistlib`) and exit with the code that policy relaunches on; when no recognised
condition covers a deliberate exit, refuse and name the plist fix rather than
exiting into silence.
- **Confirm a relaunch with the job, not the chat:** `launchctl list <label>` shows a
NEW pid, and `LastExitStatus` is recorded as `exit_code << 8` (75 → 19200).
## Pitfalls
- ❌ **KeepAlive with unknown keys** — a dict of keys launchd does not define (e.g.
`CrashedOrAbnormalExit`) is the same as no KeepAlive at all: no restart, and theFrom lukemcqueen/hermes-cortex, MIT.
More from lukemcqueen/hermes-cortex
- 0.614score
ads
lukemcqueen
When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms.
SkillAFreshness: A★ 4Claude Code +9 - 0.602score
offline-knowledge
lukemcqueen
Offline knowledge cascade — query local content (web-cache, kiwix ZIM, mycortex) without internet.
SkillAFreshness: A★ 4Claude Code +9 - 0.598score
hermes-cortex-setup
lukemcqueen
Install and configure Hermes Cortex core components — Ollama, mycortex knowledge brain, health server, agent registry, hooks, cron jobs, and profile…
SkillAFreshness: A★ 4Claude Code +9 - 0.598score
hermes-cortex
lukemcqueen
Install, configure, and maintain Hermes Cortex — the observability and knowledge layer for Hermes Agent (Ollama, mycortex, Langfuse, Cortex Dashboard, nginx…
SkillAFreshness: A★ 4Claude Code +9 - 0.596score
pi-coding-agent
lukemcqueen
Operate the Pi coding agent CLI — install, extensions, Jev.
SkillAFreshness: A★ 4Claude Code +9 - 0.566score
ai-coding-agents
lukemcqueen
Delegate coding tasks to external AI coding agent CLIs — Claude Code, Codex CLI, and OpenCode.
SkillBFreshness: B★ 4Claude Code +9 - 0.566score
auto-remediation-fixes
lukemcqueen
Essential auto-remediation fixes for staging server guardian — timeout patterns, provider drift fixes, and operational hygiene for cron job errors and agent…
SkillBFreshness: B★ 4Claude Code +9 - 0.566score
answer-cache
lukemcqueen
Agent protocol for mycortex answer cache — inserts a cache-check step between RAG miss and model call.
SkillBFreshness: B★ 4Claude Code +9 - 0.565score
evaluating-agent-frameworks
lukemcqueen
Evaluate an external agent framework for interop.
SkillBFreshness: B★ 4Claude Code +9 - 0.516score
web-cache
lukemcqueen
Local semantic web cache for AI agents — cache web_search and web_extract results locally with embeddings, reducing API costs and enabling offline operation.
SkillCFreshness: C★ 4Claude Code +9
Signals
- Stars
- 4
- Forks
- 1
- Open issues
- 1
- Last commit (this folder)
- Oct 22, 2026 (6 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/lukemcqueen/hermes-cortex
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from lukemcqueen
- 0.614score
ads
lukemcqueen
When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms.
SkillAFreshness: A★ 4Claude Code +9 - 0.602score
offline-knowledge
lukemcqueen
Offline knowledge cascade — query local content (web-cache, kiwix ZIM, mycortex) without internet.
SkillAFreshness: A★ 4Claude Code +9 - 0.598score
hermes-cortex-setup
lukemcqueen
Install and configure Hermes Cortex core components — Ollama, mycortex knowledge brain, health server, agent registry, hooks, cron jobs, and profile…
SkillAFreshness: A★ 4Claude Code +9 - 0.598score
hermes-cortex
lukemcqueen
Install, configure, and maintain Hermes Cortex — the observability and knowledge layer for Hermes Agent (Ollama, mycortex, Langfuse, Cortex Dashboard, nginx…
SkillAFreshness: A★ 4Claude Code +9 - 0.596score
pi-coding-agent
lukemcqueen
Operate the Pi coding agent CLI — install, extensions, Jev.
SkillAFreshness: A★ 4Claude Code +9 - 0.566score
ai-coding-agents
lukemcqueen
Delegate coding tasks to external AI coding agent CLIs — Claude Code, Codex CLI, and OpenCode.
SkillBFreshness: B★ 4Claude Code +9
Cite this page
macos-service-management skill. Agent Mart. https://agentmart.dev/skills/lukemcqueen-macos-service-management (last updated 2026-10-24)