- Проверка без VPN (уровень приложения): пока VPN остановлен, карточка «Доступность сервисов» на Главной по нажатию проверяет сервисы только прямым путём (физическая сеть, цели каталога, бюджеты и 3 воркера те же). «Открывается напрямую» / «Заблокировано» (сброс, тайм-аут, TLS) / «Недоступно». Автозапусков и таймеров нет, результаты только в памяти, при смене сети устаревают, при подключении VPN стираются. - Настройка «Проверка сервисов»: мультивыбор из каталога (Claude и X по умолчанию выключены), ключ в UiSettingsStore без миграции. Планировщик строит запросы только для выбранных сервисов, карточка показывает их же. - ProbeLane держат ещё и проверка подключения (health-check) и замер скорости «умной проверки». Приоритет: подключение > задержки/скорость > сервисы; вытесняемый получает сигнал, подключение ждёт полосу не дольше 3 с и затем идёт без неё, поэтому не зависит от чужой пробы. Пауза автозапуска сервисов тоже уступает полосу. - Тесты: приоритеты полосы, проверка без VPN, выбор сервисов, презентеры. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.2 KiB
Карта исходников
Раскладка Android и Windows выполнена 2026-09-05. Перенос файлов не изменяет поведение соединения, формат профилей или статус готовности нового WG/AWG runtime. Старые forwarding/shim-копии не оставлены.
Android
app/src/main/java/io/github/zapretkvn/android/
├── vpn/ сервис, контроллер, состояние и recovery VPN
├── engines/
│ ├── singbox/ libbox setup, iterators, selector reconciliation
│ └── hysteria/ runtime/recovery contract
├── network/ Android DNS, underlying network, bootstrap
│ └── probes/ health, latency, ping, external IP; services/ — доступность
│ сервисов (сессия VPN и проверка без VPN); ProbeLane — общая
│ полоса проб: подключение > задержки/скорость > сервисы
├── platform/ Android TUN/socket adapter и системная VPN policy
├── apps/ обнаружение/выбор приложений, per-app scope, ViewModel
├── diagnostics/ исходные ошибки, журнал, метрики и экспорт
├── profiles/ хранение и редактирование профилей
├── importer/ импорт ключей, QR и подписок
├── config/, routing/ native JSON и правила
├── updates/ обновления приложения
└── ui/ AppRoot, ZapretApp (редактор JSON), nav/, UiSettingsStore и
адаптеры `*Route.kt`: связывают ViewModel/AppDependencies/
VpnController с экранами из :feature:*
core/
├── model/ типы значений, которые читает UI: состояние VPN, профили,
│ маршруты, приложения, диагностика, настройки, обновления
│ (пакеты `io.github.zapretkvn.android.*` сохранены); без Compose
├── ui-model/ чистые форматтеры и тексты (без Android; читает только :core:model)
└── designsystem/ тема, токены, общие Compose-компоненты, иконки, флаги,
release notes, PresetPicker, DiagnosticShareButton
feature/ экраны, презентеры и тесты вкладок; зависят только от :core:*
├── home/ Главная + плашка обновления (`ui.home`, `ui.update`)
├── servers/ Серверы и Профили (`ui.servers`)
├── routing/ Маршруты и выбор приложений (`ui.routing`, `ui.apps`)
└── settings/ Настройки и их страницы (`ui.settings`)
ZapretVpnService и ZapretQuickSettingsTileService остаются в пакете vpn:
их имена используются Android, поэтому перенос внутренностей не меняет
системные ComponentName, applicationId, профили и сохранённые настройки.
Четыре движка сохраняют прежние границы: sing-box исполняет routing/DNS и владеет
единственным системным TUN; Xray, Hysteria и Amnezia WG/AWG обслуживают свой
transport. Встроенные Go-адаптеры изменяются через core-patches. Пустые
Kotlin-пакеты Xray/Amnezia не создаются. Для движков и рантайма отдельные
Gradle-модули тоже не создаются; исключения — core/model, UI-модули
core/ui-model, core/designsystem и feature/*: они не знают про сервис VPN,
сторы, ViewModel и AppContainer.
Существующие app-updater, network-bootstrap, wireguard-import
остаются независимыми библиотеками. Тесты перенесённых компонентов также
распределены по соответствующим пакетам.
Windows
В xray_fluent оставлены только корневые __init__.py и constants.py.
Код сгруппирован по application, engines/<core>, profiles, importer,
diagnostics, network, platform/windows, updates, ui.
Go-реле — самостоятельный модуль runtime/amnezia.
Проверка структуры
scripts/verify-project.sh, :app:testDebugUnitTest,
:app:assembleDebugAndroidTest. Windows выполняет свой полный host-набор.
ADB необязателен; сборка instrumentation APK не считается device-прогоном.
Публикация stable и функциональная приёмка нового WG/AWG — отдельные gates.
Модули Compose-интерфейса
:app ──► :feature:{home,servers,routing,settings} ──► :core:designsystem ──► :core:ui-model ──► :core:model
:app ──► :app-updater ──► :core:model
:app ──► :core:{designsystem,ui-model,model}, :network-bootstrap, :wireguard-import
:core:model— только данные, enum, sealed-типы и тривиальные чистые функции (форматирование состояния,VpnErrorExplainer, каталог сервисов). Пакеты прежние, поэтому импорты в:appне менялись. Типы обновлений (UpdateState,UpdateCandidate, …) вынесены из:app-updater, он зависит от:core:model.- Если тип смешивал данные и логику, данные вынесены в
core/model, а логика осталась в:appрасширением (PersistedServerLatency.hint()) или реализацией интерфейса (ImportPreviewState : ImportPreview). :feature:*содержат*Screen, презентеры/мапперы и их JVM-тесты.*Route.ktи всё, что требует ViewModel,AppDependencies,VpnController,BuildConfig(лаунчеры импорта QR,AppPickerScreen,SettingsPageRoutes), остаётся в:app. Сведения о сборке экранам настроек передаётAppInfo(создаётся в:app).scripts/verify-project.shзапрещает:feature:*и:core:*зависеть от:app(проверкаbuild.gradle.kts) и импортировать изfeature/**рантайм VPN, ViewModel,AppContainer,AppDependencies,BuildConfig.- JVM-тесты запускает
./gradlew testDebugUnitTest(все модули); задача:app:testDebugUnitTestпо-прежнему работает.