УВАГА: Термінал агента не працює. Не виконуй жодних команд (dotnet build, dotnet restore, dotnet run, встановлення NuGet-пакетів тощо) самостійно. Якщо для задачі щось треба встановити, оновити чи запустити — напиши це явним окремим пунктом "Потрібно виконати вручну:" в кінці відповіді для цієї задачі, і не намагайся обійти це через bash/термінал. Реалізуй дві задачі в FoxBrowser. Роби послідовно, кожну — окремим описом, що змінено і як перевірити вручну (агент працює в Linux sandbox без dotnet/WPF runtime — фінальний тест виконує користувач на Windows). ## 1. Діагностика й виправлення кнопки "Розширення" Кнопка налаштувань розширень (`ExtensionsSettingsWindow`) працює неправильно. Перевір по черзі всі гіпотези нижче, знайди реальну причину в коді (не вигадуй, яка з них правильна, — прочитай файли й перевір), і виправ саме те, що підтвердиться. Якщо підтвердиться кілька — виправ усі. ### 1a. Recovery-fallback environment без AreBrowserExtensionsEnabled - Знайти в `MainWindow`/`TabManager` весь код навколо recovery-гілки з `NEXT_AGENT_GUIDE`/інструкції ("Startup recovery fix — 0x8007139F") — місце, де при HRESULT `0x8007139F` створюється запасний `CoreWebView2Environment` з тимчасовою user-data folder. - Перевірити: чи цей запасний environment створюється через ту саму функцію/той самий `CoreWebView2EnvironmentOptions` з `AreBrowserExtensionsEnabled = true`, що й основний, чи через окремий шматок коду, де цей прапорець забули виставити. - Якщо прапорець не потрапляє в recovery-гілку — винести створення `CoreWebView2EnvironmentOptions` в один спільний метод/константу, яку використовують і основний, і recovery шлях, щоб розбіжність стала неможливою в принципі, а не просто додати прапорець ще раз у другому місці. - Додати явний лог/статус (напр. поле `bool ExtensionsAvailable` на TabManager чи MainWindow), який ExtensionsSettingsWindow може прочитати при відкритті — і якщо `false` (бо стартанули в recovery-режимі), показати користувачу зрозуміле повідомлення в самому вікні ("Розширення недоступні в цьому сеансі — застосунок запустився в режимі відновлення профілю, перезапусти FoxBrowser"), а не порожній список без пояснень. ### 1b. IsEnabled read-only і биндинг чекбокса - Знайти XAML розмітку списку розширень в `ExtensionsSettingsWindow.xaml`. - Перевірити: чи `IsChecked` чекбокса прив'язаний напряму двостороннім біндингом до `Extension.IsEnabled` (read-only властивість), чи через `Checked`/`Unchecked` event-обробник (або Command), що явно викликає `await extension.EnableAsync(bool)`. - Якщо це прямий `TwoWay`-біндинг на read-only властивість — замінити на `OneWay`-біндинг для відображення поточного стану + окремий `Click`/`Checked`/`Unchecked` обробник, який викликає `EnableAsync()`, чекає результат, і тільки після успіху оновлює UI-стан (checkbox), а при помилці — повертає checkbox у попередній стан і показує повідомлення. ### 1c. FolderBrowserDialog без owner-вікна - Знайти виклик `FolderBrowserDialog`/`OpenFileDialog` для "Додати розширення" в `ExtensionsSettingsWindow.xaml.cs`. - Перевірити, чи передається owner-handle: `new System.Windows.Interop.WindowInteropHelper(this).Handle` через `IWin32Window`-обгортку (WinForms-діалог вимагає `IWin32Window`, не голий `IntPtr` — якщо ще нема обгортки-хелпера, додати простий `NativeWindowWrapper : IWin32Window`). - Якщо owner не передається — додати, щоб діалог відкривався поверх `ExtensionsSettingsWindow`, а не міг ховатись позаду. ### 1d. Options-сторінка розширення через спільний WebView2 - Знайти обробник кнопки "Налаштування" (per-extension), що відкриває `chrome-extension:///options.html`. - Перевірити: чи ця навігація йде через ТОЙ САМИЙ спільний `CoreWebView2`, яким керує `TabManager` для звичайних вкладок, чи через окремий `CoreWebView2Controller`, створений безпосередньо в `ExtensionsSettingsWindow`. - Якщо використовується спільний контрол — це помилка архітектури: клік по "Налаштування" в діалозі може непомітно перекидати активну вкладку користувача в головному вікні. Виправити: створити в `ExtensionsSettingsWindow` власний ізольований `CoreWebView2Controller` (з того самого `CoreWebView2Environment`, щоб профіль/розширення збігались) — тільки для options-сторінок, ніколи не займаючи головний спільний WebView2. Після кожного виправленого пункту (1a-1d) — короткий підсумок і ручний тест-сценарій для Windows. ## 2. Звук WebView2 у Volume Mixer як "FoxBrowser" Додати `Core/AudioSessionLabeler.cs`, який перейменовує WASAPI audio-сесії власних дочірніх WebView2-процесів на "FoxBrowser" з іконкою застосунку, БЕЗ ризику торкнутись чужих WebView2-сесій (Teams, Outlook, системний Edge). - Додати NuGet-пакет `NAudio` (зазнач це явно в "Потрібно виконати вручну" — сам пакет не встановлюй, тільки допиши `` в `.csproj` вручну і попроси користувача зробити `dotnet restore`). - Клас має: 1. Відстежувати список PID усіх дочірніх `msedgewebview2.exe`-процесів, які належать саме FoxBrowser (ті самі, що вже прив'язані через Job Object з попередньої задачі про дерево процесів — переюзати ту логіку, не дублювати). 2. Через `NAudio.CoreAudioApi.MMDeviceEnumerator` отримати default render endpoint (`eRender`, `eMultimedia`), і його `AudioSessionManager`. 3. Підписатись на подію нової сесії (`AudioSessionManager.SessionCreated` в NAudio, або еквівалент `IAudioSessionNotification.OnSessionCreated` якщо в NAudio такого немає в потрібній версії — перевір API конкретної версії пакету, яку додаси). 4. У обробнику нової сесії: якщо `session.GetProcessID` входить у список PID FoxBrowser — викликати `session.DisplayName = "FoxBrowser"` і `session.IconPath = Path.Combine(AppContext.BaseDirectory, "foxbrowser.ico")` (або еквівалентні NAudio-методи `SetDisplayNameAsync`/властивості — перевір актуальний API пакету). 5. **Критично:** ці властивості НЕ переживають життя об'єкта сесії (задокументована поведінка WASAPI) — тому одноразового виклику при старті недостатньо. Логіка з пункту 3-4 має спрацьовувати на КОЖНУ нову сесію протягом усього часу роботи FoxBrowser, не тільки на старті. 6. НІКОЛИ не застосовувати `DisplayName`/`IconPath` до сесії, чий PID не входить у явно відстежуваний список власних дочірніх процесів — це і є захист від зачіпання чужих `msedgewebview2.exe` на машині користувача. - Покласти файл `foxbrowser.ico` в корінь проєкту поруч з іншими іконками (якщо такого файлу ще нема в репозиторії — створи заглушку-примітивну іконку і явно напиши користувачу в "Потрібно виконати вручну", що варто замінити на нормальну). - Викликати ініціалізацію `AudioSessionLabeler` один раз при старті застосунку (напр. в `MainWindow` після успішної ініціалізації `TabManager`, коли вже відомий перший дочірній PID). Ручний тест Windows: 1. Запустити FoxBrowser, відкрити вкладку з YouTube, почати відтворення. 2. Відкрити Volume Mixer (правий клік на іконку гучності в треї Windows → Open Volume mixer, або через Settings → System → Sound → Volume mixer). 3. Перевірити, що застосунок у списку показаний як "FoxBrowser" з іконкою застосунку, а не як "Microsoft Edge WebView2"/msedgewebview2.exe. 4. Переключитись на іншу вкладку, знову увімкнути звук на новій — перевірити, що лейбл лишається "FoxBrowser" і для нової audio-сесії (не тільки для першої). 5. Паралельно запустити щось інше з WebView2 на цій же машині (напр. Microsoft Teams, якщо є), перевірити, що ЙОГО лейбл у Volume Mixer НЕ змінився і лишився своїм — це підтверджує, що фільтр по PID працює правильно й не займає чужі процеси.