Skip to content

fix: separate daemon binary path from CLI to prevent launchd SIGKILL#8

Merged
willisrocks merged 3 commits intomainfrom
fix-launchd-binary-path
Mar 10, 2026
Merged

fix: separate daemon binary path from CLI to prevent launchd SIGKILL#8
willisrocks merged 3 commits intomainfrom
fix-launchd-binary-path

Conversation

@willisrocks
Copy link
Copy Markdown
Contributor

Summary

  • launchd's KeepAlive=true was SIGKILLing any CLI invocation (devproxy --version, etc.) because the plist pointed at the same binary path users invoke
  • Daemon binary now installed at ~/Library/Application Support/devproxy/devproxy-daemon (macOS) or ~/.local/share/devproxy/devproxy-daemon (Linux)
  • devproxy init copies binary to daemon path before installing plist
  • devproxy update updates both CLI and daemon binaries
  • 3 new e2e tests proving path separation works

Test plan

  • 68 unit tests pass, 13 e2e tests pass
  • cargo clippy clean
  • Manual: devproxy --version no longer hangs when daemon is running

🤖 Generated with Claude Code

chris-4d and others added 3 commits March 9, 2026 16:00
…IGKILL

launchd's KeepAlive=true monitors the managed binary path and SIGKILLs
any non-managed process at that path. This caused `devproxy --version`
(and all CLI commands) to be killed when run from ~/.local/bin/devproxy.

Fix: install a dedicated daemon binary at ~/.local/share/devproxy/devproxy-daemon
and point the launchd plist (and systemd unit) at that path instead. The CLI
binary at ~/.local/bin/devproxy is no longer managed by launchd and can run
freely.

Changes:
- config.rs: add daemon_binary_path() helper (respects DEVPROXY_DATA_DIR for tests)
- init.rs: copy binary to daemon path before installing plist/unit; pass daemon
  path to install_daemon(); add install_daemon_binary() helper
- update.rs: update daemon binary alongside CLI binary after download
- init.rs: update is_devproxy_process() to recognize "devproxy-daemon"
- e2e tests: add test_version_works_with_daemon_running,
  test_init_daemon_binary_path_separation, test_daemon_binary_matches_cli_binary;
  update test_launchd_socket_activation to verify plist uses daemon binary path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Fallback spawn now uses daemon_bin path instead of CLI exe path,
   ensuring the path separation fix applies to both socket activation
   and direct spawn code paths.

2. DEVPROXY_DATA_DIR does not need plist/unit propagation -- documented
   why: daemon_binary_path() is only called by CLI commands (init,
   update), never by the daemon process itself.

3. Deduplicated prepare_binary logic: install_daemon_binary now delegates
   to update::prepare_binary (made pub(crate)) instead of inlining the
   same chmod + xattr + codesign sequence.

4. Fixed doc comment on daemon_binary_path() to show actual platform
   paths (~/Library/Application Support on macOS, ~/.local/share on
   Linux) instead of incorrectly stating ~/.local/share for all.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The error message said "downloaded binary" but prepare_binary is now
also called for the daemon binary copy during init.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@willisrocks willisrocks merged commit dee4aea into main Mar 10, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants