--- name: nix-module description: 'Create or update a NixOS or Home Manager module following Nix-Vibe conventions. Use when adding a new service, desktop app, hardware support, or shared configuration module. Use when the user asks to add a package, service, or application module.' argument-hint: ' [service|desktop|hardware|core]' --- # Nix Module Creation ## When to Use - Adding a new service (e.g., a new containerized app, daemon, or web service) - Adding a new desktop application module - Adding hardware support (e.g., new device driver, firmware) - Creating a new shared core module - The user asks to "add support for X" or "create a module for X" ## Module Pattern All service/feature modules MUST follow this pattern: ```nix { config, pkgs, lib, ... }: { options.services. = { enable = lib.mkEnableOption "description of the service"; # Additional options as needed }; config = lib.mkIf config.services..enable { # Configuration here }; } ``` Reference implementation: [modules/services/immich.nix](../../modules/services/immich.nix) ## Procedure ### 1. Determine Module Type | Type | Directory | Example | |------|-----------|---------| | Service (daemon, container, webapp) | `modules/services/` | immich, jellyfin, ntfy | | Desktop app | `modules/desktop/apps/` | soundux, opencode, freeshow | | Desktop environment | `modules/desktop/` | gnome.nix, gui.nix | | Hardware support | `modules/hardware/` | fingerprint.nix | | Core system config | `modules/core/` | common.nix, settings.nix, fonts.nix | ### 2. Create the Module File #### Service Module Template ```nix { config, pkgs, lib, ... }: { options.services. = { enable = lib.mkEnableOption ""; port = lib.mkOption { type = lib.types.port; default = ; description = "Port for "; }; # Add data directories, user config, etc. as needed }; config = lib.mkIf config.services..enable { # Service-specific configuration # For stateful services, ensure data directories exist systemd.tmpfiles.rules = [ "d /var/lib/ 0700 -" ]; # Open firewall if needed networking.firewall.allowedTCPPorts = [ config.services..port ]; }; } ``` #### Desktop App Module Template ```nix { pkgs, ... }: { environment.systemPackages = with pkgs; [ ]; } ``` ### 3. Register in Host Configuration Import the module in the target host's `configuration.nix`: ```nix imports = [ # ...existing imports... ../../modules/services/.nix ]; ``` Then enable it: ```nix services..enable = true; ``` ### 4. Update README.md Add the new software to the Software Inventory table with the appropriate host columns. ### 5. Validate Run the full validation workflow. See [nix-flake-rebuild](../nix-flake-rebuild/SKILL.md). ## Key Conventions ### Secrets Never hardcode secrets. Use SOPS: ```nix sops.secrets."/" = { owner = ""; group = "users"; mode = "0440"; }; ``` See [docs/sops-secrets.md](../../docs/sops-secrets.md) for details. ### Overlay Awareness - If a package needs NVIDIA/CUDA or NDI, it should only be added to `x1carbon` (the only host using the full `overlays` set) - Desktops/laptops use `desktopOverlays` (`stable` without CUDA); servers use `serverOverlays` ### Module Composition - Core modules (`modules/core/common.nix`) apply to ALL hosts - Desktop modules only apply to GUI hosts - Service modules are imported per-host as needed