# План реализации трехпанельного интерфейса Windows Client

**Intent:** Перестроить текущий монолитный экран Windows-клиента в три переключаемые панели: read-only сводка, настройки ProxiFyre и настройки VPN/прокси.
**Current Behavior:** Сейчас `apps/windows-client/src/app/App.tsx` смешивает статус ProxiFyre, выбор маршрута, Local sing-box, список приложений, применение конфига и журнал событий на одном экране. Пользователь сразу видит все управляющие элементы, поэтому главная страница не отделяет состояние системы от действий.
**Expected Outcome:** Пользователь открывает приложение и сначала видит чистую сводку без редактирования. Управление ProxiFyre, список приложений и диагностика компонента находятся во второй панели. Выбор локального или внешнего прокси, подписка, серверы, ping и генерация VPN/proxy-конфига находятся в третьей панели.
**Target-Perspective Output:** Пользователь может за 5-10 секунд понять, работает ли система, запущен ли ProxiFyre, какой маршрут применен, локальный он или внешний, и какой файл конфига активен. Затем пользователь переключается во вкладку ProxiFyre для сервисных действий и списка приложений либо во вкладку VPN/Прокси для выбора маршрута и проверки соединения.
**Truth Owner:** Rust/Tauri команды и JSON-файлы под `C:\ProgramData\VpnProxy` остаются источником правды. React хранит только состояние текущей вкладки, черновики полей, loading/error/success состояния и производные view model для отображения.
**Contract Boundary:** UI вызывает существующие typed Tauri commands из `apps/windows-client/src/api/tauriCommands.ts`. Rust владеет профилями, targets, компонентами, local-singbox config/cache, generated config и применением ProxiFyre. Новые UI-панели не должны писать напрямую в derived/generated артефакты.
**Cutover:** Текущий единый экран в `App.tsx` заменяется shell-layout с тремя вкладками. Существующие функции загрузки, установки, запуска, выбора сервера, ping, apply и notifications переиспользуются, но раскладываются по панелям.
**Displaced Path:** Убирается доминирующий путь "все настройки на одной странице". Сводка не дублирует формы и кнопки apply; она только отображает состояние и ведет пользователя к нужной панели.
**Value Density:** Самый ценный срез: верхняя навигация по трем панелям плюс read-only сводка, которая корректно собирает текущее состояние из уже загружаемых данных. После этого переносим существующие настройки без изменения backend-контракта.
**Evidence Gate:** Приемка требует не только `npm run build`, но и доказательство глазами пользователя: скриншоты/состояния всех трех панелей, read-only поведение сводки, dirty/apply состояние на вкладках настроек, responsive-проверка.
**Acceptance Evidence:** `npm run build` проходит; при необходимости Rust tests проходят для нового ping/target DTO; в `EVIDENCE.md` записаны скриншоты или browser/Tauri state для трех панелей, а также проверка, что сводка не содержит изменяющих controls.
**Evidence Lane:** Доказательства исполнения будут фиксироваться в `docs/goals/windows-client-three-panel-ui/EVIDENCE.md`.
**Kill Criteria:** Нет input/button apply на сводке; нет второго источника состояния маршрута; нет скрытой установки компонентов при открытии вкладок; нет изменения root `src/web` или root `src/server`; нет расхождения терминов ProxiFyre / Local sing-box / внешний прокси.
**Architecture Slice:** Изменения сосредоточены в `apps/windows-client/src/app/App.tsx`, `apps/windows-client/src/styles/app.css`, при необходимости `apps/windows-client/src/api/tauriCommands.ts`, `apps/windows-client/src/domain/types.ts`, `apps/windows-client/src-tauri/src/commands.rs` и связанных tests для проверки внешнего target ping.
**Plan Review Gate:** Требуется PRE review перед исполнением.

## Краткий дизайн-brief

Продукт: Windows desktop utility для маршрутизации выбранных приложений через ProxiFyre и внешний или локальный proxy path.

Визуальный источник: текущий темный utilitarian-стиль `apps/windows-client/src/styles/app.css`: компактные панели, 4px radius, статусные точки, lucide icons, сдержанные borders, без landing/hero.

