"""Каталог правил: где в Windows копится кеш, мусор и остатки разработки. Пути записаны шаблонами с плейсхолдерами ``{LOCAL}``, ``{ROAMING}``, ``{HOME}``, ``{WINDIR}``, ``{PROGRAMDATA}``, ``{TEMP}``, ``{LOCALLOW}``, ``{PROGRAMFILES}``, ``{PROGRAMFILES86}``, ``{PUBLIC}``, ``{SYSTEMDRIVE}``. Поддерживаются glob-маски (``*``), поэтому одно правило покрывает все профили браузеров и все версии IDE сразу. """ from __future__ import annotations from dataclasses import dataclass, field from .model import Category, Risk @dataclass(frozen=True) class Rule: id: str title: str category: Category risk: Risk detail: str paths: tuple[str, ...] = () contents_only: bool = False # чистим внутренности, каталог оставляем needs_admin: bool = False processes: tuple[str, ...] = () # предупредить, если запущены min_size: int = 0 # не показывать мелочь files_only: tuple[str, ...] = () # маски файлов внутри paths C = Category R = Risk # --------------------------------------------------------------- Windows ---- WINDOWS_RULES: list[Rule] = [ Rule("win.temp.user", "Временные файлы пользователя", C.WINDOWS, R.SAFE, "Рабочая свалка установщиков и приложений. Занятые файлы пропускаются автоматически.", ("{TEMP}",), contents_only=True), Rule("win.temp.system", "Временные файлы системы", C.WINDOWS, R.SAFE, "C:\\Windows\\Temp — то же самое, но для служб. Нужны права администратора.", ("{WINDIR}\\Temp",), contents_only=True, needs_admin=True), Rule("win.update.download", "Кеш загрузок Windows Update", C.WINDOWS, R.LOW, "Скачанные пакеты обновлений. Уже установленные не нужны; система скачает заново, если потребуется.", ("{WINDIR}\\SoftwareDistribution\\Download",), contents_only=True, needs_admin=True), Rule("win.delivery", "Оптимизация доставки", C.WINDOWS, R.LOW, "Кеш P2P-раздачи обновлений другим ПК в сети. Часто вырастает до нескольких ГБ.", ("{WINDIR}\\ServiceProfiles\\NetworkService\\AppData\\Local\\Microsoft\\Windows\\DeliveryOptimization",), contents_only=True, needs_admin=True), Rule("win.old", "Windows.old (прошлая версия Windows)", C.WINDOWS, R.MEDIUM, "Полная копия старой системы после обновления. Удаление лишает возможности откатиться назад.", ("{SYSTEMDRIVE}Windows.old",), needs_admin=True), Rule("win.prefetch", "Prefetch", C.WINDOWS, R.LOW, "Данные предзагрузки приложений. После очистки первые запуски программ будут чуть медленнее.", ("{WINDIR}\\Prefetch",), contents_only=True, needs_admin=True), Rule("win.crashdumps", "Дампы аварийных завершений", C.WINDOWS, R.SAFE, "Снимки памяти упавших программ. Нужны только для разбора конкретного сбоя.", ("{LOCAL}\\CrashDumps", "{WINDIR}\\Minidump",), contents_only=True), Rule("win.memorydmp", "Полный дамп памяти (MEMORY.DMP)", C.WINDOWS, R.LOW, "Снимок всей оперативной памяти после BSOD — обычно равен объёму ОЗУ.", ("{WINDIR}\\MEMORY.DMP",), needs_admin=True), Rule("win.wer", "Отчёты об ошибках (WER)", C.WINDOWS, R.SAFE, "Очереди отчётов Windows Error Reporting.", ("{LOCAL}\\Microsoft\\Windows\\WER", "{PROGRAMDATA}\\Microsoft\\Windows\\WER"), contents_only=True), Rule("win.thumbcache", "Кеш эскизов и значков", C.WINDOWS, R.SAFE, "thumbcache_*.db / iconcache_*.db. Пересоздаётся проводником на лету.", ("{LOCAL}\\Microsoft\\Windows\\Explorer",), contents_only=True, files_only=("thumbcache_*.db", "iconcache_*.db")), Rule("win.fontcache", "Кеш шрифтов", C.WINDOWS, R.LOW, "Служебный кеш подсистемы шрифтов.", ("{WINDIR}\\ServiceProfiles\\LocalService\\AppData\\Local\\FontCache",), contents_only=True, needs_admin=True), Rule("win.inetcache", "Кеш Internet Explorer / WinINet", C.WINDOWS, R.SAFE, "Общесистемный HTTP-кеш, которым пользуются и многие desktop-приложения.", ("{LOCAL}\\Microsoft\\Windows\\INetCache",), contents_only=True), Rule("win.d3dcache", "Кеш шейдеров DirectX", C.WINDOWS, R.SAFE, "Скомпилированные шейдеры. Пересобираются при следующем запуске игры.", ("{LOCAL}\\D3DSCache", "{LOCAL}\\Microsoft\\DirectX Shader Cache"), contents_only=True), Rule("win.recycle", "Корзина", C.WINDOWS, R.MEDIUM, "Файлы, удалённые ранее. После очистки восстановить их уже нельзя.", ("{SYSTEMDRIVE}$Recycle.Bin",), contents_only=True), Rule("win.installer.patch", "Кеш патчей установщика Windows", C.WINDOWS, R.MEDIUM, "$PatchCache$ нужен для отката и восстановления MSI-программ.", ("{WINDIR}\\Installer\\$PatchCache$",), contents_only=True, needs_admin=True), Rule("win.panther", "Логи установки системы (Panther)", C.WINDOWS, R.SAFE, "Отчёты установщика Windows и драйверов.", ("{WINDIR}\\Panther", "{WINDIR}\\inf\\setupapi.dev.log"), contents_only=True, needs_admin=True), Rule("win.defender.history", "История проверок Windows Defender", C.WINDOWS, R.LOW, "Журнал сканирований антивируса. На саму защиту не влияет.", ("{PROGRAMDATA}\\Microsoft\\Windows Defender\\Scans\\History\\Service", "{PROGRAMDATA}\\Microsoft\\Windows Defender\\Scans\\History\\Results"), contents_only=True, needs_admin=True), Rule("win.clipboard", "Кеш перьевого/облачного ввода", C.WINDOWS, R.LOW, "Служебные данные InputPersonalization и истории буфера.", ("{LOCAL}\\Microsoft\\InputPersonalization\\TextHarvester",), contents_only=True), Rule("win.livekernel", "LiveKernelReports", C.WINDOWS, R.SAFE, "Дампы сбоев драйверов без полного BSOD.", ("{WINDIR}\\LiveKernelReports",), contents_only=True, needs_admin=True), Rule("win.downloadedinstall", "Downloaded Installations", C.WINDOWS, R.LOW, "Распакованные дистрибутивы старых установщиков.", ("{PROGRAMDATA}\\Downloaded Installations",), contents_only=True), Rule("win.hyperv.cache", "Кеш Microsoft Store / AppX", C.WINDOWS, R.SAFE, "Временные файлы доставки приложений из Store.", ("{LOCAL}\\Packages\\Microsoft.Windows.Search_cw5n1h2txyewy\\LocalState\\AppIconCache", "{LOCAL}\\Microsoft\\Windows\\Caches"), contents_only=True), ] # ------------------------------------------------------------- Логи --------- LOG_RULES: list[Rule] = [ Rule("log.windows", "Системные журналы Windows", C.LOGS, R.LOW, "C:\\Windows\\Logs — логи CBS, DISM, обслуживания компонентов.", ("{WINDIR}\\Logs\\CBS", "{WINDIR}\\Logs\\DISM", "{WINDIR}\\Logs\\MoSetup", "{WINDIR}\\Logs\\WindowsUpdate"), contents_only=True, needs_admin=True), Rule("log.perflogs", "PerfLogs", C.LOGS, R.SAFE, "Отчёты монитора производительности.", ("{SYSTEMDRIVE}PerfLogs",), contents_only=True, needs_admin=True), Rule("log.appdata", "Логи приложений в AppData", C.LOGS, R.SAFE, "Каталоги logs/ внутри данных установленных программ.", ("{ROAMING}\\*\\logs", "{LOCAL}\\*\\logs", "{LOCAL}\\*\\log"), contents_only=True, min_size=2 * 1024 * 1024), Rule("log.npm", "Логи npm/yarn", C.LOGS, R.SAFE, "_logs со stack trace неудачных установок пакетов.", ("{LOCAL}\\npm-cache\\_logs", "{ROAMING}\\npm-cache\\_logs"), contents_only=True), Rule("log.nvidia", "Логи и кеш NVIDIA", C.LOGS, R.SAFE, "Отчёты драйвера и телеметрии GeForce Experience.", ("{PROGRAMDATA}\\NVIDIA Corporation\\NvTelemetry", "{LOCAL}\\NVIDIA Corporation\\NvTelemetry", "{PROGRAMDATA}\\NVIDIA Corporation\\Downloader"), contents_only=True), ] # ---------------------------------------------------------- Браузеры -------- _CHROMIUM = [ ("Google Chrome", "{LOCAL}\\Google\\Chrome\\User Data", "chrome.exe"), ("Google Chrome Beta", "{LOCAL}\\Google\\Chrome Beta\\User Data", "chrome.exe"), ("Microsoft Edge", "{LOCAL}\\Microsoft\\Edge\\User Data", "msedge.exe"), ("Brave", "{LOCAL}\\BraveSoftware\\Brave-Browser\\User Data", "brave.exe"), ("Opera", "{ROAMING}\\Opera Software\\Opera Stable", "opera.exe"), ("Opera GX", "{ROAMING}\\Opera Software\\Opera GX Stable", "opera.exe"), ("Vivaldi", "{LOCAL}\\Vivaldi\\User Data", "vivaldi.exe"), ("Yandex", "{LOCAL}\\Yandex\\YandexBrowser\\User Data", "browser.exe"), ("Chromium", "{LOCAL}\\Chromium\\User Data", "chromium.exe"), ] _CHROMIUM_CACHES = [ ("Cache\\Cache_Data", "HTTP-кеш страниц", R.SAFE), ("Code Cache", "Скомпилированный JavaScript", R.SAFE), ("GPUCache", "Кеш GPU-шейдеров", R.SAFE), ("ShaderCache", "Кеш шейдеров", R.SAFE), ("GrShaderCache", "Кеш шейдеров Skia", R.SAFE), ("DawnCache", "Кеш WebGPU", R.SAFE), ("DawnGraphiteCache", "Кеш WebGPU (Graphite)", R.SAFE), ("DawnWebGPUCache", "Кеш WebGPU", R.SAFE), ("Service Worker\\CacheStorage", "Кеш service worker'ов сайтов", R.LOW), ("Service Worker\\ScriptCache", "Скрипты service worker'ов", R.LOW), ("Application Cache", "Устаревший AppCache", R.SAFE), ("Media Cache", "Кеш видео и аудио", R.SAFE), ("File System", "Sandboxed FileSystem API сайтов", R.MEDIUM), ("IndexedDB", "Локальные базы сайтов (офлайн-данные)", R.MEDIUM), ] def _browser_rules() -> list[Rule]: out: list[Rule] = [] for name, root, proc in _CHROMIUM: for sub, desc, risk in _CHROMIUM_CACHES: out.append(Rule( f"br.{name.lower().replace(' ', '')}.{sub.split(chr(92))[0].lower().replace(' ', '')}", f"{name} — {desc}", C.BROWSERS, risk, f"{desc}. Профили: все найденные. Браузер лучше закрыть перед очисткой.", (f"{root}\\*\\{sub}", f"{root}\\{sub}"), contents_only=True, processes=(proc,), min_size=256 * 1024, )) out.append(Rule( f"br.{name.lower().replace(' ', '')}.crashpad", f"{name} — отчёты о падениях", C.BROWSERS, R.SAFE, "Crashpad-дампы браузера.", (f"{root}\\Crashpad\\reports", f"{root}\\Crashpad\\completed"), contents_only=True, processes=(proc,), )) out += [ Rule("br.firefox.cache", "Firefox — кеш", C.BROWSERS, R.SAFE, "cache2 всех профилей Firefox.", ("{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\cache2", "{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\startupCache", "{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\shader-cache", "{LOCAL}\\Mozilla\\Firefox\\Profiles\\*\\thumbnails"), contents_only=True, processes=("firefox.exe",)), Rule("br.firefox.crash", "Firefox — отчёты о падениях", C.BROWSERS, R.SAFE, "Minidump'ы Mozilla Crash Reporter.", ("{ROAMING}\\Mozilla\\Firefox\\Crash Reports",), contents_only=True), Rule("br.tor.cache", "Tor Browser — кеш", C.BROWSERS, R.SAFE, "Кеш профиля Tor Browser.", ("{ROAMING}\\tor-browser\\*\\cache2",), contents_only=True), ] return out BROWSER_RULES = _browser_rules() # ----------------------------------------------- Кеши инструментов разработки - DEV_CACHE_RULES: list[Rule] = [ # --- JavaScript --- Rule("dev.npm", "npm — глобальный кеш пакетов", C.DEV_CACHE, R.LOW, "_cacache. npm скачает пакеты заново при следующей установке.", ("{LOCAL}\\npm-cache\\_cacache", "{ROAMING}\\npm-cache\\_cacache"), contents_only=True), Rule("dev.yarn", "Yarn — кеш пакетов", C.DEV_CACHE, R.LOW, "Глобальный кеш Yarn 1.x и Berry.", ("{LOCAL}\\Yarn\\Cache", "{LOCAL}\\Yarn\\Berry\\cache", "{HOME}\\.yarn\\berry\\cache"), contents_only=True), Rule("dev.pnpm", "pnpm — content-addressable store", C.DEV_CACHE, R.MEDIUM, "Общее хранилище пакетов pnpm. После удаления все проекты потребуют pnpm install.", ("{LOCAL}\\pnpm\\store", "{LOCAL}\\pnpm-store", "{HOME}\\.pnpm-store"), contents_only=True), Rule("dev.bun", "Bun — кеш установок", C.DEV_CACHE, R.LOW, "Кеш менеджера пакетов Bun.", ("{LOCAL}\\bun\\install\\cache", "{HOME}\\.bun\\install\\cache"), contents_only=True), Rule("dev.deno", "Deno — кеш модулей", C.DEV_CACHE, R.LOW, "Скачанные удалённые модули и скомпилированный код.", ("{LOCAL}\\deno", "{HOME}\\.deno"), contents_only=True), Rule("dev.node.gyp", "node-gyp — заголовки Node", C.DEV_CACHE, R.SAFE, "Исходники Node для сборки нативных модулей.", ("{LOCAL}\\node-gyp\\Cache", "{HOME}\\.node-gyp"), contents_only=True), Rule("dev.electron", "Electron / electron-builder — кеш", C.DEV_CACHE, R.LOW, "Скачанные бинарники Electron и распакованные зависимости сборщика.", ("{LOCAL}\\electron\\Cache", "{LOCAL}\\electron-builder\\Cache", "{LOCAL}\\electron-builder\\cache"), contents_only=True), Rule("dev.puppeteer", "Puppeteer / Playwright — браузеры", C.DEV_CACHE, R.MEDIUM, "Скачанные сборки Chromium/Firefox/WebKit для e2e-тестов. Обычно 1–3 ГБ.", ("{LOCAL}\\ms-playwright", "{HOME}\\.cache\\puppeteer", "{LOCAL}\\puppeteer"), contents_only=True), Rule("dev.cypress", "Cypress — кеш бинарников", C.DEV_CACHE, R.LOW, "Каждая версия Cypress весит ~500 МБ и остаётся навсегда.", ("{LOCAL}\\Cypress\\Cache",), contents_only=True), # --- Python --- Rule("dev.pip", "pip — кеш колёс и загрузок", C.DEV_CACHE, R.SAFE, "Скачанные wheel/sdist. Восстанавливается при следующей установке.", ("{LOCAL}\\pip\\Cache", "{HOME}\\.cache\\pip"), contents_only=True), Rule("dev.poetry", "Poetry — кеш", C.DEV_CACHE, R.LOW, "Артефакты и виртуальные окружения, созданные Poetry.", ("{LOCAL}\\pypoetry\\Cache\\cache", "{LOCAL}\\pypoetry\\Cache\\artifacts"), contents_only=True), Rule("dev.uv", "uv — кеш пакетов", C.DEV_CACHE, R.SAFE, "Кеш быстрого установщика uv.", ("{LOCAL}\\uv\\cache", "{HOME}\\.cache\\uv"), contents_only=True), Rule("dev.conda", "Conda — распакованные пакеты", C.DEV_CACHE, R.MEDIUM, "pkgs/ занимает десятки ГБ. Безопаснее `conda clean -a`, но каталог можно чистить и вручную.", ("{HOME}\\anaconda3\\pkgs", "{HOME}\\miniconda3\\pkgs", "{HOME}\\.conda\\pkgs"), contents_only=True), Rule("dev.pyinstaller", "PyInstaller — кеш сборок", C.DEV_CACHE, R.SAFE, "Промежуточные бинарники упаковщика.", ("{ROAMING}\\pyinstaller",), contents_only=True), # --- .NET / Java / Rust / Go --- Rule("dev.nuget", "NuGet — глобальные пакеты", C.DEV_CACHE, R.MEDIUM, "~/.nuget/packages. Все .NET-проекты потребуют restore после очистки.", ("{HOME}\\.nuget\\packages",), contents_only=True), Rule("dev.nuget.http", "NuGet — HTTP-кеш и temp", C.DEV_CACHE, R.SAFE, "Промежуточный кеш скачивания, восстанавливается сам.", ("{LOCAL}\\NuGet\\v3-cache", "{LOCAL}\\NuGet\\plugins-cache", "{LOCAL}\\Temp\\NuGetScratch"), contents_only=True), Rule("dev.maven", "Maven — локальный репозиторий", C.DEV_CACHE, R.MEDIUM, "~/.m2/repository. Часто десятки ГБ; при сборке скачается заново.", ("{HOME}\\.m2\\repository",), contents_only=True), Rule("dev.gradle", "Gradle — кеши и дистрибутивы", C.DEV_CACHE, R.MEDIUM, "caches/ и wrapper/dists — один из самых крупных пожирателей места у Android-разработчиков.", ("{HOME}\\.gradle\\caches", "{HOME}\\.gradle\\wrapper\\dists", "{HOME}\\.gradle\\daemon", "{HOME}\\.gradle\\native"), contents_only=True), Rule("dev.cargo", "Cargo — реестр и исходники крейтов", C.DEV_CACHE, R.LOW, "registry/cache, registry/src и git/checkouts. Восстанавливаются при сборке.", ("{HOME}\\.cargo\\registry\\cache", "{HOME}\\.cargo\\registry\\src", "{HOME}\\.cargo\\git\\checkouts", "{HOME}\\.cargo\\git\\db"), contents_only=True), Rule("dev.gomod", "Go — кеш модулей и сборки", C.DEV_CACHE, R.LOW, "GOMODCACHE/download и GOCACHE. Модули read-only — потребуется `go clean -modcache`, " "если обычное удаление не пройдёт.", ("{HOME}\\go\\pkg\\mod\\cache\\download", "{LOCAL}\\go-build"), contents_only=True), Rule("dev.sdkman", "Скачанные JDK / SDK", C.DEV_CACHE, R.MEDIUM, "Архивы и распакованные SDK, которые обычно уже не используются.", ("{LOCAL}\\Temurin", "{HOME}\\.jdks", "{HOME}\\.sdkman\\archives"), contents_only=True), # --- Mobile / Game / прочее --- Rule("dev.android.sdk", "Android SDK — временные каталоги", C.DEV_CACHE, R.LOW, "Кеш SDK-менеджера и загрузок.", ("{LOCAL}\\Android\\Sdk\\.temp", "{LOCAL}\\Android\\Sdk\\.downloadIntermediates", "{HOME}\\.android\\cache", "{HOME}\\.android\\build-cache"), contents_only=True), Rule("dev.android.emulator", "Образы эмулятора Android", C.DEV_CACHE, R.HIGH, "system-images и созданные AVD. Каждое устройство — несколько ГБ. " "Удаляйте только те, которыми точно не пользуетесь.", ("{LOCAL}\\Android\\Sdk\\system-images\\*", "{HOME}\\.android\\avd\\*"), min_size=200 * 1024 * 1024), Rule("dev.flutter", "Flutter / Dart — pub cache", C.DEV_CACHE, R.MEDIUM, "Скачанные пакеты Dart и артефакты движка Flutter.", ("{LOCAL}\\Pub\\Cache\\hosted", "{LOCAL}\\Pub\\Cache\\git", "{HOME}\\.pub-cache\\hosted"), contents_only=True), Rule("dev.composer", "Composer — кеш PHP-пакетов", C.DEV_CACHE, R.SAFE, "Скачанные zip-архивы и метаданные packagist.", ("{LOCAL}\\Composer\\files", "{LOCAL}\\Composer\\repo", "{ROAMING}\\Composer\\cache"), contents_only=True), Rule("dev.ruby", "RubyGems / Bundler — кеш", C.DEV_CACHE, R.LOW, "Скачанные .gem-архивы.", ("{LOCAL}\\gem\\cache", "{HOME}\\.bundle\\cache", "{HOME}\\.gem\\cache"), contents_only=True), Rule("dev.terraform", "Terraform — кеш плагинов", C.DEV_CACHE, R.LOW, "Скачанные провайдеры (каждый — сотни МБ).", ("{ROAMING}\\terraform.d\\plugin-cache", "{LOCAL}\\terraform.d"), contents_only=True), Rule("dev.helm", "Helm / Kubernetes — кеш", C.DEV_CACHE, R.SAFE, "Кеш репозиториев чартов.", ("{LOCAL}\\helm\\repository\\cache", "{LOCAL}\\Temp\\helm"), contents_only=True), Rule("dev.vcpkg", "vcpkg / Conan — кеш сборок", C.DEV_CACHE, R.MEDIUM, "Бинарные кеши C++-зависимостей. Пересборка может занять часы.", ("{LOCAL}\\vcpkg\\archives", "{LOCAL}\\vcpkg\\downloads", "{HOME}\\.conan\\data", "{HOME}\\.conan2\\p"), contents_only=True), Rule("dev.ccache", "ccache / sccache", C.DEV_CACHE, R.LOW, "Кеш компилятора C/C++. Ускоряет пересборку, но безопасно удаляется.", ("{LOCAL}\\ccache", "{LOCAL}\\Mozilla\\sccache", "{HOME}\\.ccache"), contents_only=True), Rule("dev.unity.global", "Unity — глобальные кеши", C.DEV_CACHE, R.MEDIUM, "Asset Pipeline cache, кеш пакетов и загрузок Unity Hub.", ("{LOCAL}\\Unity\\cache", "{ROAMING}\\Unity\\cache", "{LOCAL}\\Unity\\Caches", "{ROAMING}\\UnityHub\\Caches"), contents_only=True), Rule("dev.unreal", "Unreal Engine — DDC", C.DEV_CACHE, R.MEDIUM, "Derived Data Cache. Легко занимает 50+ ГБ; пересобирается долго.", ("{LOCAL}\\UnrealEngine\\Common\\DerivedDataCache", "{LOCAL}\\UnrealEngine\\*\\DerivedDataCache"), contents_only=True), Rule("dev.docker", "Docker Desktop — логи и кеш", C.DEV_CACHE, R.LOW, "Логи и служебный кеш. Образы хранятся в WSL-диске — их чистят через `docker system prune`.", ("{LOCAL}\\Docker\\log", "{ROAMING}\\Docker\\log", "{ROAMING}\\Docker Desktop\\logs"), contents_only=True), ] # ------------------------------------------------------------ IDE / редакторы - IDE_RULES: list[Rule] = [ Rule("ide.vscode", "VS Code — кеш и временные данные", C.DEV_CACHE, R.LOW, "Cache, CachedData, GPUCache, логи. Настройки и расширения не затрагиваются.", ("{ROAMING}\\Code\\Cache", "{ROAMING}\\Code\\CachedData", "{ROAMING}\\Code\\CachedExtensionVSIXs", "{ROAMING}\\Code\\Code Cache", "{ROAMING}\\Code\\GPUCache", "{ROAMING}\\Code\\logs", "{ROAMING}\\Code\\User\\workspaceStorage"), contents_only=True, processes=("code.exe",)), Rule("ide.vscode.insiders", "VS Code Insiders / VSCodium — кеш", C.DEV_CACHE, R.LOW, "То же самое для альтернативных сборок редактора.", ("{ROAMING}\\Code - Insiders\\Cache", "{ROAMING}\\Code - Insiders\\CachedData", "{ROAMING}\\VSCodium\\Cache", "{ROAMING}\\VSCodium\\CachedData"), contents_only=True), Rule("ide.cursor", "Cursor / Windsurf — кеш", C.DEV_CACHE, R.LOW, "Кеши AI-редакторов на базе VS Code.", ("{ROAMING}\\Cursor\\Cache", "{ROAMING}\\Cursor\\CachedData", "{ROAMING}\\Cursor\\Code Cache", "{ROAMING}\\Cursor\\GPUCache", "{ROAMING}\\Windsurf\\Cache", "{ROAMING}\\Windsurf\\CachedData"), contents_only=True, processes=("cursor.exe",)), Rule("ide.jetbrains.caches", "JetBrains — индексы и кеши", C.DEV_CACHE, R.LOW, "Индексы IDEA/PyCharm/WebStorm и др. Перестраиваются при открытии проекта.", ("{LOCAL}\\JetBrains\\*\\caches", "{LOCAL}\\JetBrains\\*\\index", "{LOCAL}\\JetBrains\\*\\tmp", "{LOCAL}\\JetBrains\\*\\log"), contents_only=True, processes=("idea64.exe", "pycharm64.exe", "webstorm64.exe")), Rule("ide.jetbrains.old", "JetBrains — данные старых версий IDE", C.DEV_CACHE, R.MEDIUM, "Конфигурация и кеши версий, которые давно не запускались.", ("{ROAMING}\\JetBrains\\*",), min_size=100 * 1024 * 1024), Rule("ide.visualstudio", "Visual Studio — кеши", C.DEV_CACHE, R.LOW, "ComponentModelCache, кеш телеметрии и отладчика.", ("{LOCAL}\\Microsoft\\VisualStudio\\*\\ComponentModelCache", "{LOCAL}\\Microsoft\\VisualStudio\\*\\Designer\\ShadowCache", "{LOCAL}\\Microsoft\\VisualStudio\\Packages\\_Instances", "{LOCAL}\\Microsoft\\VSCommon\\*\\SQM"), contents_only=True, processes=("devenv.exe",)), Rule("ide.vs.installer", "Visual Studio Installer — кеш дистрибутивов", C.DEV_CACHE, R.MEDIUM, "Скачанные пакеты установщика VS. Часто 10–20 ГБ, нужны только при изменении состава.", ("{PROGRAMDATA}\\Microsoft\\VisualStudio\\Packages",), contents_only=True, needs_admin=True, min_size=200 * 1024 * 1024), Rule("ide.vs.backup", "Visual Studio — автосохранения и трассировки", C.DEV_CACHE, R.LOW, "Backup Files и ActivityLog.", ("{LOCAL}\\Microsoft\\VisualStudio\\*\\ActivityLog.xml", "{HOME}\\Documents\\Visual Studio *\\Backup Files"), contents_only=True), Rule("ide.xamarin", "Xamarin / .NET Android — кеш", C.DEV_CACHE, R.LOW, "Скачанные компоненты Xamarin.", ("{LOCAL}\\Xamarin\\zips", "{LOCAL}\\Xamarin\\Cache"), contents_only=True), Rule("ide.eclipse", "Eclipse / NetBeans — кеш", C.DEV_CACHE, R.LOW, "Метаданные рабочих областей и индексы.", ("{ROAMING}\\NetBeans\\*\\var\\cache", "{HOME}\\.eclipse\\*\\configuration\\org.eclipse.osgi"), contents_only=True), ] # ------------------------------------------------------------ Приложения ---- APP_RULES: list[Rule] = [ Rule("app.discord", "Discord — кеш", C.APPS, R.SAFE, "Cache, Code Cache, GPUCache клиента Discord.", ("{ROAMING}\\discord\\Cache", "{ROAMING}\\discord\\Code Cache", "{ROAMING}\\discord\\GPUCache", "{ROAMING}\\discordptb\\Cache", "{ROAMING}\\discordcanary\\Cache"), contents_only=True, processes=("discord.exe",)), Rule("app.slack", "Slack — кеш", C.APPS, R.SAFE, "Кеш сообщений и вложений Slack.", ("{ROAMING}\\Slack\\Cache", "{ROAMING}\\Slack\\Code Cache", "{ROAMING}\\Slack\\GPUCache", "{ROAMING}\\Slack\\Service Worker\\CacheStorage"), contents_only=True, processes=("slack.exe",)), Rule("app.teams", "Microsoft Teams — кеш", C.APPS, R.LOW, "Кеш классического и нового клиента Teams.", ("{ROAMING}\\Microsoft\\Teams\\Cache", "{ROAMING}\\Microsoft\\Teams\\Code Cache", "{ROAMING}\\Microsoft\\Teams\\GPUCache", "{ROAMING}\\Microsoft\\Teams\\Service Worker\\CacheStorage", "{LOCAL}\\Packages\\MSTeams_*\\LocalCache"), contents_only=True, processes=("ms-teams.exe", "teams.exe")), Rule("app.telegram", "Telegram Desktop — кеш медиа", C.APPS, R.LOW, "Скачанные фото и видео. При необходимости подтянутся с сервера заново.", ("{ROAMING}\\Telegram Desktop\\tdata\\user_data\\cache", "{ROAMING}\\Telegram Desktop\\tdata\\user_data\\media_cache", "{ROAMING}\\Telegram Desktop\\tdata\\emoji"), contents_only=True, processes=("telegram.exe",)), Rule("app.spotify", "Spotify — кеш треков", C.APPS, R.SAFE, "Локальный кеш прослушанной музыки.", ("{LOCAL}\\Spotify\\Data", "{LOCAL}\\Spotify\\Storage", "{ROAMING}\\Spotify\\Data"), contents_only=True, processes=("spotify.exe",)), Rule("app.steam", "Steam — кеш и логи", C.APPS, R.LOW, "htmlcache, shadercache, логи и незавершённые загрузки.", ("{LOCAL}\\Steam\\htmlcache", "{PROGRAMFILES86}\\Steam\\logs", "{PROGRAMFILES86}\\Steam\\appcache\\httpcache", "{PROGRAMFILES86}\\Steam\\steamapps\\shadercache", "{PROGRAMFILES86}\\Steam\\steamapps\\temp", "{PROGRAMFILES86}\\Steam\\steamapps\\downloading"), contents_only=True, processes=("steam.exe",)), Rule("app.epic", "Epic Games — webcache", C.APPS, R.SAFE, "Кеш встроенного браузера лаунчера.", ("{LOCAL}\\EpicGamesLauncher\\Saved\\webcache", "{LOCAL}\\EpicGamesLauncher\\Saved\\webcache_*", "{LOCAL}\\EpicGamesLauncher\\Saved\\Logs"), contents_only=True), Rule("app.battlenet", "Battle.net — кеш", C.APPS, R.SAFE, "Кеш агента обновлений Blizzard.", ("{ROAMING}\\Battle.net\\Cache", "{PROGRAMDATA}\\Battle.net\\Agent\\data"), contents_only=True), Rule("app.origin", "EA / Origin — кеш", C.APPS, R.SAFE, "Кеш лаунчеров EA.", ("{ROAMING}\\Origin\\Cache", "{LOCAL}\\Origin", "{LOCAL}\\Electronic Arts\\EA Desktop\\cache"), contents_only=True), Rule("app.adobe", "Adobe — медиакеш", C.APPS, R.LOW, "Media Cache Files Premiere/After Effects. Пересоздаётся при открытии проекта, " "но первый предпросмотр будет медленнее.", ("{ROAMING}\\Adobe\\Common\\Media Cache Files", "{ROAMING}\\Adobe\\Common\\Media Cache", "{ROAMING}\\Adobe\\Common\\Peak Files", "{LOCAL}\\Adobe\\*\\Cache"), contents_only=True), Rule("app.obs", "OBS Studio — логи и профили сбоев", C.APPS, R.SAFE, "Логи трансляций и crash-репорты.", ("{ROAMING}\\obs-studio\\logs", "{ROAMING}\\obs-studio\\crashes"), contents_only=True), Rule("app.zoom", "Zoom — данные и логи", C.APPS, R.LOW, "Кеш конференций и логи клиента.", ("{ROAMING}\\Zoom\\logs", "{ROAMING}\\Zoom\\data"), contents_only=True), Rule("app.office", "Microsoft Office — кеш документов", C.APPS, R.LOW, "Кеш облачных документов Office. Несинхронизированные правки будут потеряны.", ("{LOCAL}\\Microsoft\\Office\\*\\OfficeFileCache", "{LOCAL}\\Microsoft\\Office\\*\\WebServiceCache"), contents_only=True, processes=("winword.exe", "excel.exe")), Rule("app.onedrive", "OneDrive — логи", C.APPS, R.SAFE, "Телеметрия и логи синхронизации.", ("{LOCAL}\\Microsoft\\OneDrive\\logs",), contents_only=True), Rule("app.nvidia.cache", "NVIDIA — кеш шейдеров", C.APPS, R.SAFE, "DXCache / GLCache / NV_Cache. Пересобирается играми автоматически.", ("{LOCAL}\\NVIDIA\\DXCache", "{LOCAL}\\NVIDIA\\GLCache", "{LOCAL}\\NVIDIA Corporation\\NV_Cache", "{LOCAL}\\NVIDIA\\ComputeCache"), contents_only=True), Rule("app.amd.cache", "AMD — кеш шейдеров", C.APPS, R.SAFE, "DxCache и GLCache драйвера AMD.", ("{LOCAL}\\AMD\\DxCache", "{LOCAL}\\AMD\\GLCache", "{LOCAL}\\AMD\\DxcCache"), contents_only=True), Rule("app.electron.generic", "Прочие Electron-приложения — кеш", C.APPS, R.LOW, "Автоматически найденные каталоги Cache/GPUCache в данных установленных приложений.", ("{ROAMING}\\*\\Cache\\Cache_Data", "{ROAMING}\\*\\GPUCache", "{ROAMING}\\*\\Code Cache\\js", "{LOCAL}\\*\\GPUCache"), contents_only=True, min_size=10 * 1024 * 1024), ] # ------------------------------------------------------ Пакетные менеджеры -- PKG_RULES: list[Rule] = [ Rule("pkg.chocolatey", "Chocolatey — кеш загрузок", C.PACKAGE_MANAGERS, R.SAFE, "Скачанные установщики пакетов choco.", ("{LOCAL}\\Temp\\chocolatey", "{PROGRAMDATA}\\chocolatey\\lib-bkp"), contents_only=True), Rule("pkg.scoop", "Scoop — кеш и старые версии", C.PACKAGE_MANAGERS, R.LOW, "cache/ с архивами и apps/*/старые версии приложений.", ("{HOME}\\scoop\\cache", "{PROGRAMDATA}\\scoop\\cache"), contents_only=True), Rule("pkg.winget", "winget — кеш установщиков", C.PACKAGE_MANAGERS, R.SAFE, "Временные файлы Windows Package Manager.", ("{LOCAL}\\Packages\\Microsoft.DesktopAppInstaller_*\\LocalState\\TempState", "{LOCAL}\\Temp\\WinGet"), contents_only=True), Rule("pkg.msi.cache", "Кеш загруженных установщиков", C.PACKAGE_MANAGERS, R.LOW, "Package Cache — дистрибутивы Visual C++, .NET и подобных бандлов.", ("{PROGRAMDATA}\\Package Cache",), contents_only=True, needs_admin=True, min_size=100 * 1024 * 1024), ] # ------------------------------------------- Артефакты внутри проектов ------ # # Их ищет devscan.py: рекурсивный обход выбранных каталогов. @dataclass(frozen=True) class ProjectRule: name: str # имя каталога/файла-артефакта title: str risk: Risk detail: str marker: tuple[str, ...] = () # файлы рядом, подтверждающие тип проекта inner: tuple[str, ...] = () # файлы внутри каталога, подтверждающие находку stop: bool = True # не заходить внутрь найденного каталога ecosystem: str = "" PROJECT_RULES: tuple[ProjectRule, ...] = ( ProjectRule("node_modules", "node_modules", R.LOW, "Зависимости Node. Восстанавливаются командой npm/yarn/pnpm install.", ("package.json",), stop=True, ecosystem="JavaScript"), ProjectRule(".next", "Сборка Next.js", R.SAFE, "Кеш и артефакты сборки Next.js.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".nuxt", "Сборка Nuxt", R.SAFE, "Артефакты Nuxt.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".output", "Вывод Nitro/Nuxt", R.SAFE, "Собранный сервер Nitro.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".turbo", "Кеш Turborepo", R.SAFE, "Кеш задач Turborepo.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".parcel-cache", "Кеш Parcel", R.SAFE, "Кеш бандлера Parcel.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".angular", "Кеш Angular CLI", R.SAFE, "Кеш сборки Angular.", ("angular.json",), ecosystem="JavaScript"), ProjectRule(".svelte-kit", "Сборка SvelteKit", R.SAFE, "Артефакты SvelteKit.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".astro", "Кеш Astro", R.SAFE, "Служебные типы и кеш Astro.", ("package.json",), ecosystem="JavaScript"), ProjectRule(".docusaurus", "Кеш Docusaurus", R.SAFE, "Кеш генератора документации.", ("package.json",), ecosystem="JavaScript"), ProjectRule("storybook-static", "Сборка Storybook", R.SAFE, "Статическая сборка Storybook.", ("package.json",), ecosystem="JavaScript"), ProjectRule("coverage", "Отчёты о покрытии", R.SAFE, "Результаты прогона тестов.", (), ecosystem="Тесты"), ProjectRule(".nyc_output", "Сырые данные покрытия", R.SAFE, "Промежуточные данные nyc.", (), ecosystem="Тесты"), ProjectRule("__pycache__", "Байт-код Python", R.SAFE, "Скомпилированные .pyc. Пересоздаются при запуске.", (), ecosystem="Python"), ProjectRule(".pytest_cache", "Кеш pytest", R.SAFE, "Кеш последнего прогона тестов.", (), ecosystem="Python"), ProjectRule(".mypy_cache", "Кеш mypy", R.SAFE, "Инкрементальный кеш проверки типов.", (), ecosystem="Python"), ProjectRule(".ruff_cache", "Кеш ruff", R.SAFE, "Кеш линтера ruff.", (), ecosystem="Python"), ProjectRule(".tox", "Окружения tox", R.LOW, "Виртуальные окружения матрицы тестов.", (), ecosystem="Python"), ProjectRule(".venv", "Виртуальное окружение", R.MEDIUM, "Пересоздаётся из requirements.txt / pyproject.toml, но не мгновенно.", (), inner=("pyvenv.cfg",), ecosystem="Python"), ProjectRule("venv", "Виртуальное окружение", R.MEDIUM, "Пересоздаётся из requirements.txt / pyproject.toml.", (), inner=("pyvenv.cfg",), ecosystem="Python"), ProjectRule("env", "Виртуальное окружение", R.MEDIUM, "Пересоздаётся из requirements.txt / pyproject.toml.", (), inner=("pyvenv.cfg",), ecosystem="Python"), ProjectRule(".conda", "Окружение conda в проекте", R.MEDIUM, "Локальное окружение conda.", (), inner=("conda-meta",), ecosystem="Python"), ProjectRule(".ipynb_checkpoints", "Чекпоинты Jupyter", R.SAFE, "Автосохранения ноутбуков.", (), ecosystem="Python"), ProjectRule("target", "Сборка Rust / Maven", R.LOW, "Артефакты cargo build или Maven. Пересборка может занять минуты.", ("Cargo.toml", "pom.xml"), ecosystem="Rust/Java"), ProjectRule("bin", "Сборка .NET (bin)", R.LOW, "Выходные файлы сборки .NET.", ("*.csproj", "*.sln", "*.fsproj", "*.vbproj"), ecosystem=".NET"), ProjectRule("obj", "Промежуточные файлы .NET", R.SAFE, "Объектные файлы сборки .NET.", ("*.csproj", "*.sln", "*.fsproj", "*.vbproj"), ecosystem=".NET"), ProjectRule(".vs", "Служебный каталог Visual Studio", R.SAFE, "Кеш IntelliSense и состояние решения.", (), ecosystem=".NET"), ProjectRule("build", "Каталог сборки", R.LOW, "Выход CMake/Gradle/Flutter. Убедитесь, что это не исходники.", ("CMakeLists.txt", "build.gradle", "build.gradle.kts", "pubspec.yaml", "package.json", "setup.py", "pyproject.toml"), ecosystem="Сборка"), ProjectRule("cmake-build-debug", "Сборка CMake (Debug)", R.SAFE, "Каталог сборки CLion.", (), ecosystem="C/C++"), ProjectRule("cmake-build-release", "Сборка CMake (Release)", R.SAFE, "Каталог сборки CLion.", (), ecosystem="C/C++"), ProjectRule("CMakeFiles", "Служебные файлы CMake", R.SAFE, "Промежуточные файлы генератора.", (), ecosystem="C/C++"), ProjectRule(".gradle", "Кеш Gradle в проекте", R.SAFE, "Локальный кеш задач Gradle.", (), ecosystem="Java/Android"), ProjectRule(".dart_tool", "Служебные файлы Dart", R.SAFE, "Кеш пакетов и сборки Dart.", ("pubspec.yaml",), ecosystem="Flutter"), ProjectRule("Pods", "CocoaPods", R.LOW, "Зависимости iOS-проекта.", (), ecosystem="Mobile"), ProjectRule("vendor", "Зависимости Composer/Go/Bundler", R.LOW, "Восстанавливается composer install / bundle install.", ("composer.json", "Gemfile", "go.mod"), ecosystem="PHP/Ruby/Go"), ProjectRule("Library", "Кеш проекта Unity", R.LOW, "Импортированные ассеты Unity. Перегенерируется при открытии проекта (долго).", ("Assets", "ProjectSettings"), inner=("ArtifactDB", "ScriptAssemblies", "PackageCache"), ecosystem="Unity"), ProjectRule("Intermediate", "Промежуточные файлы Unreal", R.SAFE, "Артефакты компиляции Unreal Engine.", (), ecosystem="Unreal"), ProjectRule("DerivedDataCache", "DDC проекта Unreal", R.LOW, "Производные данные ассетов Unreal.", (), ecosystem="Unreal"), ProjectRule(".terraform", "Плагины Terraform в проекте", R.LOW, "Скачанные провайдеры. Восстанавливается terraform init.", (), ecosystem="DevOps"), ProjectRule(".serverless", "Артефакты Serverless Framework", R.SAFE, "Сгенерированные пакеты деплоя.", (), ecosystem="DevOps"), ProjectRule(".cache", "Обобщённый кеш инструментов", R.SAFE, "Кеш сборщиков и линтеров внутри проекта.", (), ecosystem="Сборка"), ProjectRule("dist", "Каталог сборки dist", R.LOW, "Собранные файлы. Убедитесь, что это не исходники, которые вы коммитите.", ("package.json", "setup.py", "pyproject.toml", "rollup.config.js", "vite.config.js", "vite.config.ts"), ecosystem="Сборка"), ProjectRule("out", "Каталог сборки out", R.LOW, "Выход сборщика.", ("package.json", "tsconfig.json"), ecosystem="Сборка"), ) # Файлы-артефакты (не каталоги), которые ищем в проектах PROJECT_FILES: tuple[tuple[str, str, Risk, str], ...] = ( ("*.pyc", "Скомпилированный Python вне __pycache__", R.SAFE, "Python"), ("npm-debug.log*", "Лог сбоя npm", R.SAFE, "JavaScript"), ("yarn-error.log", "Лог сбоя yarn", R.SAFE, "JavaScript"), (".eslintcache", "Кеш ESLint", R.SAFE, "JavaScript"), ("tsconfig.tsbuildinfo", "Инкрементальный кеш TypeScript", R.SAFE, "JavaScript"), ("*.stackdump", "Дамп аварийного завершения", R.SAFE, "Прочее"), ("Thumbs.db", "Кеш эскизов Windows", R.SAFE, "Прочее"), ("desktop.ini", "", R.HIGH, ""), # намеренно не предлагаем ) # Каталоги, внутрь которых не спускаемся при поиске артефактов, даже если сам # каталог не подошёл ни под одно правило: внутри всё равно нет «своих» проектов. NEVER_DESCEND = { "node_modules", "__pycache__", ".git", ".svn", ".hg", "site-packages", "dist-packages", ".venv", "venv", ".tox", ".mypy_cache", ".pytest_cache", ".ruff_cache", ".gradle", ".vs", ".idea", "pods", "bower_components", } # Каталоги, в которые никогда не заходим при рекурсивном поиске SKIP_DIRS = { "$recycle.bin", "system volume information", "windows", "winsxs", "program files", "program files (x86)", "programdata", "$windows.~bt", "$windows.~ws", "appdata", "onedrive", "recovery", "boot", "perflogs", "msocache", "config.msi", } def all_rules() -> list[Rule]: return (WINDOWS_RULES + LOG_RULES + BROWSER_RULES + DEV_CACHE_RULES + IDE_RULES + APP_RULES + PKG_RULES) def rules_for(categories: set[Category]) -> list[Rule]: return [r for r in all_rules() if r.category in categories]