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.
podman pulls in vfkit on darwin, which fails to build on
aarch64-darwin with the current nixpkgs pin (cctools ld crashes
with 'Trace/BPT trap: 5'). The podman darwin tests reference the
real package through the machine watchdog script, establishing a
build dependency. Stub it on darwin test runs.
Both fail to build on aarch64-darwin with the current nixpkgs pin
(cctools ld crashes with 'Trace/BPT trap: 5'): gurk-rs directly, and
vfkit as a colima dependency. Stub them on darwin test runs.
Move public option declarations and file-entry helpers into dedicated files while keeping module assembly in default.nix. Update the AI labeler for the new module directory.
Persist managed plugins in Claude Code's personal skills directory so strict-parser subcommands do not receive injected --plugin-dir arguments. Retain version-gated legacy behavior for older and unversioned packages.
Follow up on home-cursor: remove legacy enable by preserving the implicit enable path that was not covered by the earlier deprecation warning.
Configurations that set home.pointerCursor without top-level enable now continue to work and emit a warning asking users to set home.pointerCursor.enable explicitly.
yubikey-agent triggers OS-level CCID/PIV PIN entry dialogs when SSH
authentication is requested. These system security prompts require
access to the macOS Aqua session (window server). Running in the user
domain (LimitLoadToSessionType=Background) blocks these prompts,
causing authentication to fail or hang.
Revert to the default gui domain so PIN prompts can render in the
graphical login session.
gpg-agent is commonly configured with graphical pinentry programs
(pinentry-mac, pinentry-gnome3) on macOS that need access to the Aqua
session to display passphrase prompts. Running in the user domain
(LimitLoadToSessionType=Background) prevents these prompts from
rendering, causing passphrase entry to fail silently or hang.
Revert to the default gui domain so the agent runs in the graphical
login session where pinentry can interact with the window server.
Detect active fzf and history-manager Ctrl-R bindings by their configured values, warn with the winning precedence, and let the normal binding options silence the warning.
Pure Nushell sessions do not source hm-session-vars, so feed the same FZF_* values through programs.nushell.environmentVariables before sourcing fzf integration.
Move widget settings under nested option groups while preserving behavior through rename aliases, and centralize FZF environment variable rendering for later reuse.
fzf 0.48.0 embeds shell integration scripts, so keep only the supported fzf --bash, --zsh, and --fish paths and assert that integrations use a new enough package.
Source the Nushell integration at order 2000 so fzf can keep chaining carapace at mkAfter while Atuin still wins Ctrl-R like it does in other shells.
Users who used programs.nushell.extraConfig = lib.mkAfter ... to beat Atuin now need lib.mkOrder 2001 or later.
User-domain agents need the Background session type to bootstrap into user/501, and activation should fail rather than silently unloading services when launchctl bootstrap fails.
Importing <nixpkgs> tied extraction to the caller's NIX_PATH. When that
channel lacks a maintainer referenced through `with lib.maintainers`
(such as sherlock's `_74k1`, which exists in the locked nixpkgs but not
in an older channel), evaluation fails outright and the generated list
varies by machine. Resolve nixpkgs from flake.lock so extraction matches
what Home Manager builds with.
Also classify maintainers by identity (github/name) rather than attribute
name so renamed entries like `_9p4` still match, and correct the
arguments passed to the manual derivation so its maintainer is collected.
`pkgs.formats.toml` escapes backslashes and cannot emit raw control
characters, so key-binding `chars` written as escape text (e.g.
"\uXXXX" or the "\^[" caret form) ended up as invalid literals in the
generated config. Rewrite each escape to a placeholder before
generation and restore it to "\u" afterward.
Use `builtins.split` so escapes are handled anywhere in the value,
including when repeated or mixed with other text.
Filtering disabled shared servers out of `.mcp.json` (#9457) collapsed
"present but disabled" and "absent" into the same output, so a server
set
`enabled = false` for OpenCode could no longer remain present in Claude
Code. `.mcp.json` has no per-server `enabled` field, but settings.json
does via `disabledMcpjsonServers`.
Keep disabled servers in `.mcp.json` and list them under
`disabledMcpjsonServers` (merged with any user-set value). This honors
the
disabled intent without dropping the server, and covers both shared and
Claude Code-native servers.
GitHub Actions runners lack a reusable /nix/store, so rendering the full
manual, options JSON, and manpages on every docs PR pays that cost
uncached. buildbot has a persistent store, so expose the docs outputs
there instead and leave the GHA docs step at the lightweight maintainers
check.
Program and service modules are auto-imported now, so contributor docs should point platform-specific work at guarded module behavior and tests instead of loadModule.
Document the extra module arguments, shared modules hook, and NixOS activation modes so embedded Home Manager setup matches the current integration code.
Checkout v7 blocks fork PR head checkouts in pull_request_target workflows, so keep backport on the trusted base checkout and let the backport action fetch PR commits itself.
Setting `qt.platformTheme.name = "gtk"` silently rewrote the
QT_QPA_PLATFORMTHEME session variable to `gtk2` and pulled in the
qtstyleplugins and qt6gtk2 packages, which is not what users asked for
and relies on unmaintained packages. There is no `gtk` Qt platform
theme, so `gtk` now maps to Qt's built-in `gtk3` platform-theme plugin
and installs no extra packages.
Users who want the previous behavior can set
`qt.platformTheme.name = "gtk2"` explicitly, which keeps
QT_QPA_PLATFORMTHEME=gtk2 and installs qtstyleplugins and qt6gtk2. The
`qt.useGtkTheme` -> `qt.platformTheme` migration now maps the legacy
option to `{ name = "gtk2"; }` so existing configs are unaffected.
Fixes#8663
broot 1.51 renamed the printed nushell entry point from `br` to `main`,
intended to be loaded with `use` where the command takes the module's
name. Home Manager sources the snippet with `source`, so it began
defining a global `main` instead of `br`, breaking the `br` command in
nushell.
Rewrite the definition line back to `br` for the nushell shell function
so `source` keeps exposing `br` globally. Other shells are unaffected.
Fixes#9392
Add ruff to the tree formatter so Python sources are kept consistently
formatted by 'nix fmt' and the CI format check. Test fixtures under
tests/modules are excluded since some are intentionally invalid Python.
Reformats the existing lib/python and tests scripts accordingly.
Reject globalExtensions when Home Manager has no browser-managed policy
carrier. This follows up the global extension policy work with a clear
failure mode, a regression test, and a news entry so affected users know
how to fix package = null setups.
Codex 0.134.0 stopped reading profile settings from [profiles.<name>] in config.toml and no longer supports the top-level profile selector.
Add a dedicated programs.codex.profiles option so Home Manager can write CODEX_HOME/<name>.config.toml files that match the current CLI --profile behavior. For Codex 0.134.0 and later, legacy programs.codex.settings.profiles entries are migrated into profile files with a warning, and removed legacy profile keys are omitted from config.toml so strict config loading keeps working. Older Codex versions keep the legacy config shape.
Use the shared DAG-aware JSON generator for programs.opencode.settings so order-sensitive permission rules can be expressed with lib.hm.dag entries.
Add a focused NMT test for last-match-wins permission output and news for existing opencode users.
Add reusable Home Manager generator helpers for rendering freeform attrsets that contain lib.hm.dag entries.
This keeps ordering support available to JSON and future generated formats without forcing each module to carry its own DAG sorting boilerplate.
Splitting git diff tools into the separate programs.difftastic module
made it impossible to register difftastic as a git difftool without also
forcing it as diff.external, since the boolean git.diffToolMode only
toggled between "external" and "external + difftool".
Replace git.diffToolMode with a git.mode enum ("external", "difftool",
"both") so difftastic can be wired as the difftool only, leaving
`git diff` untouched. The deprecated boolean is migrated automatically
via mkChangedOptionModule (true -> "both", false -> "external"),
preserving existing behavior.
Fixes#8592
The SMTP, identity, and profile pref sets were combined with linear foldl'
of //. mergeAttrsList performs the equivalent right-biased shallow merge and
scales with the account/address count without quadratic recopies.
Per-account rc files were combined with a linear foldl' of //. mergeAttrsList
is the equivalent shallow merge without the quadratic accumulator recopy.
The GOPATH src symlinks were combined with a linear foldl' of //.
mergeAttrsList is the equivalent shallow merge and scales with the package
count without quadratic recopies.
Per-account config files were combined with a linear foldl' of //.
mergeAttrsList performs the equivalent shallow merge without the quadratic
accumulator recopy.
The native-messaging host files were combined with a linear foldl' of //,
which recopies the accumulator on every step (O(n^2)). mergeAttrsList does
the same right-biased shallow merge with a balanced binary merge.
profilesIni folded recursiveUpdate over the profile list with the
non-strict foldl, building a thunk chain over the growing accumulator.
Use the strict foldl'.
generatedConfigs built its list with a non-strict foldl that appended via
acc ++ [ p.config ], an O(n^2) pattern. Filtering out null configs and
mapping is equivalent, order-preserving, and avoids the repeated list
copies.
toHyprconf' tested every important prefix with a non-strict foldl that
always scanned the full list. lib.any expresses the same any-prefix-matches
intent and stops at the first match. Runs once per attribute in the
Hyprland generator.
The local makeBinPath helper reimplemented lib.makeBinPath with a
non-strict foldl accumulator. Use the stdlib function instead: it is
strict and removes the duplicated logic.
The generated script calls the separate `usage` CLI at completion time,
so add `pkgs.usage` to `home.packages` whenever mise is installed.
Stub it on Darwin test runs via `tests/darwinScrublist.nix`.
The bash integration previously only ran `mise activate bash`, so tab
completion for `mise` was never set up. Source the generated completion
script via `mise completion bash --include-bash-completion-lib`; the
flag self-bundles the bash-completion helpers so it also works on
systems whose bash-completion predates `_comp_initialize`.
Fixes#8539
The skills folder deployment path has been updated to
'~/.gemini/antigravity-cli/skills/' to align with the application's
configuration path structure from docs. I think the other path is just a
weird compatibility shim that app supports. strace shows it will search
it, but it also checks the documented path.
programs.vscode.profiles.<name>.userSettings accepts either JSON settings or a path to a settings.json file. The update-check defaults were merged into userSettings before deciding whether to generate JSON or link a source file, so path values failed when Nix tried to apply // to them.
Skip those merges for path-like values and use the shared isPathLike helper for VS Code's source-or-generated JSON options so Nix paths, store path strings, and derivation outputs are handled consistently.
Fixes#7726
The link to `#opt-sshAuthSock.enable` broke the manual build on
release-26.05, where the `enable` option does not exist. Drop the
broken reference and the inaccurate "enabled and" wording.
Evaluate `nixpkgs-disabled.nix` standalone (the harness always loads the
real `nixpkgs.nix`) to verify the warning and assertion report the offending
`nixpkgs.config`/`nixpkgs.overlays` definition locations.
Surface the files that defined `nixpkgs.config`/`nixpkgs.overlays` in the
`useGlobalPkgs` warning and assertion, so users can find what set them
without inspecting `options.*.files` in the repl.
The news section told module contributors they did not need to add a
news entry because the merger would create one, contradicting the
earlier instruction to use the create-news-entry generator. Point
contributors at the generator so new modules ship with their own entry.
Replace the piecemeal assertFileRegex checks with a single
assertFileContent against the normalized unit, so the test pins the
entire generated service file rather than a handful of lines.
Nushell abbreviations are regular config settings, so users can already express them through programs.nushell.settings.abbreviations. Keep test coverage on that native path instead of maintaining a second option.
PR #9420 added set-SSH_AUTH_SOCK.service and ordered it before sshAuthSock.systemd.socketProviderUnit. When that provider is a socket unit, systemd default dependencies already order the socket before sockets.target while service defaults place set-SSH_AUTH_SOCK.service after basic.target. That creates a sockets.target -> basic.target -> set-SSH_AUTH_SOCK.service -> provider.socket -> sockets.target cycle.
For gpg-agent this makes systemd drop gpg-agent-ssh.socket, leaving SSH_AUTH_SOCK pointing at the expected S.gpg-agent.ssh path but with no socket listening there.
Only order and install the environment service against non-socket providers. Socket providers still get SSH_AUTH_SOCK imported through default.target.
Fixes#9432.