# Промт для агента: FoxBrowser — легкий фоновий браузер ## Задум і чесна оцінка реалістичності **Три цілі проєкту:** 1. Низьке споживання CPU/RAM порівняно зі звичайними браузерами. 2. Вікно завжди позаду всіх інших вікон (як "приліплений" віджет, а не звичайне вікно застосунку). 3. Не "роздувається" з часом, коли грає фонова музика/відео (напр. плейлист на YouTube з однією вкладкою). 4. (Другий етап) Вбудований VPN через WireGuard-тунель, без потреби в окремому клієнті. **Важлива чесна засторога перед стартом:** писати власний рушій рендерингу HTML/CSS/JS (як Blink чи Gecko) — це багаторічна робота команд у сотні людей, нереалістично для одного проєкту. Правильний шлях — **не змагатися з Chromium рушієм**, а взяти вже готовий системний рушій (Microsoft Edge WebView2 на Windows) і виграти на рівні: відсутності власної копії Chromium в кожному інсталяторі (Electron тягне ~150+ МБ свого Chromium, WebView2 використовує вже встановлений у системі Edge Runtime), мінімалістичного "chrome" браузера без важкої екосистеми розширень, агресивного керування вкладками/пам'яттю, і унікальних UX-фіч (always-on-bottom, audio-only режим). Це дає реальний, чесний виграш у легкості — але базове споживання пам'яті на сторінку не буде на порядок меншим за сам Edge, бо рушій той самий. ## Рекомендований стек - **Windows-first, C#/.NET 8 (WPF) + Microsoft.Web.WebView2** — обрано для консистентності з попереднім OCR-проєктом (той самий стек, ті самі патерни Win32-інтеропу для системних фіч), і тому що WebView2 — найлегший шлях отримати сучасний рушій без бандлингу власного Chromium. - Альтернатива, якщо потрібна кросплатформність з нуля: Rust + Tauri v2 (теж використовує системний WebView, а не власний Chromium) — складніше по стеку, але менший бінарник і нативна швидкість shell-коду. ## Функціональні вимоги ### 1. Базовий shell браузера - Мультивкладковість: кожна вкладка — окремий `CoreWebView2` контролер (WebView2 підтримує кілька `CoreWebView2Environment`/профілів у одному процесі-хості). - Мінімалістичний UI: рядок вкладок, адресний рядок, кнопки назад/вперед/оновити — без важкої панелі закладок/історії з великою кількістю віджетів (легкість — і візуальна, і по ресурсах). - Системний трей: згортання в трей замість закриття, іконка з контекстним меню (Show/Hide, Play/Pause якщо є активна медіа-вкладка, Exit). ### 2. Always-on-bottom (вікно завжди позаду) - Реалізується через Win32 API, а не WPF-властивості: `SetWindowPos(hwnd, HWND_BOTTOM, ...)` замість звичного `HWND_TOPMOST`. - **Ключова складність:** Windows постійно "підіймає" активне вікно наверх при фокусі/кліку, тому просто одноразовий `HWND_BOTTOM` не втримає вікно ззаду. Потрібен або: (а) хук на `WM_WINDOWPOSCHANGING`/`WM_ACTIVATE` для повторного примусового `SetWindowPos(HWND_BOTTOM)` щоразу, коли ОС намагається підняти вікно, або (б) `SetWinEventHook` на `EVENT_SYSTEM_FOREGROUND`, який відстежує зміну активного вікна і одразу опускає FoxBrowser назад вниз z-order. Задокументуй обраний підхід і протестуй, що вікно не "мигає" і не краде фокус у користувача під час гри музики. - Клік по вкладці/елементу керування в самому FoxBrowser (напр. пауза музики) має працювати без переведення вікна на передній план — тобто вікно позаду, але клікабельне (`WS_EX_NOACTIVATE` для сценаріїв, де фокус не потрібен, або контрольоване тимчасове підняття тільки коли користувач свідомо клікає в вікно). - Гаряча клавіша для "тимчасово підняти на передній план" (напр. коли треба щось вибрати в плеєрі), потім вікно саме повертається вниз. ### 3. Захист від "роздування" пам'яті з часом - **Моніторинг**: фоновий таймер кожні N хвилин читає RAM/CPU процесу WebView2 (через `Process.WorkingSet64` для дочірніх процесів WebView2 — у них окремі `msedgewebview2.exe` процеси на renderer/GPU). - **Watchdog для довгограючих вкладок**: якщо пам'ять конкретної вкладки перевищує поріг (наприклад, зросла вдвічі відносно початкового рівня після завантаження) — виконати "м'який" reload сторінки, попередньо зберігши стан програвання через JS injection (`ExecuteScriptAsync`): зчитати з `document` поточний час відео/треку, назву плейлиста/позицію, після reload — виконати JS, який перемотує на збережену позицію і продовжує відтворення. Користувач в ідеалі навіть не помітить короткого "заїкання" звуку. - **Suspend неактивних вкладок**: вкладки, які не видно і не грають аудіо, вивантажувати (закривати `CoreWebView2Controller`, лишаючи тільки URL+заголовок+favicon у пам'яті), і відновлювати повний рендер лише при переключенні на них — аналогічно "sleeping tabs" в Edge/Chrome, тільки агресивніше за замовчуванням. - **"Music Mode" (аудіо-only режим)** — головна фіча проти роздування на музичних плейлистах: для розпізнаних медіа-сайтів (YouTube, SoundCloud тощо) пропонувати режим, де відеодоріжка не рендериться взагалі (сторінка завантажується, але відеоелемент приховується/призупиняється у видимості, звук іде далі через Web Audio) — це прибирає найважчу частину навантаження (декодування й рендер відеокадрів), лишаючи тільки аудіодекодування, яке на порядки дешевше по CPU/GPU. Технічно: CSS/JS ін'єкція, яка ховає `