What happened?
The README quickstart (curl -fsSL https://codealmanac.com/install.sh | sh then codealmanac setup --yes) fails on Linux. Setup writes config, installs instructions, writes a macOS launchd plist into ~/Library/LaunchAgents/ (on a Linux box), then dies:
codealmanac: launchctl bootstrap failed for com.codealmanac.sync: [Errno 2] No such file or directory: 'launchctl'
Exit code is 1 and the machine is left in a half-configured state:
~/.codealmanac/config.toml is written, agent instructions are installed, and an orphan com.codealmanac.sync.plist sits in ~/Library/LaunchAgents/ where nothing will ever read it.
The cause: create_app() wires AutomationService with LaunchdSchedulerAdapter unconditionally (src/codealmanac/app.py), and the adapter shells out to launchctl
(src/codealmanac/integrations/automation/scheduler/launchd.py). There is no platform check anywhere in the setup/automation path. The repo's own wiki already acknowledges this: almanac/architecture/setup/automation-and-update.md says "the production setup and automation path is macOS-specific until another scheduler adapter is added and wired" — but the README, PyPI metadata
(Operating System :: OS Independent), and setup output say nothing about it.
What did you expect?
One of:
setup --yes detects a non-macOS platform, skips scheduled automation with a clear message ("scheduled automation is macOS-only for now, skipping sync/ garden/update schedules"), and still exits 0 with everything else installed, or - a hard, early, actionable error before any files are written, plus README docs saying automation requires macOS.
Either way, no plist should be written to ~/Library/LaunchAgents/ on Linux, and the quickstart should not crash on a supported Python platform.
Reproduction
# On any Linux machine, with the default runner (codex) installed and logged in:
codealmanac setup --yes
# -> codealmanac: launchctl bootstrap failed for com.codealmanac.sync: [Errno 2] No such file or directory: 'launchctl'
# Or without any runner at all:
codealmanac automation install sync --every 5h
# -> same failure, and ~/Library/LaunchAgents/com.codealmanac.sync.plist is left behind
Environment
- OS: Ubuntu 24.04 (Linux 6.8)
- Python version: 3.12.3
- CodeAlmanac version: 0.3.7
- Install method: local checkout (
uv run), also reproduces from PyPI install
- Agent provider, if relevant: Codex
- Almanac root, if relevant:
almanac/
Logs or output
$ codealmanac automation install sync --every 5h
codealmanac: launchctl bootstrap failed for com.codealmanac.sync: [Errno 2] No such file or directory: 'launchctl'
$ echo $?
1
$ ls ~/Library/LaunchAgents
com.codealmanac.sync.plist
Extra context
The partial-state problem makes this worse than a plain unsupported-platform error: setup completes config + instructions, then fails on the first automation task, so sync never gets scheduled and the user has no idea whether the rest of setup took effect. A minimal fix (platform guard in setup task selection + README note) keeps the door open for a later cron/systemd scheduler adapter behind the same SchedulerAdapter port.
What happened?
The README quickstart (
curl -fsSL https://codealmanac.com/install.sh | shthencodealmanac setup --yes) fails on Linux. Setup writes config, installs instructions, writes a macOS launchd plist into~/Library/LaunchAgents/(on a Linux box), then dies:Exit code is 1 and the machine is left in a half-configured state:
~/.codealmanac/config.tomlis written, agent instructions are installed, and an orphancom.codealmanac.sync.plistsits in~/Library/LaunchAgents/where nothing will ever read it.The cause:
create_app()wiresAutomationServicewithLaunchdSchedulerAdapterunconditionally (src/codealmanac/app.py), and the adapter shells out tolaunchctl(
src/codealmanac/integrations/automation/scheduler/launchd.py). There is no platform check anywhere in the setup/automation path. The repo's own wiki already acknowledges this:almanac/architecture/setup/automation-and-update.mdsays "the production setup and automation path is macOS-specific until another scheduler adapter is added and wired" — but the README, PyPI metadata(
Operating System :: OS Independent), and setup output say nothing about it.What did you expect?
One of:
setup --yesdetects a non-macOS platform, skips scheduled automation with a clear message ("scheduled automation is macOS-only for now, skipping sync/ garden/update schedules"), and still exits 0 with everything else installed, or - a hard, early, actionable error before any files are written, plus README docs saying automation requires macOS.Either way, no plist should be written to
~/Library/LaunchAgents/on Linux, and the quickstart should not crash on a supported Python platform.Reproduction
Environment
uv run), also reproduces from PyPI installalmanac/Logs or output
Extra context
The partial-state problem makes this worse than a plain unsupported-platform error: setup completes config + instructions, then fails on the first automation task, so
syncnever gets scheduled and the user has no idea whether the rest of setup took effect. A minimal fix (platform guard in setup task selection + README note) keeps the door open for a later cron/systemd scheduler adapter behind the sameSchedulerAdapterport.