Интерактивность: полная. Вкладки, меню, установка/запуск/остановка, добавление приложений, выбор маршрута, подписка, выбор сервера, ping, генерация и apply должны работать через реальные текущие команды.

## Архитектурный срез

Файлы для создания:
- `docs/goals/windows-client-three-panel-ui/PLAN.md`
- `docs/goals/windows-client-three-panel-ui/GOAL.md`
- `docs/goals/windows-client-three-panel-ui/EVIDENCE.md`

Файлы для изменения:
- `apps/windows-client/src/app/App.tsx`
- `apps/windows-client/src/styles/app.css`
- `apps/windows-client/src/api/tauriCommands.ts`, только если понадобится новый внешний proxy ping command.
- `apps/windows-client/src/domain/types.ts`, только если понадобится новый DTO для внешнего proxy ping.
- `apps/windows-client/src-tauri/src/commands.rs`, только если понадобится новый внешний proxy ping command.
- `apps/windows-client/src-tauri/src/main.rs`, только для регистрации нового command.
- `apps/windows-client/src-tauri/tests/*`, только для нового command или сохранения существующих контрактов.
- `docs/goals/windows-client-three-panel-ui/EVIDENCE.md`, при исполнении.

Файлы, которых не касаться:
- `src/web/*`
- `src/server/*`
- Docker/compose/entrypoint файлы.
- Installer scripts, если UI-разрез не требует изменения install boundary.
- Старые goal packages, кроме ссылок в evidence при необходимости.

Источник правды:
- `C:\ProgramData\VpnProxy\config\profiles.json`
- `C:\ProgramData\VpnProxy\config\targets.json`
- `C:\ProgramData\VpnProxy\config\components.json`
- `C:\ProgramData\VpnProxy\config\local-singbox.json`
- `C:\ProgramData\VpnProxy\state\singbox-subscription-cache.json`
- `C:\ProgramData\VpnProxy\state\activity.json`

Производные артефакты:
- `C:\ProgramData\VpnProxy\generated\proxifyre-app-config.json`
- `C:\ProgramData\VpnProxy\generated\sing-box-config.json`

Путь чтения:
- React вызывает `get_saved_state`, `get_components`, `get_proxifyre_setup_status`, `get_singbox_status`, `get_singbox_setup_status`.
- Summary panel строит производную view model из уже загруженных `profiles`, `targets`, `components`, `setupStatus`, `singBoxStatus`, `generatedConfigPath`, `serverPings` и `hasUnappliedChanges`.
- ProxiFyre panel читает `proxyfier`, `setupStatus`, `items`, `loadedProfiles`, `generatedConfigPath`.
- VPN/Proxy panel читает `routeMode`, `proxyInput`, `singBoxStatus`, `singBoxSetupStatus`, `serverPings`, selected server и target.

Путь записи:
- ProxiFyre panel пишет только через существующие handlers: install/start/stop/uninstall ProxiFyre, add/remove app items, `updateConfig`.
- VPN/Proxy panel пишет только через route/subscription/server/config handlers: `changeRouteMode`, `changeProxyInput`, `saveSingBoxSubscription`, `fetchSingBoxSubscription`, `forgetSingBoxSubscription`, `selectSingBoxServer`, `ping*`, `generateSingBoxConfig`, service actions, `updateConfig`.
- Summary panel не пишет ничего, кроме глобального non-mutating refresh, если refresh остается в header.

Граница контракта:
- `App.tsx` отвечает за orchestration и view composition.
- Typed Tauri command wrappers отвечают за API shape.
- Rust commands отвечают за validation, persistence, service/check actions и generated config.
- CSS отвечает за layout, tab transitions, loading skeletons, menu/popover transitions и responsive behavior.

Точки интеграции:
- `routeMode === 'external'` показывает внешний/глобальный proxy target.
- `routeMode === 'local-singbox'` показывает Local sing-box path.
- `hasUnappliedChanges` остается общим индикатором для вкладок настроек.
- `log-dock` остается глобальным и не привязывается к одной вкладке.

Миграция и переключение:
- Сначала добавить `activePanel` и shell-вкладки без изменения бизнес-логики.
- Затем перенести JSX блоки в три render-функции или локальные компоненты в том же файле.
- После стабилизации можно вынести панели в отдельные файлы, но только если это уменьшит размер `App.tsx` без изменения контрактов.

