All checks were successful
Check / eval-and-lint (push) Successful in 6m40s
All three confirmed real on inspection.
1. nomarchy-refresh-config was dead on every system: it read
/etc/nixos/nomarchy/{core/home/config,features} (the source tree never
lands there — only /etc/nomarchy on VM-guest/live ISO) and fell back to
~/.local/share/nomarchy/config, which nothing deployed despite SKILL.md
documenting it. Deploy the pristine core/home/config tree to
~/.local/share/nomarchy/config via xdg.dataFile and read from there, so it
works without a source checkout; its live caller nomarchy-refresh-fastfetch
now succeeds. Fix two stale SKILL.md examples (waybar/, hypr/) that pointed
at non-existent stock paths.
2. nomarchy-docs-scripts shipped a stale divergent copy in
features/scripts/utils/ (in the user nomarchy-system-scripts package)
beside the canonical bin/utils dev tool — it errored outside the repo.
Grounding it surfaced the identical bug in nomarchy-docs-keybindings.
Delete both duplicates, add them to the generator's self-reference
denylist so they don't show as false `missing`, regenerate docs/SCRIPTS.md.
3. Home ~/.config/nomarchy/state.json was never seeded on non-installer
systems, so nomarchy-installed-summary rendered "—" for theme/font/panel.
Add an idempotent home-manager activation seed in core/home/state.nix that
backfills the resolved values (defaults * existing — user choices and
runtime-only keys like welcome_done always win).
Verified: flake check + full eval matrix clean; refresh-config happy/error
paths and the seed deep-merge proven by hand.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
84 lines
4.1 KiB
Nix
84 lines
4.1 KiB
Nix
{ 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 state.json-derived value. Without mkDefault, every
|
|
# option here would resolve at default priority and conflict on
|
|
# assignment from the user's config.
|
|
config = {
|
|
nomarchy = {
|
|
toggles = {
|
|
suspend = lib.mkDefault (togglesState.suspend or schema.home.suspend);
|
|
screensaver = lib.mkDefault (togglesState.screensaver or schema.home.screensaver);
|
|
idle = lib.mkDefault (togglesState.idle or schema.home.idle);
|
|
nightlight = lib.mkDefault (togglesState.nightlight or schema.home.nightlight);
|
|
waybar = lib.mkDefault (togglesState.waybar or schema.home.waybar);
|
|
};
|
|
nightlightTemperature = lib.mkDefault (togglesState.nightlightTemperature or schema.home.nightlightTemperature);
|
|
theme = lib.mkDefault (togglesState.theme or schema.home.theme);
|
|
wallpaper = lib.mkDefault (togglesState.wallpaper or schema.home.wallpaper);
|
|
panelPosition = lib.mkDefault (togglesState.panelPosition or schema.home.panelPosition);
|
|
hyprland = {
|
|
gaps_in = lib.mkDefault (togglesState.hyprland.gaps_in or schema.home.hyprland.gaps_in);
|
|
gaps_out = lib.mkDefault (togglesState.hyprland.gaps_out or schema.home.hyprland.gaps_out);
|
|
border_size = lib.mkDefault (togglesState.hyprland.border_size or schema.home.hyprland.border_size);
|
|
};
|
|
fonts.monospace = lib.mkDefault (togglesState.font or schema.home.font);
|
|
|
|
# Derived properties from the theme directory
|
|
isLightMode = lib.mkDefault (nomarchyLib.isThemeLightMode {
|
|
themeName = togglesState.theme or schema.home.theme;
|
|
inherit assetsPath;
|
|
});
|
|
iconsTheme = lib.mkDefault (nomarchyLib.getIconsTheme {
|
|
themeName = togglesState.theme or schema.home.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}
|
|
'';
|
|
};
|
|
}
|