Scheduled Local AI Jobs on macOS with launchd
Your First AI Job
A job that calls an LLM to do real work. Choose your provider.
Branch chooser
How do you want to call the LLM?
Provider: Anthropic API
Claude's messages API — system prompts, structured output.
- default
Provider: Coding Agent CLI
Shell out to claude, codex, or pi — zero config.
Provider: Ollama (Local)
No API key, no cloud. Everything runs on your Mac.
Provider: OpenAI API
Direct API calls with fetch. You manage the key, you pick the model.
Everything so far has been infrastructure. Now you build something that does real work — a job that calls an LLM.
The Job: Daily Digest
You'll build a job that reads markdown files from workdir/notes/, sends them to an LLM, and writes a summary to workdir/digests/. It runs every morning.
The structure is the same as every other job:
system-jobs/daily-digest/
schedule # when: daily at 8am
run # what: read notes, summarize with AI, write digestThe Schedule
{"type": "scheduled", "calendar": {"Hour": 8, "Minute": 0}}Daily at 8am. Change the hour to whatever makes sense for you.
The Run Script Pattern
Every AI job does three things:
The gather and output are yours. The process step depends on which LLM provider you use.
Choose Your Provider
How do you want to call the LLM? Pick the path that matches what you have:
Not sure? If you're taking this course with a coding agent, start with the Coding Agent path. It's 10 lines and needs no configuration.
Add Some Notes to Summarize
mkdir -p workdir/notes
cat > workdir/notes/project-ideas.md << 'EOF'
# Project Ideas
- Build a local AI job scheduler using launchd
- Explore WatchPaths for reactive file processing
- Look into a dashboard for monitoring
EOF
cat > workdir/notes/reading.md << 'EOF'
# Reading Notes
- Inngest blog: agents need a harness, not a framework
- launchd is the simplest possible harness
- Koster: fun = pattern learning at the right pace
EOFAfter You Pick a Provider
Once you've built the run script using your chosen provider, test it:
bun run src/cli.ts sync
bun run src/cli.ts kick daily-digest
bun run src/cli.ts logs daily-digestCheck the output:
cat workdir/digests/$(date +%Y-%m-%d).mdYou should see a digest of your notes, generated by AI, triggered by launchd.