Гейт приемочных доказательств:
- Доказательство должно показать каждую панель отдельно.
- Должно быть видно, что summary read-only.
- Должно быть видно, что actions доступны на вкладках настроек.
- Должно быть видно, что mobile layout не ломает tab bar, app list, server list и bottom log dock.

## Детальное описание интерфейса

### Общая оболочка

Верхняя часть экрана остается компактной, но становится навигационной:
- слева: `VPN Proxy` и заголовок `Прокси для приложений`;
- справа: кнопка `Обновить`, которая запускает текущий `refresh`;
- под заголовком: segmented tabs из трех пунктов: `Сводка`, `ProxiFyre`, `VPN / Прокси`.

Поведение вкладок:
- активная вкладка имеет более яркий border/background и status underline;
- при клике меняется только `activePanel`, данные не перезагружаются автоматически;
- переход между панелями: fade + легкий slide по Y на 6-8px, длительность 140-180ms;
- при `prefers-reduced-motion: reduce` transition отключается;
- keyboard support: tabs работают как buttons с `aria-pressed` или `role="tablist"`/`role="tab"`/`role="tabpanel`.

Глобальные состояния:
- `isLoading` показывает skeleton в содержимом активной панели;
- `isDetectingComponents` показывает проверку компонентов без блокировки переключения вкладок;
- `log-dock` остается закрепленным снизу и продолжает показывать success/error/info;
- dirty/apply bar появляется только на вкладках `ProxiFyre` и `VPN / Прокси`, не на read-only сводке.

### Панель 1: `Сводка`

Назначение: главная read-only страница, которая отвечает на вопрос "что сейчас происходит с системой".

Содержимое:
- `Статус системы`: одно агрегированное состояние `Работает`, `Требует внимания`, `Не настроено`, `Проверяю`.
- `ProxiFyre`: установлен/не установлен, запущен/остановлен, путь или первая проблема.
- `Подключение`: корректность текущего маршрута: ProxiFyre running, выбран target, для Local sing-box выбран сервер и служба запущена, для внешнего proxy валиден host/port и есть последний результат ping/check, если он уже запускался.
- `Маршрут`: `Локальный прокси` или `Внешний прокси`; рядом человекочитаемый endpoint: `127.0.0.1:1080`, LAN адрес Local sing-box или внешний `host:port`.
- `Активный сервер`: selected Local sing-box server tag, если применим; иначе `не используется`.
- `Приложения в профиле`: количество настроенных process/folder/exe items.
- `Примененный конфиг`: путь `generatedConfigPath` для ProxiFyre и, если есть, `singBoxStatus.generatedConfigPath`.
- `Состояние изменений`: `Все применено` или `Есть непримененные изменения`, но без кнопки apply.
- `Последнее событие`: последний элемент `logEntries` или activity, если он уже доступен на клиенте.

Визуально:
- это не форма, а read-only dashboard;
- вместо input используются value rows: label слева, value справа, status dot рядом;
- важные значения не спрятаны в tooltip;
- длинные пути переносятся через `overflow-wrap: anywhere`;
- при широкой ширине блоки идут сеткой 2-3 колонки, на узком экране складываются в один столбец.

Действия при нажатии:
- клик по строке `ProxiFyre` переключает на вкладку `ProxiFyre`;
- клик по строке `Маршрут` или `Активный сервер` переключает на вкладку `VPN / Прокси`;
- клик по `Приложения в профиле` переключает на вкладку `ProxiFyre` и фокусирует список приложений;
- никаких input, add/remove, install/start/stop, apply или clear на этой панели нет.

Анимации:
- при refresh status rows показывают мягкий shimmer/skeleton;
- status dot для `Проверяю` использует текущий spinner pattern;
- при смене агрегированного статуса value row подсвечивается на 400-600ms через background flash;
- предупреждение `Есть непримененные изменения` может слегка проявляться fade-in, но без кнопки.

### Панель 2: `ProxiFyre`

Назначение: диагностика и настройка того, что относится именно к ProxiFyre и маршрутизируемым приложениям.

