feat(theme-sync): #79 slice 1 — auto day/night theme primitive
All checks were successful
Check / eval (push) Successful in 3m58s

First slice of the auto time-of-day theme pair (VISION § D, split into
CLI / timer / menu). `nomarchy-theme-sync auto` reads
settings.autoTheme.{enable,day,night,sunrise,sunset}, picks day vs night
from the local clock, and applies the matching preset — but only if it
differs from the current one, so the slice-2 timer can fire freely
without triggering needless rebuilds. `--which` prints the decision
without switching; `--force` and `--no-switch` included.

cmd_apply's core is factored into apply_named() so `auto` drives the
exact same one engine (no second pipeline). apply behavior is unchanged.

Verification: V1 (package builds) + functional tests on the built binary
against scratch state — wide-day window → day slug, a 00:00–00:01 day
span → night, disabled → no-op, missing day/night → clear die, auto
--no-switch writes state, a re-run no-ops as "already on", and plain
apply still writes (refactor intact). V0 py_compile + flake check +
checks.theme-sync-validate green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-07-10 21:20:55 +01:00
parent 79d73cd623
commit 429de59b52
3 changed files with 101 additions and 7 deletions

View File

@@ -28,6 +28,23 @@ in [`docs/ROADMAP.md`](../docs/ROADMAP.md); map in
## NEXT
### 79. Auto time-of-day theme pair (`VISION § D`) `[big]` — split
Auto light/dark theme switch through the **existing** engine (a timer runs
`nomarchy-theme-sync apply`), one pipeline. State: `settings.autoTheme`
`{enable, day, night, sunrise, sunset}` in theme-state.json. Slices:
1. ~~**CLI primitive + schema**~~ ✓ shipped 2026-07-10 —
`nomarchy-theme-sync auto` resolves day/night from
`settings.autoTheme.{enable,day,night,sunrise,sunset}` and applies (only
if different — idempotent, so the timer won't needlessly rebuild);
`--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).
3. **Menu** — Look & Feel Auto theme: enable/disable, pick day/night
themes, set times. Writes state.
### 76. Hibernation default — all agent work shipped `[blocked:hw]`
Hibernation + zram on by default (product intent, Bernardo 2026-07-10).
**All V0/V1/V2 slices done** (2026-07-10); only the V3 check remains — on a

View File

@@ -17,6 +17,25 @@ Template:
---
## 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.
- **Did:** `nomarchy-theme-sync auto` — reads
`settings.autoTheme.{enable,day,night,sunrise,sunset}`, computes day/night
by the local clock, and applies the matching preset **only if different**
(idempotent → the slice-2 timer won't rebuild needlessly). `--which`
prints the decision without switching; `--force`/`--no-switch` too.
Factored `cmd_apply`'s core into `apply_named` so `auto` reuses the exact
same one engine (GOALS: no second pipeline).
- **Verified:** **V1** package builds; functional tests on the built bin
against scratch state: wide-day→day slug, 00:0000:01 window→night,
disabled→no-op, missing day/night→die, `auto --no-switch` writes state,
re-run→"already on" no-op, plain `apply` still writes (refactor intact).
**V0** py_compile + flake check + `checks.theme-sync-validate` green.
- **Pending:** slices 2 (systemd sunrise/sunset timers + login apply, V2)
and 3 (Look & Feel menu) remain under #79.
- **Next suggestion:** #79 slice 2 — the timer/hook (V2 runNixOSTest).
## 2026-07-10 — #78 Omarchy migrant doc (docs/OMARCHY.md)
- **Task:** BACKLOG #78 (promoted from PROPOSED) — Omarchy→Nomarchy
one-pager (`VISION § F`).