Commit Graph

9 Commits

Author SHA1 Message Date
Bernardo Magri
bfb80cb60d 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>
2026-07-04 20:44:08 +01:00
Bernardo Magri
18b854563b fix(waybar): supervisor respawn + clean-restart switches; add sys-rebuild
Recovers the crashed iteration #7 (items 21+23, Latitude QA findings):

- nomarchy-waybar supervisor (waybar.nix, exec-once'd from
  hyprland.nix): any waybar exit respawns the bar; crash-loop guard
  (5 fast exits -> critical notify + stop); TERM trapped for a real
  stop. Fixes the bar-less session after a theme-switch crash.
- nomarchy-theme-sync prefers a clean `pkill -x waybar` (supervisor
  restart with fresh config+style) over the crash-prone in-place
  SIGUSR2 reload when the supervisor is running; SIGUSR2 stays as the
  unsupervised fallback.
- sys-rebuild: snapshot-first system rebuild against the CURRENT lock
  (no `nix flake update`) — the no-update twin of sys-update;
  README §3/§5 + motd list it.

Verified: V0 re-run green after crash recovery (flake check --no-build
+ py_compile); V1/V2 per the crashed session's journal entry (HM
renders exec-once=nomarchy-waybar; headless software-GL VM:
SIGKILL -> new pid, clean kill -> respawn, SIGUSR2 -> alive).
V3 pending on the Latitude (queued in HARDWARE-QUEUE.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 18:07:05 +01:00
Bernardo Magri
bc4e8e1410 feat(state): opt-in auto-commit of state mutations (Phase 4)
settings.autoCommit — toggled from System › Auto-commit (self-gated on
the flake being a git repo) — makes every nomarchy-theme-sync apply/set
also git-commit theme-state.json in the downstream flake, so settings
history is `git log`. Off by default.

Design: the flag is live-read by the tool on each write (nothing in Nix
consumes it → instant toggle, no rebuild, no new option); the commit is
pathspec-limited to theme-state.json so unrelated dirty files are never
swept up; it fires when the flag is on before OR after the write, so
the disable-toggle itself lands in history; same-value writes no-op
(diff against HEAD); missing git identity falls back to
Nomarchy <nomarchy@localhost>; `bg next` is deliberately excluded.

Rider fix: `get` now prints booleans JSON-style (true, not Python's
True) — un-sticking the System menu's "Auto timezone (on/off)" label,
whose `= true` comparison could never match. All shell consumers
already normalise true|True, so no other behavior change.

Verified: V0 (py_compile, nix flake check) + V1 (HM generation builds,
generated nomarchy-menu passes bash -n, wiring present in the rendered
script) + a 7-assertion sandbox-repo round-trip covering enable/set/
same-value/disable/post-disable/apply paths and the identity fallback.
Remaining: on-machine check queued in agent/HARDWARE-QUEUE.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 09:12:29 +01:00
Bernardo Magri
685126ab47 feat(nightlight): menu-driven, in-flake on/off (no ~/.local/state)
Night light is off by default and configured entirely through the menu,
writing into the downstream flake instead of ~/.local/state — so the
choice is git-tracked and reproducible across a clone+rebuild.

Two flags under a new settings.* section of the state file (exposed as
the nomarchy.settings option):
- settings.nightlight.installed — sticky, gates the hyprsunset unit;
  nomarchy.nightlight.enable mkDefault-reads it. First enable from the
  menu rebuilds to create the unit (the one accepted rebuild).
- settings.nightlight.on — runtime on/off, toggled instantly
  (theme-sync set --no-switch + systemctl), no rebuild. An ExecCondition
  reads the live flag at session start so an off survives reboot;
  splitting it from the sticky flag means a later unrelated rebuild
  never undoes an instant-off (no decay).

Drops the ~/.local/state/nomarchy/nightlight-off marker and the
ConditionPathExists hack. theme-sync set now skips the wallpaper
re-apply for non-wallpaper keys, and its rebuild notifications are
generic ("changes" not "theme").

First cut of the broader principle — any user-settable config gets a
menu writer that lands it in the flake; no state outside the checkout.
Docs (README §4, ROADMAP, template) updated to reflect it.

Eval- and round-trip-verified; on-hardware check pending.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 20:24:58 +01:00
Bernardo Magri
c2281dbc61 fix(waybar): launch from exec-once, not a systemd user service
Waybar vanished after a logout→login (no reboot): the bar's systemd user
service landed in `failed`. HM's Hyprland integration cycles
hyprland-session.target on every launch (exec-once stop && start), which
re-pulls WantedBy units — including waybar.service — very early, before
Hyprland's IPC socket is ready. Waybar's hyprland/workspaces & window
modules can't connect, so it exits non-zero and is never retried. A cold
boot's extra latency hid the race, so it only bit on warm relogins. The
non-IPC session services (swaync/hypridle/hyprsunset) survive the same
cycling fine, which is why night-light kept working.

Launch waybar from Hyprland's own exec-once instead (systemd.enable =
false). exec-once entries are dispatched once the compositor is up, so the
IPC socket is ready — the same reliable pattern awww-daemon, the wallpaper
sync and the keyboard watcher already use across relogins. Since the unit
no longer exists to be restarted on a home-manager switch, nudge the
running bar to re-read its rebuilt config/style with SIGUSR2 from
nomarchy-theme-sync so theme switches still reapply the bar live.

