{ config, lib, pkgs, ... }: let nomarchyLib = import ../../lib { inherit lib; }; # Single source of truth for default values when state.json is missing # a key. Both core/system/options.nix and core/home/options.nix read # from this same file — changing a default in one place updates # everywhere. (Was: each consumer hardcoded its own `or X` literal, # which is how the summer-night/nord split lived for so long.) schema = import ../../lib/state-schema.nix { inherit lib; }; assetsPath = ../../themes/palettes; # Read unified state from ~/.config/nomarchy/state.json togglesState = nomarchyLib.readHomeState config.home.homeDirectory; cfg = config.nomarchy; # The resolved values, in state.json's on-disk shape. Seeded into the file # so runtime consumers (nomarchy-installed-summary, the setters) see the # real defaults instead of a missing key — without this the summary shows # "—" for theme/font/panel on any system the installer didn't write to. seedJSON = builtins.toJSON { inherit (cfg) theme wallpaper panelPosition nightlightTemperature; font = cfg.fonts.monospace; inherit (cfg.toggles) suspend screensaver idle nightlight waybar; inherit (cfg.hyprland) gaps_in gaps_out border_size; }; stateFile = "${config.home.homeDirectory}/.config/nomarchy/state.json"; in { # Every assignment uses lib.mkDefault so a downstream /etc/nixos/home.nix # can override the value. The Nix options are now the declarative source # of truth. state.json is purely seeded to keep runtime scripts (menu, # summary) in sync with the Nix-level state. config = { nomarchy = { # Derived properties from the theme directory isLightMode = lib.mkDefault (nomarchyLib.isThemeLightMode { themeName = cfg.theme; inherit assetsPath; }); iconsTheme = lib.mkDefault (nomarchyLib.getIconsTheme { themeName = cfg.theme; inherit assetsPath; }); }; # Backfill any state.json key the user hasn't set. Existing values always # win (`defaults * existing`), so a user's theme/font/etc. and any # runtime-only keys (welcome_done, …) are never clobbered — this only # fills the gaps so the file reflects the system's actual defaults. home.activation.seedNomarchyState = lib.hm.dag.entryAfter [ "writeBoundary" ] '' run mkdir -p "$(dirname ${lib.escapeShellArg stateFile})" tmp="$(${pkgs.coreutils}/bin/mktemp)" # Build the next file contents in $tmp first; only the final move is # guarded by `run` so a dry-run never mutates the real state file. if [ -e ${lib.escapeShellArg stateFile} ]; then ${pkgs.jq}/bin/jq -n --argjson d ${lib.escapeShellArg seedJSON} \ --slurpfile s ${lib.escapeShellArg stateFile} '$d * $s[0]' > "$tmp" else printf '%s\n' ${lib.escapeShellArg seedJSON} > "$tmp" fi run mv "$tmp" ${lib.escapeShellArg stateFile} ''; }; }