Keep user settings and marketplace registrations writable while applying
declared values. Seed required marketplace metadata only where missing,
preserving saved timestamps and update flags. Retain the immutable
default.
Values in mcpServers are serialized into a generated plugin in the
world-readable Nix store, and the example put database credentials in a
DSN and an environment variable. Remove the credentials from the example
and point local servers at the file-backed programs.mcp.servers
environment values.
The synthesized plugin that delivers managed MCP and LSP configuration to
Claude Code was named `claude-code-home-manager`. Claude Code derives the
MCP tool namespace from the plugin manifest (`plugin.json`), so that name
appeared in the prefix of every plugin-loaded MCP tool
(`mcp__plugin_<name>_<server>__<tool>`), adding 22 characters of overhead per
tool name.
Shorten the manifest name to `hm`, centralizing it in a `generatedPluginName`
binding, so tool prefixes become `mcp__plugin_hm_<server>__<tool>`. The
personal-plugin directory entry keeps the stable `claude-code-home-manager`
name (the path under `~/.claude/skills/`); a short name there would collide
with valid `programs.claude-code.plugins.hm` or `skills.hm` and fail the
uniqueness assertions.
This is a breaking change: users who allow or deny these tools by name in
their settings must update references from `claude-code-home-manager` to
`hm`. A news entry documents the migration.
Closes#9446
Assisted-by: Claude-Code:GLM-5.2
programs.claude-code.hooks previously only accepted inline strings.
It now shares the same either-lines-or-path content option used by
agents, commands, and rules, so a hook script can be referenced from
a file instead of being inlined.
mkSourceEntry used lib.isPath, which does not match derivations such
as pkgs.writeShellScript. Since lib.types.path accepts derivations,
a derivation-backed hook (or agent, command, rule, or output style)
sent the derivation to home.file.*.text and failed evaluation. Use
lib.hm.strings.isPathLike instead, and add a derivation-backed hook
test.
No release-notes entry: other option additions/extensions to this
module (e.g. path support for agents/commands, the rules option
itself) haven't warranted one either.
Claude Code lists a plugin's `agents/` and `commands/` entries with a
`readdir` that accepts only regular files, so symlinked directory entries
are skipped. Managed plugins were linked recursively, which materializes a
real directory holding one symlink per file, and wrapped with
`pkgs.symlinkJoin`, which mirrors directories and symlinks the leaf files.
Both layers dropped every agent and command a plugin provides.
Link each plugin as a single directory symlink, and wrap it with a
`runCommand` that links only top-level entries so component directories stay
symlinks to the original.
Also accept an attribute set for `plugins`, making the personal-plugin
directory name user-controlled and stable rather than derived from the
source's base name, which yields names such as `bxa1s0m3h4sh-source` that
change whenever the plugin is updated. The list form keeps working, with a
warning.
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.