launchd: restore gui domain defaults
Some checks are pending
/ triage (push) Waiting to run
GitHub Pages / publish (ubuntu-latest) (push) Waiting to run

User-domain agents are not rediscovered from the user LaunchAgents directory after reboot. Let built-in agents inherit the GUI default while keeping explicit user-domain configuration available.
This commit is contained in:
Austin Horstman 2026-07-15 10:25:32 -05:00
parent 6dc9e081ba
commit 165228b0ef
47 changed files with 11 additions and 83 deletions

View file

@ -16,9 +16,9 @@ This release has the following notable changes:
- On Darwin, Home Manager launchd agents now support - On Darwin, Home Manager launchd agents now support
[](#opt-launchd.agents._name_.domain) to choose either the user's GUI or [](#opt-launchd.agents._name_.domain) to choose either the user's GUI or
background launchd domain. Background services provided by Home Manager now background launchd domain. Agents use the GUI domain by default. Set the
use the user domain, which allows activations from contexts such as SSH domain to `user` for agents that should run without an active graphical login
sessions without requiring an active graphical login session. session.
## State Version Changes {#sec-release-26.11-state-version-changes} ## State Version Changes {#sec-release-26.11-state-version-changes}

View file

@ -6,10 +6,8 @@
message = '' message = ''
Home Manager launchd agents now support the Home Manager launchd agents now support the
`launchd.agents.<name>.domain` option. Background services provided by Home `launchd.agents.<name>.domain` option. Agents use the GUI launchd domain by
Manager use the user launchd domain by default, so they can be managed from default. Set `launchd.agents.<name>.domain = "user"` for agents that should
SSH and other non-graphical sessions. Set run without an active graphical login session.
`launchd.agents.<name>.domain = "gui"` for agents that need the graphical
session.
''; '';
} }

View file

