Skip to content

Latest commit

 

History

History

rulepacks

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Rule packs

The known-offenders catalog behind Smart suggestions (Clean Up ▸ Smart suggestions). Adding an offender is a JSON edit — no code change, no rebuild of the matching logic. The loader and schema live in ../rulePacks.ts; the matcher that walks a scan lives in ../cleanupRules.ts.

  • common.json — rules that apply on every OS.
  • macos.json, windows.json, linux.json — that OS's known locations.

Exactly two packs load on any machine: common plus the one for the current platform. A malformed pack fails the whole catalog with a reason — Smart suggestions then reports itself unavailable and says why, while the rest of the app boots normally. Half a catalog would silently stop suggesting things people rely on, which is the worse failure.

Rule shape

Every rule carries id, kind, title, description, category, confidence, and the fields its kind requires. Unknown keys are rejected, so a typo fails loudly instead of silently doing nothing.

Field Values
category regenerable, cache, junk
confidence high, medium, low
action trash (default) or advice
os optional subset of darwin, win32, linux

Kinds

Kind Matches Extra fields
project-directory a folder by name, optionally only when a manifest sits beside it, when it holds a file it always holds, and when it holds none a same-named folder of another kind holds names, requiresSibling?, requiresChild?, forbidsChild?, restoreCommand
directory a folder by name, with nothing to confirm it names
file a file by name names
location absolute known paths paths
stale-files files under a path, over a size, past an age withinPath, olderThanDays, minSizeBytes
package-cache a shared package-manager cache (§C6 only) ecosystem, paths, clearCommand

Names and sibling patterns are matched case-insensitively, and said in the "why" sentence as the pack writes them — so write them the way the files are usually spelled (Cargo.toml, Podfile, .DS_Store). A served group's "why" names the folders it actually matched, not every name the rule knows. A sibling pattern ending in .* matches any extension (vite.config.*).

requiresChild names what the folder itself must hold, any one of them, matched the same way. Give it to a rule whose folder name is also a person's word: a folder of settings named env sits beside requirements.txt as readily as a virtualenv does, so the virtualenv rule also needs the pyvenv.cfg that Python's venv, and virtualenv since version 20, write in every environment they make, and the coverage rule a report a test tool writes (lcov.info, clover.xml, …). The "why" says both — "A folder named env holding pyvenv.cfg, sitting next to requirements.txt."

forbidsChild names what the folder must hold none of, matched the same way: what only another folder of the same name holds. A project's .gradle sits beside build.gradle, and so does the Gradle user home when a project lives in the home folder or CI points GRADLE_USER_HOME at the project's .gradle. Only the user home holds gradle.properties (often passwords), init scripts, caches, wrapper and daemon, and no build writes the first two again, so the Gradle project-cache rule needs what a build writes there (buildOutputCleanup, file-system.probe or vcs-1) and refuses those. The "why" says it — "holding buildOutputCleanup, file-system.probe or vcs-1 and no gradle.properties, …". The orphan scanner reads it too: a folder holding one is no orphan of that rule either.

Ecosystem tagging (§C6)

A rule may carry ecosystem (npm, cargo, python, …). Only the orphan scanner reads it — Smart suggestions ignores it entirely, so tagging a rule can never change what the Clean Up list shows. A tagged project-directory rule must also carry:

  • ownerManifest — the file that proves the owning project still exists. Defaults to requiresSibling, which is the same thing for every rule that has one; node_modules states it separately because Smart suggestions flags it with or without a manifest.
  • evidence — child names that identify the directory once its owner is already gone. Required for any ecosystem-tagged rule, and the load fails without it: target is both Rust and Maven, and an orphan that matches no evidence is reported as nothing rather than guessed at.

package-cache rules are never "orphaned" — nothing owns a shared cache. They are always reclaimable, and clearCommand is the supported way to empty one.

Paths use / separators and these tokens: {home}, {localAppData}, {windir}, {systemDrive}. A path whose token cannot be resolved on this machine is dropped rather than matched half-expanded.

Evaluation order

For a directory: project-directory → directory → location. For a file: file → stale-files. Within each kind, pack order wins — which is how target resolves to Rust or Maven by the manifest beside it. A directory claimed by any rule is reported once and never descended into.

Nor is a folder of installed Python packages, claimed or not: what is in it is its packages' own files. pip ships a package folder named build, and a rule that names build would otherwise offer it as build output. Such a folder is one named site-packages or dist-packages, wherever it is (a virtualenv, a Python installed for the system), and any folder holding a *.dist-info folder, the record an installer writes beside each package it puts in place — uv's cache and pip install --target put packages outside any site-packages. A scan rooted at a site-packages or dist-packages folder, or anywhere below one, offers nothing. A scan rooted inside a package folder that only a .dist-info beside it marks is walked as any folder is: the scan lists nothing above its root.

Several rules may share an id to merge into one suggestion group (the two regen-web-build entries do). They must agree on title, description, category, action and restore command, or the load fails: the group's own text cannot depend on which rule happened to match first.

action: "advice"

TreeMap's only destructive action is move to Trash. Some of the biggest things on a disk must not be moved to the Trash — the file is the data, or the OS owns it. Those get action: "advice": the group is listed with its size so the space is visible, but with no checkboxes, and with adviceCommand showing the supported way to reclaim it. Windows' Temp folder for the account (%LOCALAPPDATA%\Temp) is one: running programs keep files in it, and programs write there expecting the folder itself to exist, so it is no "Developer cache" to move to the Recycle Bin whole; Windows' Storage settings clear what nothing is using.

Deliberately absent

  • WinSxS (C:\Windows\WinSxS). §C8 lists it, and it is genuinely huge, but it is the component store — most of it is hard links into the live system, the size Explorer reports is not the space it occupies, and deleting from it breaks Windows unrecoverably. DISM /Online /Cleanup-Image /StartComponentCleanup is the only correct tool, and it is not something TreeMap should run on a user's behalf. Listing it at all, even as advice, invites someone to try.
  • Anything under a live database or VM disk beyond the Docker/WSL entries above, which are advice-only for the same reason.