From c44616aeb00154618fb17fa8162051eb728e7099 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Fri, 10 Jul 2026 21:34:56 +0100 Subject: [PATCH] =?UTF-8?q?feat(autotheme):=20#79=20slice=202=20=E2=80=94?= =?UTF-8?q?=20systemd=20timer=20runs=20`auto`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit modules/home/autotheme.nix installs a user service + timer (nomarchy-auto-theme) that periodically runs `nomarchy-theme-sync auto`, so the day/night theme is applied on the current schedule through the same one engine. Install gates on settings.autoTheme.enable (read from state, the way updates.nix gates on its enable), so a machine not using the feature carries no timer. Timer: OnStartupSec=1min (settle after login) + OnCalendar=*:0/15 + Persistent (catch a transition missed while off). Periodic rather than exact sunrise/sunset timers — robust to suspend/DST, and `auto` is idempotent (no rebuild unless the theme must change) so ticks are cheap. Verification: V1 — real-config eval (state temporarily enabled, then restored) confirms the units land when enabled (OnCalendar *:0/15, ExecStart `... nomarchy-theme-sync auto`) and are absent when disabled; systemd-analyze validates the schedule. V0 flake check green. The live timer -> home-manager switch on a real Nomarchy session is pending a Nomarchy machine (same blocker as #76). Co-Authored-By: Claude Opus 4.8 --- agent/BACKLOG.md | 12 +++++++++--- agent/JOURNAL.md | 20 ++++++++++++++++++++ modules/home/autotheme.nix | 36 ++++++++++++++++++++++++++++++++++++ modules/home/default.nix | 1 + 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 modules/home/autotheme.nix diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index c3cfb60..35425f4 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -39,9 +39,15 @@ Auto light/dark theme switch through the **existing** engine (a timer runs `--which` prints the decision, `--force`/`--no-switch` too. `cmd_apply` core factored into `apply_named` (behavior unchanged). V1 + functional tests (day/night/disabled/missing-slugs, apply writes state, idempotent). -2. **Timer/hook** — systemd user timers at sunrise+sunset running - `nomarchy-theme-sync auto`, gated on `settings.autoTheme.enable`; apply - the correct theme at session start too. V2 (runNixOSTest). +2. ~~**Timer/hook**~~ ✓ shipped 2026-07-10 — `modules/home/autotheme.nix`: + `systemd.user.{service,timer}.nomarchy-auto-theme`, install gated on + `settings.autoTheme.enable` (read from state), `OnStartupSec=1min` + + `OnCalendar=*:0/15` + `Persistent`. Chose periodic (not exact + sunrise/sunset timers) — robust to suspend/DST, and `auto` is idempotent + so ticks are cheap. V1: real-config eval shows units land when enabled + (OnCalendar `*:0/15`, ExecStart `… auto`), absent when disabled; + systemd-analyze validates the schedule. **Real-session check pending** + (live timer→`home-manager switch`) — needs a Nomarchy machine, like #76. 3. **Menu** — Look & Feel › Auto theme: enable/disable, pick day/night themes, set times. Writes state. diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index f9f3b78..0e84403 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,26 @@ Template: --- +## 2026-07-10 — #79 slice 2: auto-theme systemd timer +- **Task:** BACKLOG #79 slice 2 — the timer/hook. +- **Did:** `modules/home/autotheme.nix` (imported in home default.nix): + `systemd.user.{service,timer}.nomarchy-auto-theme`, install gated on + `config.nomarchy.settings.autoTheme.enable or false` (state-driven, like + updates.nix gates on its enable). Service runs `nomarchy-theme-sync auto` + with a PATH for `home-manager`; timer `OnStartupSec=1min` + + `OnCalendar=*:0/15` + `Persistent`. Chose periodic over exact + sunrise/sunset timers — robust to suspend/DST, and `auto` is idempotent so + ticks are cheap (rebuild only at the transition). +- **Verified:** **V1** — real-config eval (state temp-enabled, restored): + `settings.autoTheme.enable`→true, timer `OnCalendar`=`*:0/15`, service + ExecStart=`… nomarchy-theme-sync auto`; disabled→no units (isolation eval + condition=false). `systemd-analyze calendar '*:0/15'` valid. **V0** flake + check green. (Gotcha: a new .nix file is invisible to the flake until + `git add` — flake eval only sees tracked files.) +- **Pending:** live timer→`home-manager switch` on a real Nomarchy session + (needs a Nomarchy machine, like #76). Slice 3 (menu) next. +- **Next suggestion:** #79 slice 3 — Look & Feel › Auto theme menu. + ## 2026-07-10 — #79 slice 1: auto time-of-day theme CLI primitive - **Task:** Split BACKLOG #79 (`VISION § D`, `[big]`) into 3 slices (CLI / timer / menu); took slice 1. diff --git a/modules/home/autotheme.nix b/modules/home/autotheme.nix new file mode 100644 index 0000000..a346c82 --- /dev/null +++ b/modules/home/autotheme.nix @@ -0,0 +1,36 @@ +# Auto time-of-day theme switch (BACKLOG #79, VISION § D). A user timer +# periodically runs `nomarchy-theme-sync auto`, which reads +# settings.autoTheme = { enable, day, night, sunrise, sunset } from the +# state file and applies the day or night preset for the current clock — +# through the SAME one engine as a manual `apply` (no second pipeline). +# +# The command self-gates (no-op when disabled) and is idempotent (it only +# rebuilds when the active theme actually needs to change), so the timer +# can tick freely. Install is gated on the state flag (like nomarchy.updates +# gates on its enable), so a machine not using the feature carries no timer; +# enabling it from the menu (slice 3) writes the flag + rebuilds, which is +# what brings the timer into being. +{ config, lib, pkgs, ... }: + +lib.mkIf (config.nomarchy.settings.autoTheme.enable or false) { + systemd.user.services.nomarchy-auto-theme = { + Unit.Description = "Apply the day/night theme for the current time"; + Service = { + Type = "oneshot"; + # The rebuild (`home-manager switch`) and its tools resolve from the + # system + per-user profiles — same PATH shape nomarchy-updates uses. + Environment = "PATH=/run/current-system/sw/bin:/etc/profiles/per-user/${config.home.username}/bin"; + ExecStart = "${pkgs.nomarchy-theme-sync}/bin/nomarchy-theme-sync auto"; + }; + }; + + systemd.user.timers.nomarchy-auto-theme = { + Unit.Description = "Periodic day/night theme check"; + Timer = { + OnStartupSec = "1min"; # settle on the right theme shortly after login + OnCalendar = "*:0/15"; # re-check every 15 min; auto no-ops if unchanged + Persistent = true; # catch a transition missed while powered off + }; + Install.WantedBy = [ "timers.target" ]; + }; +} diff --git a/modules/home/default.nix b/modules/home/default.nix index 2159a37..7c53bbc 100644 --- a/modules/home/default.nix +++ b/modules/home/default.nix @@ -18,6 +18,7 @@ ./yazi.nix # flagship TUI file manager, themed + plugins ./osd.nix # swayosd volume/brightness OSD, themed ./nightlight.nix # scheduled blue-light filter (hyprsunset), opt-in + ./autotheme.nix # auto day/night theme switch (settings.autoTheme), opt-in ./timezone.nix # keep the Waybar clock in step with auto-timezone changes ./updates.nix # passive update-awareness indicator + notification, opt-in ./shell.nix # zsh + starship + bat/eza/zoxide, themed