Found on the Latitude 5410 hardware sweep (systemctl --user status showed
waybar.service loaded/failed; manual start worked).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 19:00:39 +01:00
Bernardo Magri
084b2a0500 feat(theme-sync): persistent switch notification so slow switches read as progress
The "Applying theme — rebuilding…" toast used the default timeout, so it
vanished seconds into a multi-minute home-manager switch — leaving the
user with no signal and the impression the selection failed. Now it's
persistent (timeout 0) and all theme notifications share a synchronous
tag, so swaync REPLACES it in place with "Theme applied ✓" (or a critical
failure toast that persists) when the rebuild finishes.

notify() grew persistent/urgency/summary params. Honest indeterminate
feedback — HM exposes no percentage, so no fake progress bar.

Verified: py_compile clean; the full apply→switch→notify path runs end to
end (dummy NOMARCHY_REBUILD). The in-place replacement is visible only in
a real swaync session.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 15:52:41 +01:00
Bernardo Magri
dccceb4c48 fix: real-hardware QA sweep — wifi, fonts, firmware, Hyprland 0.55, offline switching
Roadmap items 1+2 plus the issues found testing on a Latitude 5410:

- Ship the 10 most popular Nerd Fonts by default (iosevka swapped for
  mononoki: 1.1 GB vs 27 MB) and warn from nomarchy-theme-sync when a
  configured fonts.mono/fonts.ui family isn't installed (fc-match) —
  fontconfig substitutes silently otherwise.
- hardware.enableRedistributableFirmware: installed systems shipped NO
  firmware blobs (wifi/SOF audio/BT) — nixos-generate-config only emits
  microcode lines referencing this flag, it never sets it.
- Live ISO wifi: networking.wireless.enable = mkForce false killed
  NetworkManager's supplicant — since 26.05 the NM module drives its
  wifi backend THROUGH networking.wireless (dbusControlled). Devices
  vanished from nmtui with iwlwifi loaded and no rfkill block.
- Hyprland 0.55: launch sessions via start-hyprland (watchdog; bare
  binary warns), add the new gesture keyword (workspace_swipe is gone —
  touchpads had no gestures at all), media keys via wpctl/bindel/bindl
  plus the missing mic/play/next/prev binds.
- Offline theme switching: pin mustache-go + stdenv + the repo's own
  standalone HM generation (incl. home-files inputDerivation) into the
  ISO — stylix re-renders base16 templates per switch and an offline
  `apply` cascaded into building stdenv from source (1107 drvs).
  Verified with tools/vm/gap-analysis.py: 17 config drvs, zero fetches.
- Stylix: track release-26.05 (kills the HM version-skew warning and
  the stale home-manager follows), lock updated.
- Roadmap: swaync (no notification daemon ships today).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 17:50:55 +01:00
Bernardo Magri
8a0ec763e0 fix: live-VM desktop fixes — Hyprland 0.55 compat + swww→awww rename
Found by booting the live ISO (docs/TESTING.md checklist):
- pin HM configType = "hyprlang" (26.05 stateVersion defaults to the new
  Lua config and renders these settings as broken hl.$mod(...) calls,
  booting Hyprland into emergency mode)
- drop dwindle:pseudotile (removed in Hyprland 0.55; aborts config parse)
- disable splash rendering alongside the logo
- launch awww-daemon and call awww with swww fallback (nixpkgs' swww is
  the renamed awww fork; no `swww` binary exists anymore)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 15:38:32 +01:00
Bernardo Magri
f211ef0d09 feat: Nomarchy ground-up rewrite on NixOS 26.05
Full replacement of the previous iteration, rebuilt around three ideas:

- Pure evaluation: theme-state.json lives inside the flake and is read
  via the nomarchy.stateFile option — no --impure, ever.
- All-Home-Manager theming: `nomarchy-theme-sync apply` writes the JSON
  and runs `home-manager switch`; every theme change is one atomic,
  rollbackable generation. Wallpaper (swww) is the sole runtime piece.
- Flat, downstream-first layout: modules/{nixos,home} with one
  options.nix each, exported as nixosModules/homeModules + overlay +
  flake template; system (nixos-rebuild) and desktop (home-manager
  switch) rebuild paths are fully split.

Ships 21 themes imported from the previous iteration (palettes,
wallpapers, btop themes, six whole-swap Waybar identities), Stylix for
the GTK/Qt/cursor long tail, a live ISO target with offline theme
switching, and docs/TESTING.md with the QEMU verification workflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 10:59:13 +01:00