Refactor proxy handling and update related UI flows

This commit is contained in:
2026-07-08 09:01:10 +03:00
parent b45dd2ae05
commit 288acbf0c8
14 changed files with 2655 additions and 552 deletions

View File

@@ -0,0 +1,85 @@
# Доказательства трехпанельного интерфейса Windows Client
## Приемочные доказательства
Записать реальный артефакт, который доказывает результат с точки зрения пользователя.
Обязательные доказательства:
- `summary-panel.png`: read-only `Сводка` показывает статус системы, ProxiFyre, подключение, маршрут, активный сервер, количество приложений, config path state, dirty state и последнее событие.
- Browser state для `Сводка`: `summaryInputs = 0`, `summaryForbiddenButtons = []`, активная вкладка `panel-summary`.
- `proxifyre-panel.png`: панель `ProxiFyre` показывает статус компонента, setup action, service install action, список приложений, add controls, dirty/apply command row.
- `vpn-proxy-external-panel.png`: панель `VPN / Прокси` в режиме внешнего прокси показывает route switch, SOCKS5 input, TCP check state, route preview и apply/open actions.
- `vpn-proxy-local-panel.png`: панель `VPN / Прокси` в режиме локального прокси показывает Local sing-box empty/install state, route preview и dirty/apply state.
- `narrow-proxifyre-panel.png`: узкий viewport показывает tab bar, ProxiFyre card, app list controls и command area без overlap с log dock.
- Browser overlap state после фикса: desktop `commandBottom = 705.1875`, `logTop = 815.1875`, `overlaps = false`; narrow `appListBottom = 701.1875`, `logTop = 1072.1875`, `overlaps = false`.
- Root `src/web` и `src/server` не менялись.
Сервисные действия install/start/stop/uninstall проверены на уровне существующих handlers и сборки UI. Реальный elevated Windows service lane для ProxiFyre/Local sing-box в этой сессии не запускался: `implemented but unproven`.
## Проверка
Записать сфокусированные проверки, которые прошли, включая команды и важный вывод.
Ожидаемые команды:
```powershell
cd apps/windows-client
npm run build
```
Результат:
```text
tsc && vite build
1789 modules transformed
dist/index.html
dist/assets/index-Oqrmqzau.css
dist/assets/index-CJqhju7q.js
built in 1.31s
```
Если менялись Rust/Tauri commands:
```powershell
cd apps/windows-client/src-tauri
cargo test
```
Результат:
```text
command_tests: 10 passed, including ping_proxy_target_reports_open_tcp_endpoint
component_detection_tests: 7 passed
domain_tests: 5 passed
helper_tests: 6 passed
proxifyre_adapter_tests: 6 passed
singbox_adapter_tests: 6 passed
singbox_command_tests: 8 passed
singbox_service_tests: 7 passed
storage_tests: 8 passed
subscription_tests: 7 passed
doc-tests: 0 passed
overall: passed, warnings only for existing dead-code/test module duplication
```
Browser preview:
```text
Opened http://127.0.0.1:5174/
Tabs detected: Сводка, ProxiFyre, VPN / Прокси
Summary activePanel: panel-summary
ProxiFyre activePanel: panel-proxifyre
VPN/Proxy activePanel: panel-proxy
External route aria-pressed=true in external mode
Local route aria-pressed=true in local mode
```
## Заметки review
Записать PRE review, reviewer, maintainer или verifier findings, если они изменили результат.
- PRE review: aligned. No blockers. Main risk was weak UI evidence; resolved by browser screenshots and DOM state checks.
- POST plan review: aligned. The displaced monolithic screen path is removed from the active render path and replaced by three panels.
- Correctness review: summary has no mutating controls; ProxiFyre actions remain in ProxiFyre panel; route/proxy actions remain in VPN/Proxy panel; new `ping_proxy_target` is read-only and tested with a local TCP listener.
- Maintainability review: backend source of truth unchanged; no direct generated config writes from React; no root `src/web` or `src/server` edits.
- Residual risk: real elevated service actions were not manually executed in native Tauri/elevated Windows mode during this UI pass.

View File

@@ -0,0 +1,12 @@
# Goal: Трехпанельный интерфейс Windows Client
Use Krypton Execution to execute `docs/goals/windows-client-three-panel-ui/PLAN.md`.
Core rules:
- Treat `PLAN.md` as the source plan.
- Preserve intent, ownership, contract, cutover, evidence, and kill criteria.
- Summary panel must remain read-only: no apply, install, start, stop, delete, input, subscription, or route mutations there.
- Keep Rust/Tauri storage and commands as the source of truth; React may hold only UI state and derived display models.
- Do not add a new dominant path without deleting, redirecting, demoting, or shimming the displaced monolithic screen path.
- Capture acceptance evidence from the target perspective and record it in `EVIDENCE.md`.
- Say `implemented but unproven` if target-perspective or Windows service evidence cannot be captured.

View File

@@ -0,0 +1,423 @@
# План реализации трехпанельного интерфейса 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 как полноценного режима.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB