windowcapture
исходный код / CODE_ANALYSIS.md

CODE_ANALYSIS.md

188 строк · 28,988 байт · модуль Docs
  1# WindowCapture — Анализ кодовой базы
  2
  3> Рабочий документ. Начат: 2026-06-03. Статус: **Фаза 1 завершена — картирование + первичный аудит**.
  4> Идентификаторы кода — verbatim (англ.), проза — RU.
  5> Теги достоверности находок: ✅ проверено лично · 🔍 кандидат (нашёл агент-картограф, не верифицировано построчно) · ℹ️ инфо.
  6
  7---
  8
  9## 0. Резюме (TL;DR)
 10
 11**WindowCapture** — это уже не «скриншотер», а **монолит-комбайн** на .NET Framework 4.0 / WinForms (~94 файла, ~33 750 строк C# + нативный C++ APO). В одном `.exe` живут: захват экрана с авто-детектом регионов → GPU-редактор аннотаций (Direct2D) → экспорт в Word через COM + AI-описания (Gemini) → плюс **отдельные крупные подсистемы**: аудиоплеер, видеоплеер, запись экрана (H.264/WMV/MJPEG), Soundpad с нативным аудио-драйвером APO, менеджер буфера обмена, загрузчик медиа с веб-страниц, поиск файлов по MFT, и **T9/проверка орфографии на нескольких нейросетях**, перехватывающая каждое нажатие клавиши глобальным хуком.
 12
 13- **Сборка**: ✅ компилируется чисто (`build.ps1`, exit 0), 13 предупреждений (неиспользуемые поля).
 14- **Качество**: ядро (захват/редактор/рендеринг) — зрелое и продуманное. Периферия (Soundpad/APO, Clipboard, Search) — экспериментальная/недо-интегрированная.
 15- **Главный архитектурный вывод**: монолит надо **резать на модули/продукты** (см. §8). Ваша интуиция «отдельно скриншотер, отдельно остальное» — верна, и границы видны чётко.
 16- **Топ-баги**: отсутствие TLS 1.2 (AI/загрузки), утечки Word COM-объектов, хардкод-путь в APO, секреты (Gemini key) в открытом виде.
 17
 18## 1. Технический стек
 19- **C# / .NET Framework 4.0**, компиляция `csc.exe` (`Framework64\v4.0.30319`). Фактически исполняется на установленном 4.x runtime (на этой машине — Win10).
 20- **WinForms** + **GDI+** + **Direct2D/DirectWrite** (GPU) + **DWM** (стекло/блюр окон).
 21- WPF-сборки подключены только ради **UIAutomation** (чтение текста под курсором, парсинг адресной строки браузера).
 22- COM-интеропы: Direct2D, WASAPI, Media Foundation, DirectShow, Microsoft Word.
 23- Нативный **C++ APO** (Audio Processing Object) для Soundpad: `APO/SoundpadAPO.cpp``.dll`, общается с C# через shared memory (`Global\WC_Soundpad_Buf`).
 24- Сборка: `build.ps1` (авто-перечисление `.cs`, кроме `Tools/`, `bin/`) — **канонический**; `compile.ps1` — хардкод-список (риск рассинхрона) и заканчивается `Read-Host` (не для CI).
 25
 26## 2. Масштаб
 27- **94** `.cs` файла, **~33 750** строк (без `bin/`). Плюс `Tools/` (тренеры нейросетей, отдельные `Main`).
 28- Крупнейшие: `TextProcessor` 3055, `WordSidePanel` 1718, `AudioPlayerForm` 1561, `EditorForm.VideoPlayer` 1290, `SettingsDialog` 1204, `WordIntegration` 1180, `GeminiIntegration` 998, `AnnotationCanvas` 928, `ClipboardForm` 896, `Mp4Writer` 883, `SoundpadForm` 882, `D2DRenderer` 829, `Detector` 795, `MediaParser` 761.
 29- `Data/` несёт десятки МБ словарей/моделей (`dict_ru.txt`, `charembed.bin` ~17МБ, `morph.bin` и т.д.).
 30
 31## 3. Расхождения с документацией — ✅ НАЙДЕНО
 32- `ARCHITECTURE.md` заявляет «73 файла, ~22 400 строк» → факт **94 / ~33 750**. Документация устарела.
 33- `AudioPlayerForm` описан как 7 partial-файлов → фактически **один** файл 1561 строка.
 34- В доке **отсутствуют** подсистемы: `Recording/`, `SoundpadForm`+`APO`, `ClipboardForm`, `SearchForm`, `RecordingOverlay`, `DirectShowInterop`, весь spell-стек (`TextProcessor`, `SymSpell`, `CompactSpell`, `CharNN`, `SpellNet`, `CharEmbedNet`, `Seq2Spell`, `GruSpellNet`, `BigramLM`, `RulesEngine`, `MorphAnalyzer`, `CursorReader`, `BloomFilter`).
 35
 36---
 37
 38## 4. Карта подсистем
 39
 40### 4.1 Захват экрана и точка входа
 41`Program.cs` → (файл-аргумент → viewer `EditorForm`/`AudioPlayerForm`; иначе single-instance Mutex → `TrayApp`).
 42`App/Controller.cs` ставит **глобальные low-level хуки** клавиатуры и мыши → по комбинации запускает `FrozenOverlay` (полноэкранная «заморозка»), который через `Detection/Detector` (Sobel + flood-fill) авто-выделяет UI-элемент/окно/регион → открывает `EditorForm`. `Native/WinApi.cs` — все P/Invoke (user32/dwmapi/gdi32/ole32/mf*/winmm/shcore).
 43
 44### 4.2 Рендеринг / эффекты / glass-UI
 45`Effects/D2DRenderer.cs` — статический GPU-движок: HWND-таргет + offscreen-композиция + GDI-interop для слоя аннотаций; кэши кистей/шрифтов; восстановление при device-loss. `Effects/EffectLayer.cs` + `ImageEffects.cs` — CPU-блюр для экспорта (box/gaussian/motion, inside/outside). `Native/Direct2D.cs` — COM-интерфейсы. Helpers: `BlurHelper` (DWM acrylic/blur-behind), `GlowHelper`, `ColorHelper`, `FontHelper` (embed Bebas Neue), `BitmapHelper`. `UI/Controls/*` — тёмные «стеклянные» контролы (Dark*Numeric, DarkComboBox, GlassScrollPanel).
 46
 47### 4.3 Редактор (partial-классы `EditorForm.*`) + холст
 48`EditorForm` разнесён на 13 partial-файлов (.Zoom/.Editing/.Keyboard/.GlassButtons/.Paint/.WindowChrome/.Render/.WordExport/.VideoPlayer/.VideoPaint/.ViewerMode/.Indicators) + ядро. `UI/AnnotationCanvas.cs` — поверхность рисования: мышь/жесты, D2D/GDI-пути, эффект-слои, zoom/pan (статичный viewport, `drawScale/drawX/drawY`). Аннотации: `HighlightRect`, `ArrowAnnotation` (кубический Безье), `NumberMarker`, `TextBlock` (3D/тень/контур), `CommentBubble`. Undo — простой стек по типам.
 49
 50### 4.4 Word + AI (Gemini)
 51`Integration/WordIntegration.cs`**late-bound COM-автоматизация** Word (вставка картинок с подписью/описанием, титульник, нумерация, извлечение/замена текста). `GeminiIntegration.cs` — REST к Google Gemini с ротацией ключей/моделей (fallback на 16+ моделей при 429), ручной парсинг JSON. `DocxRenderer.cs` — превью .docx без Word. UI: `WordSidePanel` (1718 строк — основной рабочий сценарий!), `WordExportDialog`, `OriginalizePreviewDialog`. Персист: `TitlePageData` (JSON), `GeminiSettings`.
 52
 53### 4.5 Орфография / T9 / OCR-контекст
 54`Helpers/TextProcessor.cs` (3055) — оркестратор: перехват клавиш → буфер слов → пайплайн `RulesEngine → CompactSpell(RU)/SymSpell(EN) → CharNN scoring → CharEmbedNet → BigramLM → CascadeRepair → вставка через WM_CHAR`. `CursorReader` читает контекст под курсором (UI Automation, STA). Активно интегрирован в `Controller`. **Несколько нейромоделей мертвы/отключены** (см. §6 D1).
 55
 56### 4.6 Аудиоплеер + Soundpad + APO
 57`UI/AudioPlayerForm.cs` (1561) — отдельное приложение для аудио (MCI playback, декод вейвформы через Media Foundation, ID3/FLAC/M4A метаданные + обложка, доминантный цвет). `UI/SoundpadForm.cs` + `APO/SoundpadAPO.cpp` — инъекция звуков в виртуальный микрофон через системный APO (требует админ-прав, правка реестра `MMDevices/.../FxProperties`, хардкод-CLSID). **Авто-установка APO отключена** в `TrayApp` — экспериментально.
 58
 59### 4.7 Видео + запись экрана + загрузка медиа
 60Видеоплеер: тройной fallback DirectShow(EVR) → IMFMediaEngine → WebBrowser(HTML5), оверлей-контролы, JS-мост (`VideoScriptBridge`), правка реестра `FEATURE_BROWSER_EMULATION`. Запись: `VideoRecorder` (GDI BitBlt + WASAPI-аудио) → `Mp4Writer` (H.264/WMV/MJPEG) / `AviWriter`, `RecordingOverlay`. Загрузка: `MediaParser` (Clipboard/UIA/HTML-regex/IAccessible) → `MediaDownloadDialog`. **Запись экрана — рабочая** (подтверждено логами в `bin/VideoLog.txt`).
 61
 62### 4.8 Буфер обмена / поиск / диалоги
 63`ClipboardForm` — слушатель `WM_CLIPBOARDUPDATE`, история в памяти (50 элементов, без персиста). `SearchForm` — скан MFT (USN), полнотекстовый поиск по именам. `SettingsDialog` (1204) — 5 вкладок, 40+ опций. Малые диалоги: `KeyCaptureDialog`, `TextBlockPopup`, `DarkColorPicker`.
 64
 65---
 66
 67## 5. Дерево зависимостей (что куда обращается)
 68
 69```
 70Program.Main
 71├─ (file arg) ──► EditorForm(path) | AudioPlayerForm(path)
 72└─ (tray) ──► TrayApp
 73      ├─ Controller  ── глоб. хуки клав/мышь
 74      │    ├─ FrozenOverlay ──► Detector ──►(регион)──► EditorForm(bitmap)
 75      │    ├─ TextProcessor ──► SymSpell, CompactSpell, CharNN, CharEmbedNet,
 76      │    │                    BigramLM, RulesEngine, BloomFilter, CursorReader
 77      │    ├─ VideoRecorder ──► Mp4Writer/AviWriter, RecordingOverlay, WASAPI
 78      │    ├─ ClipboardForm        (Ctrl+V hold)
 79      │    └─ MediaParser ──► MediaDownloadDialog
 80      ├─ SearchForm  (MFT)
 81      ├─ SoundpadForm ──► APO(native), WASAPI, MediaFoundation
 82      └─ SettingsDialog ──► Settings, KeyBindings, DarkColorPicker
 83
 84EditorForm (13 partials)
 85 ├─ AnnotationCanvas ──► D2DRenderer(GPU)│GDI-fallback ; EffectLayer ──► ImageEffects
 86 │     └─ Models: HighlightRect, ArrowAnnotation, NumberMarker, TextBlock, CommentBubble, UndoAction
 87 ├─ WordSidePanel ──► WordIntegration(Word COM), GeminiIntegration(HTTPS)
 88 │     └─ TitlePageData(JSON), GeminiSettings, DocxRenderer
 89 └─ D2DRenderer ──► Native/Direct2D, Native/WinApi(DWM)
 90
 91ОБЩИЙ ФУНДАМЕНТ (используется почти всеми):
 92  Settings, KeyBindings · Native/WinApi · Effects/* · Helpers/{Bitmap,Color,Font,Blur,Glow} · UI/Controls/*
 93```
 94
 95---
 96
 97## 6. Находки: баги, риски, мёртвый код
 98
 99### Подтверждено лично
100- **B1 ✅ [Высокая] Нет настройки TLS 1.2.** Поиск `SecurityProtocol/ServicePointManager/Tls12` по всему репо — 0 совпадений. На .NET Framework дефолт — TLS1.0. `GeminiIntegration` (HTTPS) и загрузки в `MediaParser`/`MediaDownloadDialog` могут падать с «Could not create SSL/TLS secure channel» в зависимости от ОС/рантайма. **Фикс**: `ServicePointManager.SecurityProtocol = Tls12 | Tls11 | Tls` в `Program.Main` (1 строка).
101- **B2 ✅ [Средняя] Хардкод пути пользователя в C++ APO.** `APO/SoundpadAPO.cpp:57``CreateFileW(L"C:\\Users\\Admin\\AppData\\Local\\WindowCapture\\apo_native.log")`. У любого не-`Admin` лог APO не пишется. C#-сторона (`SoundpadForm.cs:503`) делает правильно через `Environment.GetFolderPath(LocalApplicationData)`. **Фикс**: в C++ через `GetEnvironmentVariableW(L"LOCALAPPDATA", ...)`.
102- **B3 ✅ [Низкая] Мёртвые поля (предупреждения сборки).** `EditorForm`: `videoSeeking, volumeSeeking, lmbDown, rmbDown, lmbStartX, rmbStartX, rmbSwitched`. `SearchForm`: `d2dReady, renderPanel, treeScroll, treeScrollTarget, TFF`. `SoundpadForm`: `apoBindAttempted`. Удалить.
103- **B4 ✅ [Низкая] `compile.ps1`** заканчивается `Read-Host` (виснет в headless/CI) и дублирует список файлов хардкодом. Канон — `build.ps1`; `compile.ps1` лучше удалить или свести к вызову `build.ps1`.
104- **B12 ✅ [Низкая] Per-paint аллокации в `AnnotationCanvas`.** `DrawMarker/DrawArrowWithControlPoints/DrawTextBlock/DrawBubble` создают `new Pen/SolidBrush/StringFormat` на каждой отрисовке (60 fps × N аннотаций) → GC-churn. Кэшировать переиспользуемые объекты.
105- **ℹ️ Ложная тревога (НЕ баг):** симметрия `Settings.Load/Save/ResetDefaults` в порядке — все поля присутствуют во всех трёх (см. комментарий `Settings.cs:171`, баг уже исправлен ранее). Зафиксировано как пример необходимости верификации.
106- **ℹ️ Логи в репозитории:** `bin/VideoLog.txt` (500+ строк), `bin/SettingsLog.txt` — рантайм-логи без ротации, не должны попадать в репо (добавить в `.gitignore`).
107
108### Кандидаты (нашли агенты; требуют построчной проверки в Фазе 2)
109- **B5 🔍 [Высокая] Утечки Word COM-объектов** (`WordIntegration.cs`). Late-bound `InvokeMember` возвращает RCW (`Range/Font/Selection/Documents`), которые не освобождаются; `GC.Collect()` использован как «костыль». Классическая утечка Office-автоматизации → зависший `WINWORD.EXE`, рост памяти.
110- **B6 🔍 [Средняя] Секреты в открытом виде.** Gemini API-ключи хранятся в JSON (`TitlePageData`) без шифрования и, возможно, попадают в логи. Рекомендуется DPAPI (`ProtectedData`).
111- **B7 🔍 [Средняя] Сеть на UI-потоке.** Часть путей Gemini и `MediaParser.ParsePageHtml` (`WebClient.DownloadString` без таймаута) могут морозить UI при зависании сети.
112- **B8 🔍 [Средняя] Temp-файлы записи** (`%TEMP%\WindowCapture_*.mp4`) не удаляются на путях с ошибкой/краше.
113- **B9 🔍 [Низкая–средняя] Дисбаланс disposal** (накопительная утечка памяти в долгих сессиях): COM в `AudioPlayerForm` (MF reader/buffers), `MemoryStream`/GIF в `EditorForm.ViewerMode`, `Font` поля в `TextBlock`/`CommentBubble`, `GetDC/ReleaseDC` в `D2DRenderer` при исключении, таймеры/обработчики.
114- **B10 🔍 [Низкая] Буфер обмена без retry** (`ClipboardForm`) → редкие пропуски событий при `CLIPBRD_E_CANT_OPEN`.
115- **B11 🔍 [Низкая] `Detector.floodVisited[,]`** аллоцируется под размер первого экрана; при смене разрешения/монитора риск `IndexOutOfRange`.
116
117### Мёртвый код / экспериментальное
118- **D1 ✅ Отключённые нейромодели.** `Seq2Spell` + `GruSpellNet` закомментированы как «галлюцинируют» (`TextProcessor.cs:2255`). `SpellNet` 🔍 грузится, но не вызывается. → удалить 3 `.cs` + соответствующие `.bin` (~2.3 МБ) после проверки.
119- **D2 🔍 `forcedFix`** — ~1400 ручных правок-пар встроены прямо в `TextProcessor.cs`. Вынести в `Data/`-файл (данные ≠ код).
120- **D3 ✅ Soundpad/APO** — авто-установка отключена в `TrayApp` (комментарий). Решить: довести или вырезать.
121- **D4 🔍 ClipboardForm / SearchForm** — без персистентности; Search каждый запуск заново сканирует MFT. Похоже на «proof-of-concept».
122- **Дубли:** `HSBToColor/ColorToHSB` (≥2 места) · генераторы noise-текстуры (≥3 места) · `Dark*Numeric` контролы (~90% общего кода) · логика crop в 3 методах редактора · `VLog/WaveLog/Log` в разных файлах.
123
124---
125
126## 7. Возможности оптимизации
127- Кэш `Pen`/`Brush`/`StringFormat` в `AnnotationCanvas` (B12) и переиспользование — снять GC-нагрузку в 60-fps пейнте.
128- `Detector.GetMedianColor` аллоцирует `List<int>` на каждый пиксель — для 4K это миллионы аллокаций; использовать переиспользуемые буферы.
129- Shimmer/glow в `SettingsDialog` считает `sqrt` для всех label каждые 40 мс — батчить.
130- Noise-текстура регенерируется вместо кэша по ключу настроек.
131- Кэш result-ов `CharNN.NeuralScore` (сотни кандидатов на слово); предвычисленные эмбеддинги словаря.
132- Ленивая/фоновая инициализация spell-моделей (десятки МБ) — не блокировать первый ввод.
133
134## 8. Рефакторинг и выделение модулей  ← ключевое для «разделить скриншотер и остальное»
135
136Естественные границы (по дереву зависимостей слабая связанность уже есть — почти всё общается только через `Settings` и `Native/WinApi`):
137
138| Модуль | Что входит | Статус | Зависит от ядра |
139|---|---|---|---|
140| **WC.Core (shared)** | `Native/*`, `Effects/*`, `Helpers/{Bitmap,Color,Font,Blur,Glow}`, `UI/Controls/*`, `Models/{Settings,KeyBindings}`, `D2DRenderer` | фундамент | — |
141| **WC.Screenshot** (главный продукт) | `App/*`, `Detection/Detector`, `FrozenOverlay`, `EditorForm.*`, `AnnotationCanvas`, аннотации, `Word/Gemini`-экспорт | зрелый | Core |
142| **WC.MediaViewer** | `AudioPlayerForm`, `EditorForm.Video*`, MF/DirectShow interop, `MediaTypes` | зрелый | Core |
143| **WC.Recorder** | `Recording/*`, `RecordingOverlay`, `VideoRecorder` | рабочий | Core |
144| **WC.MediaDownloader** | `MediaParser`, `MediaDownloadDialog` | рабочий | Core |
145| **WC.Soundpad** | `SoundpadForm`, `APO/*`, WASAPI | экспериментальный | Core |
146| **WC.Clipboard** | `ClipboardForm` | экспериментальный | Core |
147| **WC.Search** | `SearchForm` | экспериментальный | Core |
148| **WC.TextAssist (T9/spell)** | весь spell-стек + `Data/`-модели (~десятки МБ) | зрелый, но **чужеродный** | Core (минимально) |
149
150**Рекомендация:** как минимум вынести **WC.TextAssist** (глобальный T9/орфография — отдельный класс задач, тянет десятки МБ моделей и глобальный хук) и **WC.Soundpad** (нативный драйвер, админ-права) из основного скриншотера. Это сразу уменьшит вес, поверхность багов и риски прав/антивируса для основного продукта. Дальше — по желанию разнести медиа-плеер/рекордер/загрузчик в плагины.
151
152## 9. Сборка и запуск
153- `build.ps1``bin/WindowCapture.exe`, exit 0. 13 warnings (неиспользуемые поля, см. B3).
154- Запуск/ручная проверка поведения (tray, захват, редактор) — **не выполнялись** (требуют GUI-сессии; запланировать).
155- `compile.ps1` для автоматизации непригоден (`Read-Host`).
156
157## 10. Открытые вопросы к автору
1581. **«Удалённая машина / GitHub»** — что именно: завести репозиторий на GitHub (+ возможно CI на GitHub Actions для сборки .NET 4.0)? перенести сборку/тесты на удалённую машину? пока только локально?
1592. **Куда направить Фазу 2**: (а) глубокий **верифицированный** аудит багов + починка подтверждённых; (б) проектирование **разделения на модули** (§8); (в) ресёрч форумов/отзывов конкурентов (Snipaste/ShareX/Greenshot/Lightshot) — чего годами не хватает людям.
1603. Язык/формат отчёта (сейчас — этот файл, RU) — оставить так?
161
162---
163
164## 11. Журнал Фазы 2 (2026-06-03)
165- Репозиторий: **https://github.com/teoplaydor/WindowCapture** (private). PR **#1** — живой трекер фиксов.
166- **B1 ИСПРАВЛЕНО** (`f0a2482`): TLS 1.2/1.1 включён в `Program.Main`. Сборка зелёная.
167- **B4 ИСПРАВЛЕНО** (`fe30863`): `Read-Host` убран из `compile.ps1` (headless/CI).
168- **B5 ПОДТВЕРЖДЕНО** (построчная верификация агентом): утечки Word COM реальны и массовые — ≈80+ RCW (`selection/range/font/paragraphFormat/inlineShapes/fields/...`) не освобождаются почти в каждом методе; корректно релизятся только `documents` (`:149`) и `templateDoc` (`:831`). `GC.Collect()` на `:1382–1388` — признанный костыль (есть комментарий-признание). Худшее — циклы по `Paragraphs`/`Fields`: `ExtractDescriptionsAndCaptions` (~`:1060`), `ApplyReplacements` (~`:1236`), `GetNextFigureNumber` (~`:436`) — per-item RCW × N. **Фикс**: `SafeRelease(ref obj)` + `try/finally` (LIFO), релиз per-item в конце итерации; отдельным PR с проверкой через реальный Word. → СЛЕДУЮЩИЙ крупный шаг.
169- ℹ️ **Уточнение к B3**: `videoSeeking`/`volumeSeeking` дают CS0649 = **читаются, но никогда не присваиваются** → вероятно **латентный баг** (состояние перетаскивания seek-bar никогда не включается, видеоплеер). Проверить перед удалением. Поля с CS0169 (`lmbDown/rmbDown/lmbStartX/rmbStartX/rmbSwitched`, `apoBindAttempted`, `treeScrollTarget`) — реально мёртвые, удалить безопасно.
170- **B3 сделано** (`6dec9b1`): мёртвые поля удалены, рудиментные `videoSeeking`/`volumeSeeking` свёрнуты (поведенчески эквивалентно). Warnings 13→4 (остаток — `SearchForm` мёртвый D2D-путь, отдельная тема).
171- **B5 частично** (`75c727b`): добавлен `SafeRelease`; read-only циклы `GetNextFigureNumber`/`GetLastDescription` освобождают per-item RCW. Мутирующие методы (`InsertImageWithCaption`/`InsertTitlePage`/`AddPageNumbering`/`ApplyReplacements`) + once-per-call транзиты — отложены до сессии с реальным Word. `GC.Collect` оставлен как страховка.
172- **B7 сделано** (`TimedWebClient`): таймаут 15с на сетевые вызовы `MediaParser` (`ParsePageHtml`, `DownloadFile`) — нет бесконечного виса/заморозки UI.
173- **Smoke-test**: `WindowCapture.exe <image>` (viewer-режим, без глобального хука) стартует без краша, окно живёт 5с, закрывается чисто.
174- ℹ️ **B11 — НЕ баг** (проверено): `Detector.SetScreen` переаллоцирует `floodVisited` и сбрасывает `w/h`/кэши при каждом вызове → рассинхрона при смене разрешения нет. Ещё одна ложная тревога агента.
175
176### Остаток (для следующих сессий)
177- **B5 (основное)** — освобождение COM в мутирующих методах Word; делать с открытым Word для проверки вставки/титульника/нумерации.
178- **B2** — хардкод пути в `APO/SoundpadAPO.cpp:57` (нужен MSVC для пересборки .dll).
179- **B6** — шифрование Gemini-ключа (DPAPI) + **отозвать утёкший ключ** в Google AI Studio (действие автора).
180- **SearchForm** — мёртвый «собственный D2D-путь» (4 warning'а): удалить поля+инициализацию или довести.
181- Стратегическое: ✅ ресёрч → `FEATURE_RESEARCH.md`; ✅ детальный план разделения → `MODULARIZATION_PLAN.md`.
182
183### Финальный статус автономной сессии (2026-06-03)
184Сборка **чистая (0 warnings, exit 0)**, smoke-test viewer-режима ок. Сделано и запушено (ветка `fix/audit-phase2`, PR #1, 10 коммитов): **B1** TLS, **B2** APO-путь, **B3** мёртвые поля, **B4** build, **B5-частично** (read-only Word COM), **B7** таймауты сети, очистка мёртвого D2D-пути `SearchForm` (warnings 13→0). Документы: `CODE_ANALYSIS`, `FEATURE_RESEARCH`, `MODULARIZATION_PLAN`. 3 ложные тревоги агентов отсеяны проверкой.
185**Шлюзовый остаток** (нужен внешний вход): B5-основное (тест с реальным Word), B2-проверка (пересборка APO в MSVC), B6 (ротация ключа Gemini — аккаунт автора), фичи OCR/scrolling (выбор OCR-движка).
186
187### Разделение на приложения + лаунчер (2026-06-03, реализовано)
188Монолит разнесён на **отдельные приложения-процессы** (`--screenshot`/`--textassist`/`--clipboard`/`--soundpad`/`--search`) + **лаунчер с круговым pie-меню** (`Ctrl+Alt+Space`). Сделано: `ControllerMode`-флаги (каждый процесс ставит только нужные хуки; дефолт `All` = полный режим без изменений), роутинг в `Program`, `TrayApp(AppMode)`, новые `AppMode`/`LauncherForm`/`LauncherApp`/`FormHostApp`. Все 6 режимов **стартуют без краша** (smoke-test); сборка чистая. Документация — `APPS_AND_LAUNCHER.md`. Это runtime-сепарация (одна exe, отдельные процессы); физический split на отдельные `.exe` + `WC.Core.dll` — следующий шаг (`MODULARIZATION_PLAN.md`). Нужна GUI-проверка: рендер меню, хоткей, поведение каждого приложения вживую.