Skill v1.0.0
currentLLM-judged scan90/100version: "1.0.0" name: managing-launchd-jobs description: Defines, applies, and inspects launchd user agents on TJ's Macs (the always-on work mac mini work, and others) through the dotfiles-managed lj tool. Use when asked to add a background job, cron, or daemon on one of his machines, to check whether a launchd job is running or healthy, or to read a job's log. Never hand-write ~/Library/LaunchAgents plists.
Managing launchd jobs
All user launchd agents on this machine are defined in ~/dev/dotfiles/launchd/jobs/<name>/ and rendered into ~/Library/LaunchAgents/com.tjbai.<name>.plist by lj (~/dev/dotfiles/launchd/lj, on PATH). The repo is the source of truth; lj owns every com.tjbai.* label and nothing else.
Inspect
lj ls— repo jobs with loaded state, pid, last exit, last run, run count.--alladds every other agent in the user domain, read-only.lj status <name>— fulllaunchctl printfor one job (also accepts any label).lj log <name> [-f]—~/Library/Logs/tjbai/<name>.log; each run is bracketed bySTARTandEND exit=N dur=Nslines written by the wrapper.lj doctor— exit 1 if any job has drifted from its plist, is unloaded, failed its last run, is overdue for its interval, has a huge log, fails itscheckhook, or if an orphancom.tjbai.*plist exists.lj run <name>— start a run now (kickstart -k).
Define a job
Create ~/dev/dotfiles/launchd/jobs/<name>/ with:
job— bash-sourced spec. Exactly one trigger:INTERVAL=<seconds>,CALENDAR="Hour=5 Minute=0"(any StartCalendarInterval keys), orKEEP_ALIVE=1(daemon, restarted on exit). OptionalRUN_AT_LOAD=1,CWD=<dir>,DESC="...".run— the executable (chmod +x). It runs straight from the checkout vialj _exec <name>, which sets PATH, logs, records~/.local/state/lj/<name>.last, and notifies on non-zero exit. Edits torunare live on the next tick; only changes tojobneedlj apply.check— optional executable doctor hook; exit non-zero with a one-line reason to makelj doctorflag the job.
Then lj apply (or lj apply --prune to also unload labels the repo no longer defines), lj ls to confirm it loaded, and commit the dotfiles change. Do not push unless asked.
Rules
- Never write or edit
~/Library/LaunchAgents/*.plistdirectly, and neverlaunchctl loada hand-made plist. Define the job in the repo andlj apply. lj disable <name>/lj enable <name>to pause a job; deleting its directory pluslj apply --pruneremoves it.- Existing jobs:
amp-runner(keeps theworkAmp runner alive, hostworkonly; amp self-updates and re-execs in place viaamp.runner.autoUpdate.enabled, so thecheckhook compares the mapped binary inode, not mtime vs process start) andscratch-fold(hourly; folds the scratch repo'sinboxbranch intomain, one commit per project dir per closed 4h window — protocol in the using-scratch skill). Do not stopamp-runnerfrom a remote thread; it is the remote thread's only path to this machine.