Содержимое:
- главный статус ProxiFyre: найден/не найден, запущен/остановлен, path/problem;
- setup/modules list из `setupStatus.items`: binary/service/install folder/config capability и все, что возвращает backend;
- service controls: install, start, stop, uninstall через меню `MoreHorizontal`;
- `Список приложений`: настроенные process/folder/exe items, сгруппированные или помеченные типом;
- счетчик приложений и отдельные пустые состояния для "ничего не настроено";
- generated ProxiFyre config path;
- dirty/apply state для изменений списка приложений.

Визуально:
- верхний status block сохраняет текущий `finder-card` pattern, status-light и animated border glow;
- modules list разворачивается внутри панели через `Состав ProxiFyre` / `Что будет установлено`;
- список приложений становится основной частью панели, а не хвостом общей страницы;
- app rows имеют icon по типу: process, exe, folder;
- add-toolbar остается с icon buttons: process, exe, folder, с tooltip/title.

Действия при нажатии:
- `Установить`: вызывает текущий `installProxiFyrePackage`, показывает loading на кнопке и animated border;
- `Запустить`/`Остановить`: вызывает `setProxiFyreServiceRunning`, блокирует повторный клик на время action;
- `Еще` открывает popover с `Удалить ProxiFyre`; uninstall сохраняет текущий confirm boundary;
- `Состав ProxiFyre`: раскрывает/скрывает setup details;
- `Добавить процесс`: открывает inline input, Enter добавляет, Escape закрывает;
- `Добавить EXE`: открывает file picker через Tauri dialog;
- `Добавить папку`: открывает directory picker;
- `Удалить` у app row удаляет item и выставляет `hasUnappliedChanges`;
- `Применить в ProxiFyre`: валидирует items и текущий route, затем вызывает `updateConfig`;
- `Открыть конфиг`: открывает generated config location, если эта кнопка остается в ProxiFyre panel.

Анимации:
- поиск/установка/запуск используют существующий moving border glow;
- раскрытие modules list: height/opacity transition 160-220ms;
- добавление app row: fade/slide-in;
- удаление app row: быстрый opacity collapse, если реализация не усложнит state;
- dirty bar появляется slide-up/fade-in над command row;
- меню `Еще`: fade + scale 0.98 -> 1.

### Панель 3: `VPN / Прокси`

Назначение: выбор маршрута и настройка самого proxy/VPN path.

Содержимое:
- segmented control `Внешний прокси` / `Локальный прокси`;
- для `Внешний прокси`: input адреса `socks5://host:port` или `host:port`, validation hint, кнопка проверки доступности;
- для `Локальный прокси`: Local sing-box status, install/start/stop/uninstall, setup details, локальный и LAN endpoint, selected server, generated sing-box config path;
- subscription input: paste URL/link, load/update, clear;
- server list из `singBoxStatus.cache.servers`;
- ping controls: `Ping все`, per-server ping action, отображение latency/error рядом с server row;
- generate sing-box config action;
- route preview: `Выбранные приложения -> ProxiFyre -> внешний proxy` или `Выбранные приложения -> ProxiFyre -> Local sing-box -> selected server`;
- dirty/apply state для route/proxy/subscription/server changes.

Визуально:
- mode switch остается заметным вверху панели;
- внешний proxy block не должен выглядеть менее важным, потому что это полноценный route path;
- Local sing-box block визуально похож на ProxiFyre status block, но расположен только в VPN/Proxy panel;
- server list может оставаться grid, но row должен показывать selected dot, server name и ping badge;
- для плохого ping row получает amber/red border, для хорошего ping зеленый badge;
- route preview оформляется как read-only line/flow, без декоративной схемы.

