# PR: UI — выравнивание под макеты (редактор + пульт) Связь с **feature-pipeline** (`.cursor/skills/feature-pipeline/SKILL.md`): критерии ниже сгруппированы по стадиям; после merge обновляют `.cursor/pipeline-state.json` по мере прохождения стадий. --- ## Мета PR | Поле | Значение | |------|----------| | **Цель** | Визуальная и UX-полировка существующих экранов без новых продуктовых фич из макета | | **Область** | `EditorApp`, `SceneGraph`, `ControlApp`, общие токены/мелкие UI-баги | | **Вне скоупа** | Новые пункты меню, новые типы сцен, новые каналы микшера, если их нет в коде | --- ## Stage 1 — Implementation (subagent: `frontend-senior`) ### Чеклист PR - [ ] **P0-A** Карточка узла графа: статусы «Авто / Цикл / Аудио» отражают **реальные** поля сцены (`previewVideoAutostart`, `settings.loopVideo`, наличие `media.audios`), а не статичный текст. - [ ] **P0-B** Пульт: для сцены с видео-превью явно подписано, что **кисть эффектов** недоступна (согласовано с `PresentationView`: эффекты только для image). - [ ] **P1-A** Пульт: порядок секций **Предпросмотр → Варианты ветвления → Музыка сцены → Быстрый микшер** (вертикальный поток как в референсе). - [ ] **P1-B** Сетка «Варианты ветвления» без «дыр»: `repeat(auto-fit, minmax(...))` **или** фиксированные слоты с disabled/placeholder **без новых сценариев** — только визуальная сетка. - [ ] **P2-A** Редактор: меню «Файл» — цвет текста пункта на валидном токене (`--text0` / `--text1`), без несуществующего `--text`. - [ ] **P2-B** Список сцен: убрать пустой статус-ряд у неактивных карточек (без лишнего вертикального зазора). ### Критерии приёмки (Stage 1) 1. На графе для сцены **без видео-превью** не отображаются вводящие в заблуждение чипы «Авто/Цикл» видео-превью; при наличии аудио — корректный индикатор аудио. 2. Для сцены с **видео-превью** чипы «Авто»/«Цикл» совпадают с `previewVideoAutostart` и `scene.settings.loopVideo`. 3. В пульте при `previewAssetType === 'video'` пользователь видит **одну строку-пояснение** (вторичный текст), почему нет панели эффектов. 4. Визуальный порядок блоков пульта соответствует чеклисту P1-A; отступы между `Surface` единообразны (`gap` 16). 5. Нет регрессий drag-and-drop сцен на граф и переключения веток. **Definition of Done (Stage 1):** все пункты чеклиста Stage 1 отмечены; `npm run build` успешен. --- ## Stage 2 — Review (subagent: `reviewer`) ### Чеклист PR - [ ] Нет «мёртвых» веток UI и ложных состояний (чипы/подписи соответствуют данным). - [ ] a11y: фокус/клавиатура на интерактивах не сломаны; `aria-*` не ухудшены. - [ ] Нет лишнего diff вне файлов задачи. ### Критерии приёмки (Stage 2) 1. Reviewer фиксирует замечания с **Severity**; все **high** устранены или явно отклонены с причиной в PR. 2. После правок по review снова выполняется `npm run build`. **Definition of Done (Stage 2):** review-замечания закрыты; state `review: done`. --- ## Stage 3 — Tests (subagent: `unit-tests`) ### Чеклист PR - [ ] Добавлены или обновлены тесты на **чистую логику** (например, хелпер разметки чипов по `Scene`, если вынесен в `app/shared`). - [ ] Либо задокументировано в PR, что изменения только презентационные и покрыты smoke-тестом пайплайна. ### Критерии приёмки (Stage 3) 1. `npm run test` завершается с кодом 0. 2. Новые тесты не flaky, не зависят от Electron UI. **Definition of Done (Stage 3):** `tests: done` в `.cursor/pipeline-state.json`. --- ## Stage 4 — Verify (локально / hook `final-verify.cjs`) Выполнить подряд: ```bash npm run lint npm run typecheck npm run test ``` **Если `npm run lint` падает на массовых `Delete ␍` (CRLF/LF) в файлах вне PR** — до отдельного chore-PR с нормализацией строк для этого чеклиста достаточно: ```bash npx eslint app/renderer/control/ControlApp.tsx app/renderer/editor/graph/SceneGraph.tsx app/renderer/shared/ui/sceneGraphChips.ts app/renderer/shared/ui/sceneGraphChips.test.ts --max-warnings 0 npm run typecheck npm run test npm run build ``` ### Критерии приёмки (Stage 4) 1. `npm run typecheck`, `npm run test`, `npm run build` — **exit 0**. 2. Линт: либо полный `npm run lint` — **exit 0**, либо (при известном eol-долге репозитория) scoped-ESLint по файлам PR — **exit 0**, как в блоке выше. 3. `node .cursor/hooks/final-verify.cjs` — успешное завершение пайплайна только когда полный `npm run lint` зелёный (хук вызывает полный lint; при падении lint хук пишет `followup_message` в stdout). --- ## Синхронизация с `.cursor/pipeline-state.json` После каждой стадии обновлять файл: ```json { "implementation": "done", "review": "done", "tests": "done" } ``` До начала работы — все `"pending"`.