refactor(#107): theme-state.json → state.json, theme-sync → state-sync
Some checks failed
Check / eval (push) Has been cancelled

The machine flake's git-tracked settings file is system state, not
"theme" only — rename it to state.json. CLI becomes nomarchy-state-sync
with a nomarchy-theme-sync symlink for scripts and muscle memory.

Eval (mkFlake, doctor, lifecycle) still accepts theme-state.json; the
next write migrates to state.json and removes the legacy file.
Documented in MIGRATION.md; drop the CLI alias after release notes.
This commit is contained in:
2026-07-15 11:26:59 +01:00
parent 013403deb4
commit d8e1a13d50
62 changed files with 463 additions and 369 deletions

View File

@@ -1,10 +1,10 @@
# Nomarchy theming engine.
#
# nomarchy.stateFile (theme-state.json, inside the consuming flake) is
# nomarchy.stateFile (state.json, inside the consuming flake) is
# ingested at evaluation time — pure, because flake files are store
# paths — and exposed to every other module as `config.nomarchy.theme`.
#
# Theme changes are fully Home Manager managed: `nomarchy-theme-sync
# Theme changes are fully Home Manager managed: `nomarchy-state-sync
# apply <theme>` writes the JSON and runs `home-manager switch`, baking
# everything (Hyprland, Waybar, Kitty, btop, Stylix) into one
# read-only generation. No runtime patching, no partial states; theme
@@ -13,17 +13,17 @@
# The one runtime exception is the wallpaper (swww is imperative by
# nature): applied at session start, after every switch (hook below), and
# after output hotplug (hyprland.nix); cycled instantly with
# `nomarchy-theme-sync bg next`.
# `nomarchy-state-sync bg next`.
{ config, lib, pkgs, ... }:
let
cfg = config.nomarchy;
# Fail-closed load: missing / empty / non-object get a short pointer at
# the template + `nomarchy-theme-sync validate`, not a raw readFile stack
# the template + `nomarchy-state-sync validate`, not a raw readFile stack
# from deep inside a consumer (nightlight, hyprland, …). Field-level
# checks below still run on the merged result.
themeState = import ../theme-state-read.nix { inherit lib; } cfg.stateFile;
themeState = import ../state-read.nix { inherit lib; } cfg.stateFile;
# Defaults guarantee evaluation succeeds on a sparse or older state
# file (e.g. one written before a schema field was added). The shipped
@@ -92,7 +92,7 @@ let
parsed = lib.recursiveUpdate defaults themeState;
# ── Friendly eval-time validation ───────────────────────────────────
# The same schema nomarchy-theme-sync enforces before every write. A
# The same schema nomarchy-state-sync enforces before every write. A
# HAND-edited state file (the one path that bypasses the tool) must
# fail with the field, the problem, and the fix — not a Nix stack
# trace deep in some consumer. Checks run on `parsed` (after the
@@ -137,14 +137,14 @@ let
if problems == [ ] then parsed
else throw ''
Nomarchy: your theme-state.json is invalid:
Nomarchy: your state.json is invalid:
${lib.concatMapStrings (p: " ${p}\n") problems}
Fix the named field(s) in the theme-state.json of your flake
checkout (usually ~/.nomarchy/theme-state.json the store copy at
Fix the named field(s) in the state.json of your flake
checkout (usually ~/.nomarchy/state.json the store copy at
${toString cfg.stateFile} is a snapshot of it). The tool prints
the same report with per-field fixes: `nomarchy-theme-sync
the same report with per-field fixes: `nomarchy-state-sync
validate`. Re-applying any preset resets all appearance fields:
`nomarchy-theme-sync apply boreal`.'';
`nomarchy-state-sync apply boreal`.'';
# A border value is a palette key (look it up in colors) unless it's
# already a literal hex. Unknown roles are rejected by the field checks
@@ -155,7 +155,7 @@ let
Nomarchy: border role "${v}" is not in the palette (colors.*).
Use one of: ${lib.concatStringsSep ", " colorRoles}
or a literal "#RRGGBB". Validate with: nomarchy-theme-sync validate'');
or a literal "#RRGGBB". Validate with: nomarchy-state-sync validate'');
border = {
active = resolveColor checked.border.active;
inactive = resolveColor checked.border.inactive;