diff --git a/docs/specs/plans/04-shell-first-frame.md b/docs/specs/plans/04-shell-first-frame.md new file mode 100644 index 0000000..463b1d9 --- /dev/null +++ b/docs/specs/plans/04-shell-first-frame.md @@ -0,0 +1,41 @@ +# План 4 — `shturman-shell` (первый Slint-кадр) + +> REQUIRED SUB-SKILL: `executing-plans` + TDD. Полный код — в `src`; здесь дизайн/задачи/acceptance. + +**Goal:** первый Slint-кадр (срезы C03/C04/C05/C07/C02): статус-бар (часы + сеть «unknown») + home-грид +плейсхолдеров + тема день/ночь; читает `ui.theme`/Power **через `sdk`** (best-effort, деградирует без шины — #4). + +**Architecture:** `shturman-shell` (bin) ← `sdk` + `common` + `slint`. Реализует тезис «first-party на SDK». +Чистая логика темы — тестируема (TDD); рендер кадра — на железе/в Lima (План 5 E2E + `just shell-frame`). + +**Tech/решения:** Slint = **GPL-3.0** (вариант A; exception в `deny.toml`, финал к v4). Slint+D-Bus: одноразовое +чтение состояния при старте (tokio-runtime, block_on), затем Slint event loop; live-обновления (Changed/AccChanged) — +позже (v0.5). Часы v0 — **UTC HH:MM** (без tz-deps; локальная tz — позже, a-base §7). UI — `slint!`-макрос. + +--- + +### P4.1: Slint в граф + `deny.toml` exception + +- `Cargo.toml` workspace.deps: `slint = "1"`. +- `deny.toml`: `[licenses] exceptions` — для крейтов `slint`/`i-slint-*`/`slint-*` разрешить `GPL-3.0` + (список уточнить по выводу `cargo deny` после добавления зависимости). Комментарий: вариант A, финал к v4. +- Acceptance: `cargo deny check` зелёный с slint в графе. + +### P4.2: `shturman-shell` — тема (TDD) + Slint-кадр + main + +- `crates/apps/shturman-shell` (members). Deps: `shturman-sdk`, `shturman-common`, `slint`, `tokio`, `anyhow`, `tracing`. +- `theme.rs` — `pub fn resolve_night(theme: &str, hour_utc: u8) -> bool`: `night`→true, `day`→false, + `auto`→ночь если `hour < 7 || hour >= 20` (🟡 пороги). **TDD:** day/night явные; auto по часам; неизвестное → как auto. +- `ui` (`slint!`-макрос): `AppWindow` с `in property` `is-night`/`clock`/`network`/`ignition` + грид тайлов-плейсхолдеров; + фон/цвета от `is-night`. +- `main.rs`: `init_tracing`; одноразовое чтение `ui.theme` (Settings) + `ignition` (Power) через `sdk` (best-effort, + при отсутствии шины — дефолты `auto`/`unknown`, кадр всё равно рисуется #4); `resolve_night` от UTC-часа; + выставить свойства; `AppWindow::run()`. +- `justfile`: `shell-frame` — запустить shell (ручная проверка кадра). (Реальный screenshot-E2E — План 5.) +- **Acceptance:** `cargo build -p shturman-shell` (slint! компилируется); `theme`-тесты зелёные; `just ci` зелёный + (deny с slint-exception); `just test` не требует шины (shell-тесты — чистая логика). + +--- + +## Дальше +План 5 — dev-tools (валидатор манифеста/scaffolding/fixtures) + systemd-юниты + Lima + сквозной E2E (screenshot кадра).