feat(yahweh-theme): persistencia de la preferencia de theme entre runs

Iter 13. El switcher ya cambiaba el chrome en runtime, pero al
cerrar/reabrir el theme volvía a Nebula default. Ahora se persiste
en $XDG_CONFIG_HOME/yahweh/theme (default ~/.config/yahweh/theme)
y se restaura al boot.

yahweh-theme:
- pub fn config_path() -> Option<PathBuf>: resuelve XDG; None en
  sandbox/CI sin HOME ni XDG_CONFIG_HOME.
- pub fn load_persisted() / persist(theme): API pública.
  Variantes load_from_path / persist_to_path con path explícito
  para tests y apps custom.
- Theme::install_default(cx) ahora load_persisted o cae a Nebula.
- Theme::set(cx, theme) ahora persist + set_global. Best-effort:
  io errors ignorados (no rebota la UX por un secundario).
- 5 tests nuevos: round-trip, missing file, unknown name, create
  parent dir, XDG_CONFIG_HOME respetado.

API pública de install_default/set sin cambio de shape — todos los
downstream compilan sin tocar nada. Smoke run verificado.

Beneficio: 4 apps yahweh-themed comparten preferencia persistente.
Usuario puede preset via `echo Aurora > ~/.config/yahweh/theme`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-10 11:56:48 +00:00
parent 99838b849b
commit ce424eb6af
2 changed files with 212 additions and 5 deletions
+52
View File
@@ -6,6 +6,58 @@ ratio/diff ver `git show <sha>`.
## 2026-05-10
### feat(yahweh-theme): persistencia de la preferencia de theme entre runs
Iter 13. El theme switcher ya cambiaba el chrome en runtime, pero
al cerrar y reabrir la app el theme volvía a Nebula default. Ahora
el name del theme se persiste en `$XDG_CONFIG_HOME/yahweh/theme`
(default `~/.config/yahweh/theme`) y se restaura al boot.
Cambios en `yahweh-theme`:
- **`pub fn config_path() -> Option<PathBuf>`**: resuelve el path
XDG. Devuelve `None` si ni `XDG_CONFIG_HOME` ni `HOME` están
set (sandbox/CI).
- **`pub fn load_persisted() -> Option<Theme>`**: lee el archivo,
trim, busca el theme por name vía `Theme::by_name`. `None` si
el file no existe, lectura falla, o el name no matchea ningún
preset (e.g. preset renombrado entre versiones).
- **`pub fn persist(theme: &Theme) -> io::Result<()>`**: escribe
el name al config file. Crea el dir parent si no existe.
- **`pub fn load_from_path` y `pub fn persist_to_path`**: variantes
con path explícito — útiles para tests con tempfile y para apps
que quieren un path custom (multi-user, staging, etc.).
- **`Theme::install_default(cx)` cambia**: antes hardcoded
`nebula()`. Ahora intenta `load_persisted()`, fallback a Nebula.
- **`Theme::set(cx, theme)` cambia**: antes sólo `cx.set_global`.
Ahora también `persist(&theme)` antes (best-effort: ignora io
errors). El `theme_switcher` widget ya consume `Theme::set`, así
que sin cambios en su código el switching ahora persiste.
5 tests nuevos (`persistence_tests`):
- `persist_then_load_round_trip` — escribir + leer Aurora.
- `load_from_missing_file_returns_none` — no rebota.
- `load_from_unknown_name_returns_none` — name desconocido →
`None` (degrada a default cuando se usa).
- `persist_creates_parent_dir_if_missing` — crea
`~/.config/yahweh/` si no existe.
- `config_path_uses_xdg_config_home_when_set` — respeta el env.
Tests stack: ~5 nuevos en yahweh-theme. Todos los downstream
(nakui-ui, *-explorer) compilan sin tocar nada — la API pública
de `Theme::install_default` y `Theme::set` no cambió shape.
Smoke run del binario verificado: bootstrap OK, panic esperado
sin display.
Beneficio operativo:
- Usuario abre `nakui-ui`, cicla a Aurora con el switcher, cierra
app. Próxima apertura: Aurora cargado del disco. Todas las
apps yahweh-themed (4 del repo) comparten la misma preferencia.
- Failure mode benigno: sin home dir o sin permisos de write,
el theme cambia in-memory pero no se persiste — el switcher
sigue usable, sólo no sobrevive al close.
- Path canónico documentado: usuarios que quieran preset el
theme antes de abrir la app pueden hacer
`echo Aurora > ~/.config/yahweh/theme`.
### feat(minga-explorer): listings de items recientes en cada stat card
Iter 12. Hasta ahora minga-explorer mostraba sólo counts (3
números). Ahora cada stat card muestra también un sample de los