Действия при нажатии:
- `Внешний прокси`: меняет `routeMode` на `external`, выставляет dirty state;
- ввод адреса proxy: обновляет `proxyInput`, выставляет dirty state, frontend validation показывает ошибки до apply;
- `Проверить`: парсит внешний proxy и вызывает новый или переиспользованный backend TCP connect check; результат сохраняется в UI state и отображается на этой панели и в summary;
- `Локальный прокси`: меняет `routeMode` на `local-singbox`, выставляет dirty state;
- `Установить Local sing-box`: вызывает текущий install handler;
- `Запустить`/`Остановить`: вызывает текущий service handler;
- `Состав Local sing-box`: раскрывает setup details;
- `Подробности`: показывает локальный endpoint, LAN, server, binary path, config path;
- `Загрузить`/`Обновить` подписку: вызывает текущий subscription flow;
- `Очистить`: вызывает forget flow, очищает server pings и selected server;
- click по server row: вызывает `selectSingBoxServer`, выставляет dirty state;
- `Ping все`: вызывает `pingAllSingBoxServers`;
- per-server ping: вызывает существующий `pingSingBoxServer(tag)`, если добавляем кнопку/иконку в row;
- `Конфиг`: вызывает `generateSingBoxConfig`;
- `Применить маршрут`: вызывает общий `updateConfig`.

Анимации:
- mode switch меняет активный segment без скачка высоты;
- при смене mode panel content cross-fade;
- ping badge показывает loading spinner только на проверяемых row;
- server row после ping обновляет latency с короткой подсветкой;
- subscription/server empty state появляется fade-in;
- generated config success подсвечивает config path на 400-600ms.

## Задачи исполнения

### Задача 1: Ввести shell вкладок и производные view models

Разрешенные файлы:
- `apps/windows-client/src/app/App.tsx`
- `apps/windows-client/src/styles/app.css`

Ожидаемый результат:
- `activePanel: 'summary' | 'proxifyre' | 'proxy'`.
- Общий header с tab control.
- Производные функции для summary: system status, route label, endpoint label, config labels, app count, issue list.
- Старые JSX-блоки временно остаются, но render path начинает разделяться.

Проверка:
- `cd apps/windows-client && npm run build`

Приемочные доказательства:
- Screenshot/state показывает три tab buttons и корректную активную вкладку.

Параллельное выполнение: нет, общий `App.tsx`.

### Задача 2: Реализовать read-only панель `Сводка`

Разрешенные файлы:
- `apps/windows-client/src/app/App.tsx`
- `apps/windows-client/src/styles/app.css`

Ожидаемый результат:
- Summary panel без input/apply/install/start/stop/delete.
- Статус системы, ProxiFyre, подключение, маршрут, активный server, apps count, config paths, dirty state.
- Навигационные клики по read-only строкам переводят на соответствующие вкладки.

Проверка:
- `cd apps/windows-client && npm run build`
- Manual DOM/visual check: на summary нет изменяющих controls.

Приемочные доказательства:
- Screenshot summary panel.
- Запись в evidence: какие элементы read-only и куда ведут navigation clicks.

Параллельное выполнение: нет.

### Задача 3: Перенести ProxiFyre и список приложений во вторую панель

Разрешенные файлы:
- `apps/windows-client/src/app/App.tsx`
- `apps/windows-client/src/styles/app.css`

Ожидаемый результат:
- ProxiFyre panel содержит status card, setup details, service actions, app add/remove, generated config path и apply/open config actions.
- Существующие handlers переиспользованы без изменения backend ownership.
- `hasUnappliedChanges` продолжает работать после add/remove.

Проверка:
- `cd apps/windows-client && npm run build`

Приемочные доказательства:
- Screenshot ProxiFyre panel с service status и apps list.
- Проверка add/remove вызывает dirty state.

Параллельное выполнение: нет.

### Задача 4: Перенести VPN/Proxy route settings в третью панель

Разрешенные файлы:
- `apps/windows-client/src/app/App.tsx`
- `apps/windows-client/src/styles/app.css`
- `apps/windows-client/src/api/tauriCommands.ts`, если нужен внешний target ping.
- `apps/windows-client/src/domain/types.ts`, если нужен внешний target ping DTO.

Ожидаемый результат:
- VPN/Proxy panel содержит route mode switch, external proxy editor, Local sing-box controls, subscription, server selection, ping, generate config, route preview и apply.
- Внешний proxy path не зависит от Local sing-box.
- Local sing-box UI не показывается на summary и не смешивается с ProxiFyre panel.

Проверка:
- `cd apps/windows-client && npm run build`

Приемочные доказательства:
- Screenshot external proxy mode.
- Screenshot local proxy mode с server list или empty state.

Параллельное выполнение: нет.

### Задача 5: Добавить или переиспользовать проверку доступности внешнего proxy target