@ -303,7 +303,6 @@ in
launchd.agents.atuin-daemon = { launchd.agents.atuin-daemon = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ (lib.getExe cfg.package) ] ++ daemonArgs; ProgramArguments = [ (lib.getExe cfg.package) ] ++ daemonArgs;
EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) { EnvironmentVariables = lib.optionalAttrs (daemonCfg.logLevel != null) {

View file

@ -609,7 +609,6 @@ in
{ {
"git-maintenance-hourly" = { "git-maintenance-hourly" = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = baseArguments ++ [ "--schedule=hourly" ]; ProgramArguments = baseArguments ++ [ "--schedule=hourly" ];
StartCalendarInterval = map (hour: { StartCalendarInterval = map (hour: {
@ -620,7 +619,6 @@ in
}; };
"git-maintenance-daily" = { "git-maintenance-daily" = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = baseArguments ++ [ "--schedule=daily" ]; ProgramArguments = baseArguments ++ [ "--schedule=daily" ];
StartCalendarInterval = map (weekday: { StartCalendarInterval = map (weekday: {
@ -632,7 +630,6 @@ in
}; };
"git-maintenance-weekly" = { "git-maintenance-weekly" = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = baseArguments ++ [ "--schedule=weekly" ]; ProgramArguments = baseArguments ++ [ "--schedule=weekly" ];
StartCalendarInterval = [ StartCalendarInterval = [

View file

@ -151,7 +151,6 @@ in
launchd.agents.nh-clean = lib.mkIf cfg.clean.enable { launchd.agents.nh-clean = lib.mkIf cfg.clean.enable {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
"${lib.getExe cfg.package}" "${lib.getExe cfg.package}"

View file

@ -631,7 +631,6 @@ in
launchd.agents = mkIf webCfg.enable { launchd.agents = mkIf webCfg.enable {
opencode-web = { opencode-web = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = ProgramArguments =
let let

View file

@ -160,7 +160,6 @@ let
in in
{ {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
(lib.getExe rcloneSidecarWrapper) (lib.getExe rcloneSidecarWrapper)
@ -620,7 +619,6 @@ in
mkLaunchdConfigService = lib.mkIf (cfg.remotes != { }) { mkLaunchdConfigService = lib.mkIf (cfg.remotes != { }) {
rclone-config = { rclone-config = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ (lib.getExe rcloneConfigScript) ]; ProgramArguments = [ (lib.getExe rcloneConfigScript) ];
RunAtLoad = true; RunAtLoad = true;

View file

@ -87,7 +87,6 @@ in
launchd.agents.borgmatic = { launchd.agents.borgmatic = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
(lib.getExe programConfig.package) (lib.getExe programConfig.package)

View file

@ -265,7 +265,6 @@ in
name: profile: name: profile:
lib.nameValuePair "colima-${name}" { lib.nameValuePair "colima-${name}" {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
"${lib.getExe cfg.package}" "${lib.getExe cfg.package}"

View file

@ -218,7 +218,6 @@ in
launchd.agents.emacs = { launchd.agents.emacs = {
enable = true; enable = true;
domain = lib.mkDefault (if cfg.startWithUserSession == "graphical" then "gui" else "user");
config = { config = {
ProgramArguments = [ ProgramArguments = [
"${cfg.package}/bin/emacs" "${cfg.package}/bin/emacs"

View file

@ -60,7 +60,6 @@ in
launchd.agents.exo = { launchd.agents.exo = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ (lib.getExe cfg.package) ] ++ cfg.extraArgs; ProgramArguments = [ (lib.getExe cfg.package) ] ++ cfg.extraArgs;
EnvironmentVariables = cfg.environmentVariables; EnvironmentVariables = cfg.environmentVariables;

View file

@ -108,7 +108,6 @@ in
launchd.agents = services ( launchd.agents = services (
_name: repo: { _name: repo: {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
StartInterval = repo.interval; StartInterval = repo.interval;
ProcessType = "Background"; ProcessType = "Background";

View file

@ -87,7 +87,6 @@ in
launchd.agents.glance = mkIf (cfg.package != null) { launchd.agents.glance = mkIf (cfg.package != null) {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
(getExe cfg.package) (getExe cfg.package)

View file

@ -105,7 +105,6 @@ in
launchd.agents.home-manager-auto-expire = { launchd.agents.home-manager-auto-expire = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ (toString script) ]; ProgramArguments = [ (toString script) ];
ProcessType = "Background"; ProcessType = "Background";

View file

@ -65,7 +65,6 @@ let
name = "imapnotify-${name}"; name = "imapnotify-${name}";
value = { value = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
# Use the nix store path for config to ensure service restarts when it changes # Use the nix store path for config to ensure service restarts when it changes
ProgramArguments = [ ProgramArguments = [

View file

@ -254,7 +254,6 @@ in
launchd.agents.mpd = { launchd.agents.mpd = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
(lib.getExe cfg.package) (lib.getExe cfg.package)

View file

@ -121,7 +121,6 @@ in
launchd.agents.nix-gc = { launchd.agents.nix-gc = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
"${nixPackage}/bin/nix-collect-garbage" "${nixPackage}/bin/nix-collect-garbage"

View file

@ -107,7 +107,6 @@ in
launchd.agents.ollama = { launchd.agents.ollama = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
"${lib.getExe ollamaPackage}" "${lib.getExe ollamaPackage}"

View file

@ -311,7 +311,6 @@ in
name: machine: name: machine:
nameValuePair "podman-machine-${name}" { nameValuePair "podman-machine-${name}" {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ "${mkWatchdogScript name machine}" ]; ProgramArguments = [ "${mkWatchdogScript name machine}" ];
KeepAlive = { KeepAlive = {

View file

@ -57,7 +57,6 @@ in
launchd.agents.pueued = lib.mkIf (cfg.package != null) { launchd.agents.pueued = lib.mkIf (cfg.package != null) {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [

View file

@ -105,7 +105,6 @@ in
launchd.agents.ssh-agent = { launchd.agents.ssh-agent = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
(lib.getExe pkgs.bash) (lib.getExe pkgs.bash)

View file

@ -943,7 +943,6 @@ in
launchd.agents = { launchd.agents = {
syncthing = { syncthing = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
"${pkgs.writers.writeBash "syncthing-wrapper" '' "${pkgs.writers.writeBash "syncthing-wrapper" ''

View file

@ -62,7 +62,6 @@ in
launchd.agents.tldr-update = { launchd.agents.tldr-update = {
enable = true; enable = true;
domain = lib.mkDefault "user";
config = { config = {
ProgramArguments = [ ProgramArguments = [
(lib.getExe cfg.package) (lib.getExe cfg.package)

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.git-maintenance-daily</string> <string>org.nix-community.home.git-maintenance-daily</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.git-maintenance-hourly</string> <string>org.nix-community.home.git-maintenance-hourly</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.git-maintenance-weekly</string> <string>org.nix-community.home.git-maintenance-weekly</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.nh-clean</string> <string>org.nix-community.home.nh-clean</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.opencode-web</string> <string>org.nix-community.home.opencode-web</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.opencode-web</string> <string>org.nix-community.home.opencode-web</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.borgmatic</string> <string>org.nix-community.home.borgmatic</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -22,8 +22,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.colima-default</string> <string>org.nix-community.home.colima-default</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -18,8 +18,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.colima-default</string> <string>org.nix-community.home.colima-default</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.emacs</string> <string>org.nix-community.home.emacs</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.git-sync-test</string> <string>org.nix-community.home.git-sync-test</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -18,12 +18,10 @@
serviceFile=$(normalizeStorePaths $serviceFile) serviceFile=$(normalizeStorePaths $serviceFile)
assertFileExists "$serviceFile" assertFileExists "$serviceFile"
assertFileContent "$serviceFile" ${./glance.plist} assertFileContent "$serviceFile" ${./glance.plist}
assertFileContains "$serviceFile" '<key>LimitLoadToSessionType</key>'
assertFileContains "$serviceFile" '<string>Background</string>'
domainFile=LaunchAgentDomains/org.nix-community.home.glance.domain domainFile=LaunchAgentDomains/org.nix-community.home.glance.domain
assertFileContent "$domainFile" ${builtins.toFile "expected-domain" "user\n"} assertFileContent "$domainFile" ${builtins.toFile "expected-domain" "gui\n"}
assertFileContains activate 'domain="user/$(id -u)"' assertFileContains activate 'domain="gui/$(id -u)"'
assertFileContains activate 'launchctl kickstart -k "$domain/org.nix-community.home.glance"' assertFileContains activate 'launchctl kickstart -k "$domain/org.nix-community.home.glance"'
'') '')
]; ];

View file

@ -2,13 +2,13 @@
{ {
services.glance.enable = true; services.glance.enable = true;
launchd.agents.glance.domain = "gui"; launchd.agents.glance.domain = "user";
nmt.script = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin '' nmt.script = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin ''
domainFile=LaunchAgentDomains/org.nix-community.home.glance.domain domainFile=LaunchAgentDomains/org.nix-community.home.glance.domain
assertFileExists "$domainFile" assertFileExists "$domainFile"
assertFileContent "$domainFile" ${builtins.toFile "expected-domain" "gui\n"} assertFileContent "$domainFile" ${builtins.toFile "expected-domain" "user\n"}
assertFileContains activate 'domain="gui/$(id -u)"' assertFileContains activate 'domain="user/$(id -u)"'
assertFileContains activate 'launchctl kickstart -k "$domain/org.nix-community.home.glance"' assertFileContains activate 'launchctl kickstart -k "$domain/org.nix-community.home.glance"'
''; '';
} }

View file

@ -6,8 +6,6 @@
<true/> <true/>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.glance</string> <string>org.nix-community.home.glance</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.home-manager-auto-expire</string> <string>org.nix-community.home.home-manager-auto-expire</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -13,8 +13,6 @@
<true/> <true/>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.imapnotify-hm-example.com</string> <string>org.nix-community.home.imapnotify-hm-example.com</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -4,8 +4,6 @@
<dict> <dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.nix-gc</string> <string>org.nix-community.home.nix-gc</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>
<array> <array>
<string>/bin/sh</string> <string>/bin/sh</string>

View file

@ -20,8 +20,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.ollama</string> <string>org.nix-community.home.ollama</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.podman-machine-podman-machine-default</string> <string>org.nix-community.home.podman-machine-podman-machine-default</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.podman-machine-dev-machine</string> <string>org.nix-community.home.podman-machine-dev-machine</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.ssh-agent</string> <string>org.nix-community.home.ssh-agent</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.ssh-agent</string> <string>org.nix-community.home.ssh-agent</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.ssh-agent</string> <string>org.nix-community.home.ssh-agent</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>

View file

@ -11,8 +11,6 @@
</dict> </dict>
<key>Label</key> <key>Label</key>
<string>org.nix-community.home.syncthing</string> <string>org.nix-community.home.syncthing</string>
<key>LimitLoadToSessionType</key>
<string>Background</string>
<key>ProcessType</key> <key>ProcessType</key>
<string>Background</string> <string>Background</string>
<key>ProgramArguments</key> <key>ProgramArguments</key>