diff --git a/docs/conventions.md b/docs/conventions.md index 5180c6d..9ecc3a8 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -47,7 +47,7 @@ Leave upstream `services.*`, `networking.*`, `home.*`, etc. alone. Aggregates: `nixosModules.system` and `nixosModules.desktop` import their leaves. Host configs import those stacks and set options — they shouldn't reimplement whole subsystems. -**Home** — files under `modules/wisdom/`. Baseline is `homeManagerModules.wisdom` (`chiasson.home.enable`). Everything else is separate exports (`wisdomBrowsersZen`, …); enable on a host via `chiasson.users.extraModules.` and the matching `chiasson.home.*.enable`. +**Home** — files under `modules/wisdom/`. Baseline is `homeManagerModules.wisdom` (`chiasson.home.enable`, wired via `chiasson.desktop.homeManager.bundleWisdom`). Other `wisdom*` slices auto-wire once per user via `lib.wisdomCatalogExtraModules self` (`modules/lib/wisdom-catalog.nix`); hosts only set matching `chiasson.home.*.enable` toggles — no re-import in `home.nix`. User apps / dotfiles → wisdom. Daemons, firewall, kernel → NixOS. Sometimes both (LocalSend: HM installs, `systemLocalsend` opens the firewall). @@ -72,14 +72,36 @@ Passwords aren't in the repo. They're in `secrets/secrets.yaml` (encrypted with On a host: ```nix +# configuration.nix — machine policy chiasson.users.enabled = [ "olivier" ]; chiasson.users.hostOverrides. = { /* optional */ }; -chiasson.users.extraModules.olivier = [ - self.homeManagerModules.wisdomTerminalsKitty - # … -]; ``` +Desktop hosts also have `home.nix` exporting `flake.nixosModules.Home`, wired from `default.nix` alongside `*Configuration`: + +```nix +# default.nix +modules = [ + self.nixosModules."14900kConfiguration" + self.nixosModules."14900kHome" +]; + +# home.nix — flake fragment, per-host `chiasson.home.*` toggles +{ self, inputs, ... }: { + flake.nixosModules."14900kHome" = { self, pkgs, ... }: { + imports = [ self.nixosModules.desktopHomeBase ]; + chiasson.users.extraModules.olivier = [ + { + chiasson.home.browsers.edge.enable = true; + # … + } + ]; + }; +} +``` + +`flake.nixosModules.desktopHomeBase` expands `lib.wisdomCatalogExtraModules` plus shared desktop toggles. Host `*Home` modules append per-host `chiasson.home` overrides (and rare inline `home.packages` blocks). `chiasson.users.extraModules` concatenates lists from multiple modules (base + host), so both can set the same user key. + `usersHomeIntegration` turns that into `users.users` + HM. Don't hand-roll catalog users unless you're changing the users module itself. SSH: `sshInbound` on NixOS, outbound/rbw under `modules/ssh/home-manager/`. @@ -88,11 +110,11 @@ SSH: `sshInbound` on NixOS, outbound/rbw under `modules/ssh/home-manager/`. **New NixOS leaf:** export `flake.nixosModules.whatever`, wire from `system/default.nix` or `desktop/default.nix` if it's global, or only from a host `configuration.nix` if it's not. `nix flake check`. Git-add new paths if eval uses the git tree. -**New HM slice:** export `flake.homeManagerModules.wisdomFoo`, add the file to `imports` in `modules/wisdom/default.nix`, then wire `extraModules` + options on hosts that need it. +**New HM slice:** add `modules/wisdom/.../foo.nix` exporting `flake.homeManagerModules.wisdomFoo` (import-tree picks it up; `wisdomCatalogExtraModules` includes every `wisdom*` export except `wisdom` / `wisdomShellBash`). Gate packages on `chiasson.home.*.enable`, set `mkDefault true` in `desktop-home-base.nix` if shared, or `enable = true` in a host `home.nix`. Upstream HM deps stay imported unconditionally — use `mkIf` on `cfg.enable` for config (never `config`-dependent `imports`; that recurses). **Derivations:** `let` inside a fragment, or `flake.packages` / `flake.lib` — not a bare `mkDerivation` file import-tree will try to load. -**New host:** `hosts//default.nix` with `nixosSystem`, `configuration.nix` exporting `*Configuration`, hardware + `_private/` as needed, register in `modules/deploy/navi.nix` if it should be in the fleet. +**New host:** `hosts//default.nix` with `nixosSystem` listing `*Configuration` (+ `*Home` for desktops), `configuration.nix` exporting `*Configuration`, hardware + `_private/` as needed. Desktop/laptop hosts also get `home.nix` exporting `*Home` (import `self.nixosModules.desktopHomeBase` unless it's a special case). Register in `modules/deploy/navi.nix` if it should be in the fleet. ## When editing diff --git a/modules/desktop/options.nix b/modules/desktop/options.nix index 9ca4803..6d45aff 100644 --- a/modules/desktop/options.nix +++ b/modules/desktop/options.nix @@ -153,7 +153,7 @@ type = lib.types.bool; default = true; description = '' - Add `wisdom` (baseline + bash) to HM `sharedModules`. Other slices still go in per-user `extraModules`. + Add `wisdom` (baseline + bash) to HM `sharedModules`. Per-user `extraModules` should use `lib.wisdomCatalogExtraModules self` once and set `chiasson.home.*.enable`. ''; }; }; diff --git a/modules/desktop/shells/dms/home-manager/default.nix b/modules/desktop/shells/dms/home-manager/default.nix index fe6d5b1..c54399a 100644 --- a/modules/desktop/shells/dms/home-manager/default.nix +++ b/modules/desktop/shells/dms/home-manager/default.nix @@ -123,7 +123,7 @@ in { { # Nix rebuild widget used by DankMaterialShell (via nix-monitor). - # Per-host `rebuildCommand` is set in `hosts/clients//home.nix`. + # Per-host `rebuildCommand` is set in `modules/hosts//configuration.nix` (`chiasson.desktop.shells.dms`). programs.nix-monitor = { enable = true; generationsCommand = [ @@ -1108,6 +1108,12 @@ in { ''; } (lib.mkIf (lib.attrByPath [ "chiasson" "home" "shell" "ohMyPosh" "enable" ] false config) { + # Matugen overwrites this at runtime; seed a stock theme so `oh-my-posh init fish` works before DMS runs matugen. + xdg.configFile."oh-my-posh/theme.omp.json".source = + let + ompTheme = config.chiasson.home.shell.ohMyPosh.builtinTheme or "jandedobbeleer"; + in + "${config.programs.oh-my-posh.package}/themes/${ompTheme}.omp.json"; # Same path as matugen `[templates.ohmyposh]` output in `programs.dank-material-shell` config. programs.oh-my-posh = { useTheme = lib.mkForce null; diff --git a/modules/hosts/14900k/configuration.nix b/modules/hosts/14900k/configuration.nix index 2b6d34e..8da8c14 100644 --- a/modules/hosts/14900k/configuration.nix +++ b/modules/hosts/14900k/configuration.nix @@ -86,8 +86,6 @@ services.cloudflare-warp.enable = true; }; }; - chiasson.system.chromiumHevc.enable = true; - chiasson.system = { ytDlpTelequebecPatch.enable = true; @@ -141,78 +139,5 @@ services.cloudflare-warp.enable = true; }; chiasson.users.enabled = [ "olivier" ]; - - chiasson.users.extraModules.olivier = [ - self.homeManagerModules.wisdomFilebrowsersDolphin - self.homeManagerModules.wisdomTerminalsKitty - self.homeManagerModules.wisdomBrowsersEdge - self.homeManagerModules.wisdomBrowsersFlow - self.homeManagerModules.wisdomBrowsersOrion - self.homeManagerModules.wisdomBrowsersZen - self.homeManagerModules.wisdomBrowsersChromiumHevc - self.homeManagerModules.wisdomEditorsCursor - self.homeManagerModules.wisdomEditorsObsidian - self.homeManagerModules.wisdomShellYazi - self.homeManagerModules.wisdomShellFish - self.homeManagerModules.wisdomShellOhMyPosh - self.homeManagerModules.wisdomAppsDiscord - self.homeManagerModules.wisdomAppsSpotify - self.homeManagerModules.wisdomAppsLocalsend - self.homeManagerModules.wisdomAppsPokeclicker - self.homeManagerModules.wisdomDesktopScreenshot - self.homeManagerModules.wisdomDesktopGtkQtTheming - { - programs.git = { - enable = true; - settings.user = { - name = "OlivierChiasson"; - email = "olivierchiasson@hotmail.fr"; - }; - }; - - chiasson.home = { - extraPackages = [ pkgs.parsec-bin ]; - - shell = { - fish.enable = true; - yazi.enable = true; - ohMyPosh.enable = true; - }; - - terminals.kitty.enable = true; - - filebrowsers.dolphin.enable = true; - - browsers.edge.enable = true; - browsers.flow.enable = false; - browsers.orion.enable = true; - browsers.zen.enable = true; - browsers.chromiumHevc = { - enable = true; - packages = [ "google-chrome" ]; - vaapi.gpu = "intel"; # Chromium + NVIDIA VA-API → frame pool errors in Jellyfin cuz chrome is proprietary rats nests, gecko engine might support NVIDIA VA-API - }; - - editors.cursor.enable = true; - editors.obsidian.enable = true; - - apps = { - discord.enable = true; - spotify.enable = true; - spotify.openDiscoveryFirewall = true; - localsend.enable = true; - pokeclicker.enable = true; - }; - - desktop = { - screenshot = { - enable = true; - swiftshareApiKeyFile = "/run/secrets/swiftshare/API_KEY"; #TODO[epic=sops] redo this by passing sops file output directly - }; - theming.enable = true; - }; - }; - } - ]; }; } diff --git a/modules/hosts/14900k/default.nix b/modules/hosts/14900k/default.nix index a17b24d..76db09d 100644 --- a/modules/hosts/14900k/default.nix +++ b/modules/hosts/14900k/default.nix @@ -9,6 +9,7 @@ }; modules = [ self.nixosModules."14900kConfiguration" + self.nixosModules."14900kHome" ]; }; } diff --git a/modules/hosts/14900k/home.nix b/modules/hosts/14900k/home.nix new file mode 100644 index 0000000..3e4ea1d --- /dev/null +++ b/modules/hosts/14900k/home.nix @@ -0,0 +1,30 @@ +{ self, inputs, ... }: +{ + flake.nixosModules."14900kHome" = + { self, pkgs, ... }: + { + imports = [ self.nixosModules.desktopHomeBase ]; + + chiasson.users.extraModules.olivier = [ + { + chiasson.home = { + extraPackages = [ pkgs.parsec-bin ]; + + browsers = { + edge.enable = true; + orion.enable = true; + zen.enable = true; + }; + + apps = { + discord.enable = true; + spotify.enable = true; + spotify.openDiscoveryFirewall = true; + pokeclicker.enable = true; + }; + + }; + } + ]; + }; +} diff --git a/modules/hosts/desktop-home-base.nix b/modules/hosts/desktop-home-base.nix new file mode 100644 index 0000000..ba42939 --- /dev/null +++ b/modules/hosts/desktop-home-base.nix @@ -0,0 +1,90 @@ +# Shared Home Manager selection for all desktop hosts (14900k, t2mbp, ideapad, uConsole). +# Wisdom slices resolved here (NixOS has `self`); toggles select what actually installs. +{ self, inputs, ... }: +{ + flake.nixosModules.desktopHomeBase = + { self, lib, pkgs, ... }: + { + chiasson.system.chromiumHevc.enable = lib.mkDefault true; + + chiasson.users.extraModules.olivier = + self.lib.wisdomCatalogExtraModules self + ++ [ + ( + { lib, pkgs, ... }: + let + aarch64 = pkgs.stdenv.hostPlatform.isAarch64; + in + { + programs.git = { + enable = lib.mkDefault true; + settings.user = { + name = "OlivierChiasson"; + email = "olivierchiasson@hotmail.fr"; + }; + }; + + chiasson.home = { + # Catalog of `chiasson.home.*` toggles — host `home.nix` sets `enable = true` to override `mkDefault false`. + shell = { + fish.enable = lib.mkDefault true; + ohMyPosh.enable = lib.mkDefault true; + yazi.enable = lib.mkDefault true; + }; + + terminals.kitty.enable = lib.mkDefault true; + + filebrowsers.dolphin.enable = lib.mkDefault true; + + browsers = { + chrome.enable = lib.mkDefault false; + chromiumHevc = { + enable = lib.mkDefault true; + packages = lib.mkDefault ( + if aarch64 then + [ "chromium" ] + else + [ "google-chrome" ] + ); + } // lib.optionalAttrs (!aarch64) { + # Chromium + NVIDIA VA-API → frame pool errors in Jellyfin; gecko may fare better on NVIDIA. + vaapi.gpu = lib.mkDefault "intel"; + }; + edge.enable = lib.mkDefault false; + flow.enable = lib.mkDefault false; + orion.enable = lib.mkDefault false; + zen.enable = lib.mkDefault false; + }; + + editors = { + cursor.enable = lib.mkDefault true; + kate.enable = lib.mkDefault false; + obsidian.enable = lib.mkDefault true; + }; + + apps = { + discord.enable = lib.mkDefault false; + localsend.enable = lib.mkDefault true; + pokeclicker.enable = lib.mkDefault false; + spotify = { + enable = lib.mkDefault false; + openDiscoveryFirewall = lib.mkDefault false; + }; + }; + + desktop = { + screenshot = { + enable = lib.mkDefault true; + swiftshareApiKeyFile = "/run/secrets/swiftshare/API_KEY"; #TODO[epic=sops] redo this by passing sops file output directly + }; + # WhiteSur GTK/icons, Phinger cursor, Qt via KDE platform theme; imports DMS matugen `dank-colors.css`. + theming.enable = lib.mkDefault true; + }; + + hardware.uconsoleGamepad.enable = lib.mkDefault false; + }; + } + ) + ]; + }; +} diff --git a/modules/hosts/ideapad/configuration.nix b/modules/hosts/ideapad/configuration.nix index 0b8cfd4..e2c67fe 100644 --- a/modules/hosts/ideapad/configuration.nix +++ b/modules/hosts/ideapad/configuration.nix @@ -127,67 +127,8 @@ }; - # ─────────────────────── Users / HM ─────────────────────── chiasson.users.enabled = [ "olivier" ]; - # Touch-friendly application set, mirroring uConsole's selection (no heavy IDEs / gaming). - chiasson.users.extraModules.olivier = [ - self.homeManagerModules.wisdomFilebrowsersDolphin - self.homeManagerModules.wisdomTerminalsKitty - self.homeManagerModules.wisdomBrowsersZen - self.homeManagerModules.wisdomEditorsKate - self.homeManagerModules.wisdomEditorsCursor - self.homeManagerModules.wisdomShellFish - self.homeManagerModules.wisdomShellOhMyPosh - self.homeManagerModules.wisdomAppsSpotify - self.homeManagerModules.wisdomAppsLocalsend - self.homeManagerModules.wisdomDesktopScreenshot - { - chiasson.home = { - shell = { - fish.enable = true; - ohMyPosh.enable = true; - }; - terminals.kitty.enable = true; - filebrowsers.dolphin.enable = true; - browsers.zen.enable = true; - editors.kate.enable = true; - editors.cursor.enable = true; - apps.spotify.enable = true; - apps.localsend.enable = true; - desktop = { - screenshot = { - enable = true; - swiftshareApiKeyFile = "/run/secrets/swiftshare/API_KEY"; #TODO[epic=sops] redo this by passing sops file output directly - }; - }; - }; - } - # Tablet-class apps: kept inline rather than promoting to wisdom modules — these aren't - # part of the broader catalog (no use on uConsole / 14900k / servers) and adding a wisdom - # module per single-host package would just be ceremony. If a second tablet host ever - # appears, factor them out then. - # - # NOTE on cameras: no v4l2/libcamera GUI is installed. The Mobile NixOS kernel for - # `lenovo-wormdingler` ships with `CONFIG_VIDEO_QCOM_CAMSS` disabled and no - # `VIDEO_OV*`/`VIDEO_HI*` sensor drivers, so `/dev/video0`-`/dev/video1` only expose - # the Qualcomm Venus codecs (h.264/h.265 enc/dec) and there is no camera source for - # PipeWire / libcamera to pick up. See `_private/CAMERA-TODO.md` for the steps that - # would (potentially) bring the front/rear cameras online — it's a kernel-rebuild + - # device-tree + libcamera project, not a config tweak. - ( - { pkgs, ... }: - { - home.packages = with pkgs; [ - # PDF viewer — fits the existing KDE app set (Dolphin + Kate). - kdePackages.okular - # ePub reader, GTK4, large touch targets. - foliate - ]; - } - ) - ]; - system.stateVersion = "26.05"; }; } diff --git a/modules/hosts/ideapad/default.nix b/modules/hosts/ideapad/default.nix index f974b04..ed83131 100644 --- a/modules/hosts/ideapad/default.nix +++ b/modules/hosts/ideapad/default.nix @@ -9,6 +9,7 @@ }; modules = [ self.nixosModules.ideapadConfiguration + self.nixosModules.ideapadHome ]; }; } diff --git a/modules/hosts/ideapad/home.nix b/modules/hosts/ideapad/home.nix new file mode 100644 index 0000000..6dbc7ba --- /dev/null +++ b/modules/hosts/ideapad/home.nix @@ -0,0 +1,21 @@ +{ self, inputs, ... }: +{ + flake.nixosModules.ideapadHome = + { self, ... }: + { + imports = [ self.nixosModules.desktopHomeBase ]; + + # Host-only HM overrides (tablet apps, toggles off from desktop-home-base, …). + chiasson.users.extraModules.olivier = [ + # { + # chiasson.home = { + # # editors.kate.enable = true; + # }; + # } + # ( + # { pkgs, ... }: + # { home.packages = with pkgs; [ ]; } + # ) + ]; + }; +} diff --git a/modules/hosts/t2mbp/configuration.nix b/modules/hosts/t2mbp/configuration.nix index 150f6f8..57596b7 100644 --- a/modules/hosts/t2mbp/configuration.nix +++ b/modules/hosts/t2mbp/configuration.nix @@ -110,59 +110,6 @@ }; chiasson.users.enabled = [ "olivier" ]; - - chiasson.users.extraModules.olivier = [ - self.homeManagerModules.wisdomFilebrowsersDolphin - self.homeManagerModules.wisdomTerminalsKitty - self.homeManagerModules.wisdomBrowsersZen - self.homeManagerModules.wisdomBrowsersChrome - self.homeManagerModules.wisdomBrowsersEdge - self.homeManagerModules.wisdomEditorsCursor - self.homeManagerModules.wisdomEditorsKate - self.homeManagerModules.wisdomEditorsObsidian - self.homeManagerModules.wisdomShellYazi - self.homeManagerModules.wisdomShellFish - self.homeManagerModules.wisdomShellOhMyPosh - self.homeManagerModules.wisdomAppsDiscord - self.homeManagerModules.wisdomAppsSpotify - self.homeManagerModules.wisdomAppsLocalsend - self.homeManagerModules.wisdomAppsPokeclicker - self.homeManagerModules.wisdomDesktopScreenshot - { - chiasson.home = { - shell = { - fish.enable = true; - yazi.enable = true; - ohMyPosh.enable = true; - }; - - terminals.kitty.enable = true; - filebrowsers.dolphin.enable = true; - browsers = { - zen.enable = false; - chrome.enable = false; - edge.enable = true; - }; - editors = { - cursor.enable = true; - kate.enable = false; - obsidian.enable = true; - }; - apps = { - discord.enable = true; - spotify.enable = false; - localsend.enable = true; - pokeclicker.enable = true; - }; - desktop = { - screenshot = { - enable = true; - swiftshareApiKeyFile = "/run/secrets/swiftshare/API_KEY"; #TODO[epic=sops] redo this by passing sops file output directly - }; - }; - }; - } - ]; }; } \ No newline at end of file diff --git a/modules/hosts/t2mbp/default.nix b/modules/hosts/t2mbp/default.nix index 955eaf8..19dc294 100644 --- a/modules/hosts/t2mbp/default.nix +++ b/modules/hosts/t2mbp/default.nix @@ -9,6 +9,7 @@ }; modules = [ self.nixosModules.t2mbpConfiguration - ]; + self.nixosModules.t2mbpHome + ]; }; } \ No newline at end of file diff --git a/modules/hosts/t2mbp/home.nix b/modules/hosts/t2mbp/home.nix new file mode 100644 index 0000000..206602a --- /dev/null +++ b/modules/hosts/t2mbp/home.nix @@ -0,0 +1,23 @@ +{ self, inputs, ... }: +{ + flake.nixosModules.t2mbpHome = + { self, ... }: + { + imports = [ self.nixosModules.desktopHomeBase ]; + + chiasson.users.extraModules.olivier = [ + { + chiasson.home = { + browsers = { + edge.enable = true; + }; + + apps = { + discord.enable = true; + pokeclicker.enable = true; + }; + }; + } + ]; + }; +} diff --git a/modules/hosts/uConsole/configuration.nix b/modules/hosts/uConsole/configuration.nix index dcabe1b..4ef0cd4 100644 --- a/modules/hosts/uConsole/configuration.nix +++ b/modules/hosts/uConsole/configuration.nix @@ -103,40 +103,6 @@ chiasson.users.enabled = [ "olivier" ]; - chiasson.users.extraModules.olivier = [ - self.homeManagerModules.wisdomFilebrowsersDolphin - self.homeManagerModules.wisdomTerminalsKitty - self.homeManagerModules.wisdomBrowsersZen - self.homeManagerModules.wisdomEditorsKate - self.homeManagerModules.wisdomShellFish - self.homeManagerModules.wisdomShellOhMyPosh - self.homeManagerModules.wisdomAppsSpotify - self.homeManagerModules.wisdomAppsLocalsend - self.homeManagerModules.wisdomDesktopScreenshot - self.homeManagerModules.wisdomHardwareUconsoleGamepad - { - chiasson.home = { - shell = { - fish.enable = true; - ohMyPosh.enable = true; - }; - terminals.kitty.enable = true; - filebrowsers.dolphin.enable = true; - browsers.zen.enable = true; - editors.kate.enable = true; - apps.spotify.enable = true; - apps.localsend.enable = true; - desktop = { - screenshot = { - enable = true; - swiftshareApiKeyFile = "/run/secrets/swiftshare/API_KEY"; #TODO[epic=sops] redo this by passing sops file output directly - }; - }; - hardware.uconsoleGamepad.enable = true; - }; - } - ]; - console.packages = with pkgs; [ terminus_font ]; }; } diff --git a/modules/hosts/uConsole/default.nix b/modules/hosts/uConsole/default.nix index 3c9b3e0..1469989 100644 --- a/modules/hosts/uConsole/default.nix +++ b/modules/hosts/uConsole/default.nix @@ -14,6 +14,7 @@ inputs.oom-hardware.nixosModules.uc.configtxt inputs.oom-hardware.nixosModules.uc.base-cm5 self.nixosModules.uConsoleConfiguration + self.nixosModules.uConsoleHome ]; }; } diff --git a/modules/hosts/uConsole/home.nix b/modules/hosts/uConsole/home.nix new file mode 100644 index 0000000..9f67b2e --- /dev/null +++ b/modules/hosts/uConsole/home.nix @@ -0,0 +1,16 @@ +{ self, inputs, ... }: +{ + flake.nixosModules.uConsoleHome = + { self, ... }: + { + imports = [ self.nixosModules.desktopHomeBase ]; + + chiasson.users.extraModules.olivier = [ + { + chiasson.home = { + hardware.uconsoleGamepad.enable = true; + }; + } + ]; + }; +} diff --git a/modules/lib/wisdom-catalog.nix b/modules/lib/wisdom-catalog.nix new file mode 100644 index 0000000..1b47ed2 --- /dev/null +++ b/modules/lib/wisdom-catalog.nix @@ -0,0 +1,17 @@ +# Resolve `wisdom*` HM slices for NixOS `extraModules` (`self` is not an HM specialArg). +# Slices are gated by `chiasson.home.*.enable`; hosts only flip toggles in `home.nix`. +{ lib, ... }: { + flake.lib.wisdomCatalogExtraModules = + self: + let + names = lib.sort builtins.lessThan ( + lib.filter ( + n: + lib.hasPrefix "wisdom" n + && n != "wisdom" + && n != "wisdomShellBash" + ) (builtins.attrNames self.homeManagerModules) + ); + in + map (name: self.homeManagerModules.${name}) names; +} diff --git a/modules/system/users/catalog-options.nix b/modules/system/users/catalog-options.nix index 1fde545..f629d36 100644 --- a/modules/system/users/catalog-options.nix +++ b/modules/system/users/catalog-options.nix @@ -23,11 +23,24 @@ ''; }; extraModules = lib.mkOption { - type = lib.types.attrsOf (lib.types.listOf lib.types.unspecified); + type = + (lib.types.attrsOf (lib.types.listOf lib.types.unspecified)) + // { + merge = + loc: defs: + let + values = map (d: d.value) defs; + names = lib.unique (lib.concatLists (map builtins.attrNames values)); + in + lib.genAttrs names ( + name: lib.concatLists (map (v: v.${name} or [ ]) values) + ); + }; default = { }; description = '' Per-user Home Manager `extraModules` keyed by catalog user name. - Keys must match `chiasson.users.enabled`. + Keys must match `chiasson.users.enabled`. Lists from multiple modules + are concatenated (e.g. `desktop-home-base.nix` + host `home.nix`). ''; }; homeManager = { diff --git a/modules/wisdom/default.nix b/modules/wisdom/default.nix index fe92f4d..21a2bc1 100644 --- a/modules/wisdom/default.nix +++ b/modules/wisdom/default.nix @@ -10,8 +10,8 @@ ./hardware/uconsole-gamepad.nix ]; - # Root module: chiasson.home.enable + bash. Everything else is separate `wisdom*` exports — - # pull those into `home.users..extraModules` on each host as needed. + # Root module: chiasson.home.enable + bash. Other `wisdom*` slices auto-wire via + # `lib.wisdomCatalogExtraModules`; hosts flip `chiasson.home.*.enable` rather than re-importing. flake.homeManagerModules.wisdom = { config, lib, ... }: let @@ -24,8 +24,8 @@ options.chiasson.home = { enable = lib.mkEnableOption '' - HM profile root for this flake (bash on by default). Wire other `wisdom*` modules in - `home.users..extraModules` and flip their `chiasson.home.*.enable` options on the host. + HM profile root for this flake (bash on by default). Desktop hosts use + `lib.wisdomCatalogExtraModules` once per user and flip `chiasson.home.*.enable` on the host. '' // { default = true; }; diff --git a/modules/wisdom/shells/yazi.nix b/modules/wisdom/shells/yazi.nix index 7cefa76..6c99cb2 100644 --- a/modules/wisdom/shells/yazi.nix +++ b/modules/wisdom/shells/yazi.nix @@ -1,6 +1,5 @@ { ... }: { - # Optional fragment: import from `home.users..extraModules` only on hosts that need Yazi so this - # module (and its `pkgs.yazi` wiring) is not evaluated when omitted. + # Gated by `chiasson.home.shell.yazi.enable` (desktop hosts wire slices via `desktopHomeBase`). flake.homeManagerModules.wisdomShellYazi = { config, lib, pkgs, ... }: let