Разрешенные файлы:
- `apps/windows-client/src-tauri/src/commands.rs`
- `apps/windows-client/src-tauri/src/main.rs`
- `apps/windows-client/src/api/tauriCommands.ts`
- `apps/windows-client/src/domain/types.ts`
- `apps/windows-client/src-tauri/tests/command_tests.rs` или отдельный focused test.

Ожидаемый результат:
- Если существующих данных недостаточно для "все ли окей с подключением" во внешнем proxy mode, добавить typed command наподобие `ping_proxy_target`.
- Command делает TCP connect check к host/port с timeout, возвращает `{ ok, latency, error }`.
- UI отображает результат в VPN/Proxy panel и summary.
- Это не заменяет apply и не пишет source config.

Проверка:
- `cd apps/windows-client/src-tauri && cargo test command`
- `cd apps/windows-client && npm run build`

Приемочные доказательства:
- Test или manual state показывает успешный/ошибочный result shape.

Параллельное выполнение: частично, если UI DTO names согласованы заранее; интеграция не parallel-safe.

### Задача 6: Привести CSS, анимации и responsive behavior

Разрешенные файлы:
- `apps/windows-client/src/styles/app.css`
- `apps/windows-client/src/app/App.tsx`, только className/ARIA adjustments.

Ожидаемый результат:
- Tab bar, panel transitions, setup expand/collapse, ping badges, dirty/apply bar и responsive grids.
- Нет перекрытия текста, длинные paths/servers переносятся.
- Mobile layout: tabs не ломаются, server list минимум 2 колонки или 1 колонка на очень узком экране, command row складывается.
- `prefers-reduced-motion` отключает декоративные transitions.

Проверка:
- `cd apps/windows-client && npm run build`
- Browser/Tauri visual check на desktop и узком viewport.

Приемочные доказательства:
- Screenshots desktop + narrow viewport.

Параллельное выполнение: нет, потому что зависит от финальной разметки.

### Задача 7: Финальная проверка и evidence

Разрешенные файлы:
- `docs/goals/windows-client-three-panel-ui/EVIDENCE.md`
- При необходимости `apps/windows-client/README.md`, если нужно зафиксировать новую навигацию.

Ожидаемый результат:
- Evidence содержит commands, результаты build/tests, screenshots/state checks и список остаточных рисков.
- Если Tauri service actions не проверялись на реальной Windows elevated среде, это явно помечено как `implemented but unproven` только для service lane.

Проверка:
- `git status --short`
- `cd apps/windows-client && npm run build`
- `cd apps/windows-client/src-tauri && cargo test`, если Rust command менялся.

Приемочные доказательства:
- Summary read-only verified.
- ProxiFyre actions verified.
- VPN/Proxy route switch and ping states verified.
- No root web/server changes.

Параллельное выполнение: нет.

## Prompt для PRE review

Использовать `C:\Users\PC\.agents\skills\krypton-planning\plan-reviewer-prompt.md` со следующими данными:

Файл плана:
- `docs/goals/windows-client-three-panel-ui/PLAN.md`

Исходный запрос:
- Разбить Windows client UI на три переключаемые панели: общая read-only сводка, настройки ProxiFyre, настройки VPN/proxy; подробно описать внешний вид, анимации и действия.

Контракт результата:
- Пользователь сначала видит статус системы и примененный route/config без изменения данных, затем переходит в нужную панель для ProxiFyre или VPN/proxy действий.

Архитектурный срез:
- Основной scope: `apps/windows-client/src/app/App.tsx` и `apps/windows-client/src/styles/app.css`; backend только для внешнего target ping, если текущих команд недостаточно.

Требование к приемочным доказательствам:
- Build/tests плюс screenshots/state proof трех панелей и read-only summary.

Известные non-goals:
- Не менять root `src/web`/`src/server`.
- Не переписывать Tauri backend без нужды.
- Не добавлять скрытую установку компонентов.
- Не делать summary редактируемой.

Опасные пути или слои:
- Дублирование source of truth в React.
- Изменение generated config напрямую.
- Смешивание Local sing-box controls обратно в ProxiFyre panel.
- Потеря external proxy path как полноценного режима.
