feat(state): validation + friendly errors on both write and eval paths (item 11)
All checks were successful
Check / eval (push) Successful in 2m56s

'Never has to master Nix' includes the error messages. The tool grows
validate_state (appearance schema = hard errors; settings.* and
unknown keys = warnings so menu writers and newer schemas keep
working), a read-only `validate` subcommand, and validation BEFORE
every write — an invalid set/apply is refused with the on-disk file
untouched. JSON syntax errors now say line, column, and fix. theme.nix
enforces the same schema at eval time (on the post-defaults state, so
sparse/older files still evaluate) and throws a message naming each
field, its got-value, and the fix paths — the hand-edit escape hatch
no longer ends in a Nix stack trace. Doctor's JSON fix-text points at
validate.

V1: new checks.theme-sync-validate fixture corpus green (good state,
trailing comma, bad hex, bad type, unknown key, refused set with
byte-identical file); negative mkFlake eval of a broken scratch
downstream shows the friendly throw; good-path template-home builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-07-04 20:44:08 +01:00
parent 352c681f48
commit bfb80cb60d
6 changed files with 291 additions and 14 deletions

View File

@@ -26,15 +26,6 @@ next, in what order*.
## NEXT
### 11. State-file validation & friendly errors
New; "the user never has to master Nix" must include *error messages*.
A hand-edited theme-state.json (trailing comma, wrong type, unknown
theme slug) today surfaces as a raw Nix eval stack. Add (a) `nomarchy-
theme-sync validate` + validate-before-write on every set/apply; (b) an
eval-time schema assertion in `theme.nix` whose message says the field,
the problem, and the fix in plain language. **Verify:** V1 + a corpus of
broken-state fixtures round-tripped through validate; V2 if cheap.
### 12. Screen recording in the Capture submenu
New; screenshots ship, recording doesn't — a standard workstation need.
Extend `nomarchy-menu capture`: record region/full → `wl-screenrec`