1.2.5

Changed (#384)

  • Страница чата: панели «Избранное», «Задачи» и «Данные» переведены с перекрывающих оверлеев на единый split-view (#384, паттерн zcode) — при открытии панели область чата (лог + композер) плавно сжимается влево, правая часть становится inline-панелью: width: max(380px, min(50%, 720px)) с анимацией ширины 280ms, без затемнения и перекрытия чата. Новый компонент SidePanel.svelte (заголовок с иконкой/названием/кнопкой закрытия, Esc с гвардом от двойного закрытия и перехватом onescape для содержимого, полный экран absolute inset-0 на <768px); FavoritesPanel (была: выезд сверху на 85vh) и TodosPanel (была: fixed drawer 380px поверх чата) стали content-only; WorkspaceMDViewer (был: выезд сверху на 85vh) — content-only, а его внутренний сплит «дерево 280px + контент» переведён с viewport-media на container queries (container-type: inline-size на .wmd-body, @container (max-width: 640px)) — раскладка зависит от ширины панели, а не окна. Управление: одно состояние sidePanel: 'favorites' | 'todos' | 'data' | null вместо трёх булевых, одна панель одновременно, повторный клик по кнопке — toggle, активная кнопка подсвечена (десктоп и мобильное kebab-меню), смена агента при открытой панели перемонтирует содержимое ({#key}) — данные чужого агента не показываются. Esc в «Данных» работает как навигация: при открытом файле возвращает к дереву, при создании папки отменяет его, вторым нажатием закрывает панель; Esc не перехватывается при открытом ConfirmModal (aria-modal). Попутно в selectFile добавлен token-guard: медленный fetch раннего клика больше не перетирает результат позднего и не утекает object URL. Тесты/проверки: npm run check, npm test (855), npm run lint, prettier, make build-webui — зелёные; smoke в браузере — все три панели, toggle, переключение, upload/просмотр файла, Esc-навигация, мобильная ширина. ocr review — 11 находок: 5 закрыты (гвард двойного закрытия SidePanel, race в selectFile + revoke, active-состояние в мобильном меню, отличимый от hover цвет активной кнопки, min-width у fav-root), остальные отклонены с обоснованием (remount {#key} при смене агента — намеренный, данные агента; «фликер loading» TodosPanel невозможен — состояние экземплярно; svelte:window всегда активен — контракт «Esc закрывает панель»).