reclaim

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 27, 2026 License: MIT

README

reclaim icon

reclaim

Reclaim disk space without losing anything you cannot get back.

Go Platform Distros Dependencies Tests

What it is

Every disk-cleanup tool faces the same question and most answer it badly: what is safe to delete? Treat everything cache-shaped as disposable and you eventually remove a browser's Local Storage and log someone out of everything, or delete a dependency tree whose lockfile no longer resolves. Be too timid and the tool is not worth running.

reclaim answers it by refusing to treat "regenerable" as one category. Every target is a unit carrying a tier — from costs nothing to may be irreplaceable — and a separate flag saying whether losing it destroys information or merely costs a re-download. The planner walks tiers in order, stops at a ceiling, and an opt-in flag can raise that ceiling but can never authorise destroying information. Only --allow-lossy does that.

The second thing it takes seriously is that caches belong to programs that may be running right now. Deleting a live IDE's cache corrupts the session it is in the middle of. So before anything is selected, reclaim reads the process table and parks every unit whose directories belong to something currently running, then tells you what to quit and which pid to blame.

$ reclaim clean
DRY-RUN — nothing was deleted. Re-run with --apply to clean.
...
== Locked by running apps ==
  • JetBrains caches    6.2GiB  held by jetbrains-ide (pid 1155531)
      quit it, then re-run

Nothing is deleted without --apply, and --apply prompts before it acts.

Install

curl -fsSL https://raw.githubusercontent.com/mralaminahamed/reclaim/trunk/install.sh | sh

The script installs a native package where one fits the machine — .deb on Debian and its derivatives, .rpm on Fedora, RHEL and openSUSE — so reclaim can be upgraded and removed by the tools that already manage everything else there. Anywhere else, including macOS, it falls back to a static binary in /usr/local/bin. Checksums are verified, and a missing checksum file is a failure rather than a shrug.

On macOS, Homebrew is the native path instead:

brew tap mralaminahamed/reclaim https://github.com/mralaminahamed/reclaim
brew install --cask reclaim

It selects on the package format the machine expects, not the distribution's name. That is what makes it work on the derivatives too, and there are far more of those than there are upstreams.

Or take a package straight from the releases:

sudo dpkg -i reclaim_0.2.0_amd64.deb            # Debian, Ubuntu, Mint, Pop!_OS
sudo dnf install reclaim-0.2.0-1.x86_64.rpm     # Fedora, RHEL, Rocky, Alma
sudo zypper install reclaim-0.2.0-1.x86_64.rpm  # openSUSE

Arch has a PKGBUILD, macOS a Cask. With Go already installed, go install github.com/mralaminahamed/reclaim/cmd/reclaim@latest. From a checkout, make build — or make dist deb rpm to produce the packages yourself.

There are no third-party dependencies. For a tool that deletes files as root, an empty require block is a feature rather than an accident. The published binaries are static for the same reason: this runs on a machine that is having a bad day, and a dynamic link to a libc on the same failing disk is a bad bet.

The macOS binaries are not (yet) notarised — that needs an Apple Developer account, which this project does not have. install.sh and the Cask both fetch with curl, which never sets the quarantine flag, so neither is affected. Only a binary pulled through a browser is: xattr -d com.apple.quarantine reclaim clears it, the same workaround the release notes point at until notarising becomes worth the cost for a tool this size.

Usage

reclaim dry-run output
reclaim clean                 # measure and report; deletes nothing
reclaim clean --apply         # reclaim, after confirming
reclaim status                # filesystems, free space, pressure
reclaim analyze --min 1G      # largest directories; advisory
reclaim analyze --installers  # stale downloads; advisory
reclaim history               # what past runs actually removed
reclaim completion bash       # shell completion script
How hard to try
reclaim clean --free 12G    # clean until 12G is free, then stop
reclaim clean --auto        # read disk pressure and pick a target
reclaim clean --below 20G   # do nothing unless free space is under 20G
reclaim clean --tier 2      # never escalate past tier 2

--auto finds the most pressured filesystem and lets how full it is decide how hard to try. A comfortable disk gets only the free tiers; a critical one earns a cold reload.

A target also changes how a cache goes. Where a tool can trim, dropping only what nothing uses any more (npm cache verify, uv cache prune, pnpm store prune), the trim runs first as a free unit and the full wipe waits a tier up. Caches made of standalone files (the Go build cache, pip, npm's _cacache, thumbnails) give up their least recently used files first, and reclaim stops as soon as the target is met. "Last used" means the later of a file's access and modification times. If the target is still short once every file is gone, whatever is left goes too. Without a target, every unit goes whole, as before. Module caches and extracted archives are never trimmed file by file, because half an unpacked package is worse than none.

What to look at
reclaim clean --discover      # also claim caches with no hardcoded rule
reclaim clean --only 'xdg-*'  # restrict to matching unit ids
reclaim clean --exclude 'npm-*'
reclaim clean --workers 12    # size the probe pool
reclaim clean --json          # machine-readable output
Opt-in groups

Units in these groups are never touched unless you name them. Irreversible units additionally require --allow-lossy.

Flag Reclaims
--system the package-manager cache, a bounded journal vacuum, old snap revisions, crash dumps
--kernels superseded kernel packages and what removed kernels left in /lib/modules, never the running one
--obsolete config left by removed-but-not-purged packages, rotated logs over 30 days old, directories of superseded JetBrains IDE versions
--trash the desktop trash — lossy
--models huggingface, torch, whisper and LM Studio model stores, Chrome's on-device AI model
--flatpak unused runtimes
--docker build cache, dangling images, unused networks
--docker-containers stopped containers, each named in the dry run — a stopped container can hold state nowhere else
--docker-volumes unused volumes — these may hold databases
--steam-compatdata Steam's Proton prefixes, each named by game in the dry run — lossy: some games keep saves or settings there and nowhere else
--timemachine macOS: thins Time Machine's local snapshots — lossy: a local snapshot is the only copy of the state it captured
--gradle ~/.gradle/caches, ~/.gradle/wrapper
--maven ~/.m2/repository
--jetbrains JetBrains IDE caches
--browsers Chrome, Brave and Firefox HTTP caches
--playwright Playwright browser binaries
--claude-jobs, --claude-plugins Claude Code scratch and plugin cache
--sites-idle N dependency and build trees of projects idle for N days
--heavy discovered caches over 1GiB

Set RECLAIM_NO_OPLOG=1 to disable the operations log.

What it knows about

System packages

--system covers whichever package manager the machine has — apt, dnf, yum, pacman, zypper or apk — chosen by which binary is present rather than by parsing a distribution name. Each is a cache clean and nothing more. None of them runs an autoremove: that decides for itself what is orphaned, and the result cannot be previewed honestly.

The dry run reports what each will actually free. apt-get clean counts the two binary package indexes it also drops, not only the archive; the journal vacuum counts the journal less the window it keeps.

It needs root, and reclaim asks for it once up front via sudo -v — a single password prompt rather than one per unit. If elevation is declined the system units are reported under Failed with the reason, never counted as reclaimed.

Kernels

--kernels is deliberately separate from --system, and never runs apt autoremove. Two kernels always survive — the running one and the newest — and the dry run names every package it would purge, because a byte count is not something anyone can consent to for a kernel removal.

Debian-only, and not because the others are harder: dnf enforces installonly_limit itself, and Arch ships one linux package that is replaced rather than accumulated. On those systems there is nothing to collect, and a kernel unit would be inventing work.

A removed kernel is not quite gone. Its modules package reruns depmod on the way out, which rewrites the module indexes into /lib/modules/<version> — a directory of indexes for modules that no longer exist — and dpkg keeps the package in the rc state. --kernels takes both, but only for a version nothing still claims: no installed package of that version, not the running kernel, and no image in /boot. The last check protects a kernel installed outside dpkg, which has modules and an image and no package at all.

Time Machine and the unified log

macOS has no package manager cache for --system to clean, so it covers two things there instead, gated on tmutil being present rather than on the platform name.

The unified log (--system) is the journal's analogue. log erase --ttl takes only entries macOS itself already marked expired, the same reason a 7-day-old crash dump is reversible: the bound is what the system already committed to, not one this tool invented.

Time Machine local snapshots (--timemachine, its own flag for the reason kernels get one) are the high-value target — tens of gigabytes are routine even with no backup disk ever attached. tmutil thinlocalsnapshots asks the system to free space and decides for itself which snapshots to drop, so nothing on disk can state the yield in advance; the dry run instead names how many local snapshots currently exist, and --apply reports what actually freed, measured from free space before and after rather than estimated. Must be lossy — a local snapshot is the only copy of the state it captured — so it also needs --allow-lossy.

Obsolete files

--obsolete covers what outlived the thing that needed it, and all of it is lossy, so it also needs --allow-lossy:

  • Config of removed packages. apt remove without --purge leaves the package's configuration in /etc. A reinstall restores the shipped defaults, never the edits, so purging destroys whatever was changed. The dry run names every package.
  • Rotated logs over 30 days old — syslog.2.gz, dpkg.log-20250101.xz, Xorg.0.log.old. The command deletes exactly the files the dry run measured rather than searching again, so logrotate running in between cannot change what goes. The journal is left to its own bounded unit.

dpkg-based systems only for the package half; the logs work anywhere.

  • Superseded JetBrains versions. Every IDE upgrade starts a new RustRover2025.3 directory and abandons RustRover2025.2. A version counts only when a newer one of the same product sits beside it. Plugin and index data is reversible; the old settings directory is lossy, since the upgrade imported it once and only if asked.
Model stores

Tier 3 rather than tier 1, because "comes back" and "comes back for free" are different claims: every file re-downloads, over hours, often metered. Pruning is separate and unflagged — hf cache prune discards only revisions nothing references and downloads that never finished, so it costs nothing and leaves working models alone.

The Hugging Face home also holds the login (token, stored_tokens), so --models takes only its hub, xet, datasets and assets directories, and --discover never claims the home whole.

Ollama models go through ollama rm, which names exactly the models ollama list showed, so the server keeps its own index. reclaim never deletes blobs under a live store. The unit is lossy: a model built locally with ollama create does not come back from a pull, and nothing on disk tells it apart from one that does. So it needs --models --allow-lossy, and the report lists every model by name. The store is found, not assumed (OLLAMA_MODELS, ~/.ollama/models, or the packaged service's /usr/share/ollama), and it is only measured. If the server isn't running, nothing is offered, because nothing can be listed.

Stores moved to another disk are found where they were moved. HF_HOME, HF_HUB_CACHE (or the older HUGGINGFACE_HUB_CACHE) and TORCH_HOME are read for the model units. XDG_CACHE_HOME moves every ~/.cache entry in the catalog and the --discover sweep of the cache root. A relative value is ignored, as the XDG spec requires. A variable aimed at home, at / or at anything else the runner would refuse to delete registers nothing.

Trash

--trash --allow-lossy. Earlier versions emptied the trash by default as though it were a cache. It is the opposite of one: the trash exists so a deletion can be taken back, and emptying it removes that option.

Crash artifacts

/var/crash and /var/lib/systemd/coredump are only taken once they are older than seven days. That bound is what makes them safe to treat as regenerable: a dump written this morning belongs to a crash someone may be reading right now, and taking it would destroy the only copy of that failure. One from last month is a record the system itself is configured to expire.

Idle projects

--sites-idle knows around fifteen project shapes — Cargo, Maven, Gradle, Python venvs, Next, Elixir, CocoaPods, Terraform, .NET, Zig, Dart and the Node/PHP pair it started with. Each dependency directory is paired with a manifest that proves what produced it, because build, target, obj and bin are ordinary words and a directory of that name with nothing beside it is somebody's source. Idleness is judged from a project's own files, never from its build output.

Projects are found up to six levels below --sites-root, so a plugin inside Sites/<site>/wp-content/plugins/ is a project of its own. Hidden directories and symlinks are not entered.

A manifest proves the shape, not that the directory can be regenerated: a WordPress plugin commits vendor/ so it ships working. So inside a git repository a directory is claimed only when git vouches for it -- nothing under it is tracked (git ls-files) and the repository ignores it (git check-ignore). If git cannot answer, the directory is left alone. dist is claimed only this way; outside a repository there is no telling. A dependency directory that is a repository itself, or a Rust target/ holding Anchor's deploy/*-keypair.json, is never claimed.

A directory inside an idle project that carries a valid CACHEDIR.TAG is claimed whatever its name, as a reversible artifact: the tag is the directory's own statement that it can be regenerated. A committed one contradicts its tag and is left alone.

The index
reclaim index                  # snapshot every filesystem; later runs refresh
reclaim index --full           # re-read everything
reclaim index show [DIR]       # largest directories inside DIR, instantly
reclaim index cold [DIR]       # largest subtrees untouched for a year (--days, --min)

A full walk of every filesystem took 16s on a 200GB machine; a refresh took 2.4s, and analyze answered from the index in 0.3s where walking the home directory had taken 2m41s. Each filesystem is its own tree, never crossed into from another, so nothing is counted twice.

The index is for looking, never for deleting. clean measures everything live at the moment it runs. A snapshot is out of date by definition, and "it was a cache an hour ago" is not a reason to delete anything now.

A refresh re-reads only directories whose modification time changed — which happens whenever an entry is added, removed or renamed. It does not see a file growing in place, like a log or a database. analyze therefore only trusts an index less than a day old and says when it used one; --full rebuilds exactly. Directories the user cannot read are counted and reported; run as root to include them. Under sudo, the index is still written to the invoking user's home and handed back to them, so analyze run as that user finds it.

Unused applications

reclaim analyze --apps lists desktop applications not used in 90 days (--idle N to change that), each with the command that would remove it. It removes nothing: an uninstalled app does not come back by itself, and neither does whatever it kept.

An app is only listed on evidence, and every signal used can err one way only — towards "used":

  • the access time of the binary it launches. relatime still records a read at most once a day, which is plenty for months of disuse; on a noatime mount there is no answer and the app is not judged
  • the app's own data directory for snaps (~/snap/<name>) and flatpaks (~/.var/app/<id>)
  • GNOME Shell's record of when each app last ran

A deb package is skipped when it was installed as a dependency, or when another installed package depends on or recommends it — removing ibus removes ubuntu-desktop, and the next autoremove takes everything that was holding. Apps unpacked into /opt are sized as their directory.

On macOS there are no .desktop launchers, so this scans /Applications and ~/Applications directly, and the evidence is kMDItemLastUsedDate — the same Spotlight record Launchpad sorts "recently used" by. An app Spotlight has no launch record for is not judged, same as a binary on a noatime mount. The removal command is brew uninstall --cask <token> for anything Homebrew owns, or rm -rf for a plain drag-installed .app.

Stale installers
reclaim analyze --installers --older 90

Reports .deb, .rpm, .AppImage, .iso and friends in ~/Downloads that have sat there for months. This one only ever reports. Everything else the tool touches lives in a cache directory, where the containing directory is itself the argument that the contents are disposable; ~/Downloads is the opposite, and a download there may be the only copy of something.

Archives are not counted. A .zip is a container, not an intent, and on a real ~/Downloads the largest ones turned out to be a book collection and a Figma UI kit.

Where redundancy can be proven rather than guessed — a .deb whose package is already installed at exactly that version — the report says so:

  • ~/Downloads/coreutils.deb   20.2KiB  200d  coreutils 9.4-3ubuntu6.3 is already installed

Configuration

Defaults

~/.config/reclaim/config.json fills in flags that were not given:

{
  "workers": 12,
  "tier": 3,
  "exclude": ["go-*", "cargo-*"],
  "sites_root": "~/Projects"
}

One rule holds the whole file together: a config may narrow a run and may never widen one. So apply, yes, allow_lossy, discover and the opt-in group names are refused, by name and with the reason, rather than accepted quietly. A flag is typed at the moment of use and read back by whoever is about to press enter; a file is not read back by anyone, and the person it would surprise is the one who wrote it months ago and forgot. The worst a stale exclusion can do is leave space unreclaimed, which the next report points out.

A file that exists and does not parse stops the run.

Custom units

The catalog covers what this tool ships with an opinion about. Anything else — a cache for a tool nobody here uses, a site-specific scratch directory — can be declared in ~/.config/reclaim/units.json, or dropped into /etc/reclaim/units.d/*.json by a package:

{
  "units": [
    {
      "id": "ccache",
      "label": "ccache objects",
      "tier": 1,
      "reversible": true,
      "paths": [".cache/ccache"]
    },
    {
      "id": "conda-pkgs",
      "label": "conda package cache",
      "tier": 1,
      "reversible": true,
      "command": "conda clean --all --yes",
      "requires": "conda"
    }
  ]
}

tier and reversible are required. They are the two claims the safety model rests on, and defaulting either would let an omission make a promise the author never made. Relative paths resolve under $HOME; requires drops the unit on machines without that binary; flag makes it opt-in, named as --with <name> since a file cannot register a CLI flag.

A file adds to the catalog and can never restate it — the shipped definition of a unit id always wins. Definitions go through the same protected-path backstop as everything else, so one aiming at /, a top-level system directory or $HOME is refused at load. reversible: false still requires --allow-lossy: writing a unit down does not lower that gate. A longer example is in docs/units.example.json.

Shell completion
reclaim completion bash > /etc/bash_completion.d/reclaim
reclaim completion zsh  > "${fpath[1]}/_reclaim"
reclaim completion fish > ~/.config/fish/completions/reclaim.fish

Completing --only and --exclude asks the binary for unit ids rather than carrying a list, since which units exist depends on what is installed. The packages install these for you.

Running on a schedule

--below makes a run a no-op unless the disk is actually under pressure, and it decides that before building a catalog or probing anything — so a timer can fire often and cost nothing most of the time:

sudo cp systemd/reclaim.* /etc/systemd/system/
sudo systemctl enable --now reclaim.timer

The shipped service runs clean --below 20G --auto --apply --yes, with no opt-in group flags and no --allow-lossy. Whatever it does, it does at 03:00 with nobody reading the output, and the default tier ceiling is the right amount of ambition for that. --json and the operations log make a run auditable afterwards.

There is no watch daemon on purpose. A timer plus --below is the same capability without a process to supervise, and systemd already handles the parts a daemon would have to reimplement badly: persistence across reboot, missed windows, and logging.

Safety model

  • Dry run by default. Nothing is deleted and no command runs without --apply, which prompts unless given --yes.
  • Tiers. Units run cheapest-first and the planner will not cross its ceiling.
  • Reversibility is absolute. An opt-in flag authorises a unit but never authorises destroying information. A test pins that distinction.
  • Opt-in means opt-in. A unit carrying a flag runs only when that flag is passed, whatever the tier ceiling says.
  • Locks. Caches of running applications are skipped, named, and attributed to a pid. reclaim excludes its own process, so its command line cannot lock it out of its own work.
  • Probing never deletes. Everything reachable from the measuring phase is read-only, asserted by a test that walks the tree before and after.
  • Protected names. Local Storage, IndexedDB, Cookies, Login Data and friends are never treated as caches, in any casing.
  • Protected paths. A backstop refuses /, top-level system directories and $HOME however a unit is defined, so a malformed unit cannot aim the deleter at the wrong tree. It is checked again at the moment of deletion against the path with its symlinks resolved.
  • Deletion stays inside its tree. Removal walks each target through a handle opened on the target itself, so no symlink, present from the start or swapped in mid-run, can lead it elsewhere. A link is removed, never followed. A mount point inside a cache belongs to another filesystem and is left alone.
  • Skipped is not failed. Anything left in place on purpose, such as a mount point or a directory some tool re-populated while it was being removed, is listed under == Skipped == with the reason, and the run carries on.
  • The log says what went. reclaim history records the paths each unit removed, not just which unit ran — after a --discover run the unit list was not knowable in advance. Long lists are trimmed with a true count, so a record never understates what happened. Deletion is final: there is no undo.

How it works

survey → catalog → probe → lock → plan → run → report

The catalog registers a unit only when its path exists or its tool is installed. Probing is du-bound and every unit is independent, so it runs on a worker pool — a full discovery run over a developer machine takes about 1.7 seconds. Locking happens after probing, so a locked unit still reports its size and you can see what quitting the app would buy you.

Sizes are what deleting would give back: allocated disk blocks, not file lengths, so a sparse file counts for what it occupies. A hard-linked file is counted once, and only when every link to it is inside what is being deleted. The pnpm store is hard-linked into each project's node_modules, so deleting the store alone frees almost nothing, and it is reported that way. After a run, a path unit reports what it measured before minus what is left. A command unit reports the drop in free space around running it, marked measured in --json, because nothing on disk could have said in advance what the tool would remove.

cmd/reclaim/         the CLI
internal/unit/       unit model and registry
internal/catalog/    the table of things worth reclaiming
internal/system/     package-manager caches, journal, kernels, crash artifacts
internal/scan/       dependency and build trees of idle projects
internal/probe/      parallel measurement
internal/lock/       running-application detection
internal/plan/       tier ceiling and selection
internal/runner/     execution, with a protected-path backstop
internal/remove/     tree removal that never leaves its target or filesystem
internal/discover/   caches with no hardcoded rule
internal/unitfile/   unit definitions loaded from files
internal/config/     defaults read from a file
internal/installers/ stale downloads, reported and never removed
internal/report/     text and JSON output
internal/oplog/      append-only record of what was deleted
internal/fsutil/     sizes, mounts, pressure and age
internal/testharness/ sealed sandbox the end-to-end tests run the binary in

Chromium and Electron apps get a deeper sweep. Their data directory is known by Chromium's own marker files (Local State, or Preferences with Network Persistent State), and inside one the layout is fixed: cache-named directories are claimed in the directory itself, in each profile, and in each Partitions/<id>/ -- Postman keeps a whole browser per workspace there. Service Worker/CacheStorage is web apps' offline data, not a cache: it is offered as lossy, behind --site-data --allow-lossy, because deleting it can log you out or make an app download everything again. While such an app runs it holds a SingletonLock naming its host and pid, and its caches are skipped even when the app is not in the lock table.

A flatpak app runs sandboxed, and its command line names a path inside the sandbox, so the process table cannot say which app it is. Flatpak's own instance directory ($XDG_RUNTIME_DIR/.flatpak/<instance>/info) can. A running app's ~/.var/app/<id>/cache moves out of the shared flatpak unit into a locked unit of its own, and every other app's cache is still cleaned by default.

Discovery uses two different rules on purpose. Everything directly under ~/.cache is regenerable by the XDG basedir spec, so it is claimed by location and needs no whitelist. A cache nested inside ~/.config sits beside real application state, so there it is claimed by name against a strict list.

Claiming by location is a sound argument that the contents are regenerable and no argument at all about what regenerating them costs. A model cache and a font cache are both disposable; only one of them is cheap. So once sizes are known, any discovered unit over 1GiB is re-rated: it moves to the cold-reload tier and becomes opt-in behind --heavy. It is still reported — with its size and the flag that would claim it — because hiding the space would be no better than deleting it unasked. RECLAIM_HEAVY_THRESHOLD=500M lowers that bound; it cannot raise it, since nothing in the environment may widen what a run deletes.

Development

make test              # go test ./... and go vet ./...
go test ./... -race    # 286 tests across 16 packages
make dist deb rpm      # release artifacts

The CLI tests build the real binary and run it against a fixture HOME, so flag parsing, exit codes, dry-run behaviour and JSON validity are covered end to end. CI additionally runs the built binary on Debian, Fedora, Arch, openSUSE and Alpine, because the claim that this works beyond Debian only stays true if something keeps checking it somewhere that is not Debian.

Assets are generated, never hand-edited — editing them individually is what let the palette drift the first time:

python3 assets/generate.py && bash assets/render.sh

Status

Linux, on every distribution CI can reach: Debian, Ubuntu, Fedora, Arch, openSUSE and Alpine.

macOS has its own CI job building, testing and running the real binary on macos-latest, and by now covers mount enumeration and disk pressure, process-based lock detection (so a live app's cache is still parked, not just reported as free), the cache catalog, unused-application detection, --system's platform analogues (the unified log and Time Machine local snapshots), release binaries, an .icns icon and a Homebrew Cask (#4, #41 closed; #5 mostly closed — notarising is still open, and needs an Apple Developer account this project does not have). Tracked in the #1 umbrella.

This began as a single self-contained bash script that reached 1615 lines and 201 built-in assertions. It is preserved in git history:

git show 67fd60c:reclaim.sh > reclaim.sh

License

MIT — see LICENSE.

Directories

Path Synopsis
cmd
reclaim command
Command reclaim reclaims disk space on Ubuntu and Debian machines.
Command reclaim reclaims disk space on Ubuntu and Debian machines.
internal
apps
Package apps reports installed applications that have not been used in a long time.
Package apps reports installed applications that have not been used in a long time.
catalog
Package catalog is the table of things worth reclaiming.
Package catalog is the table of things worth reclaiming.
config
Package config reads default flag values from a file.
Package config reads default flag values from a file.
discover
Package discover finds caches the catalog has no hardcoded rule for.
Package discover finds caches the catalog has no hardcoded rule for.
fsutil
Package fsutil measures disk usage and resolves mounts.
Package fsutil measures disk usage and resolves mounts.
index
Package index keeps a snapshot of where the space on a filesystem is, so mapping it does not mean walking it again.
Package index keeps a snapshot of where the space on a filesystem is, so mapping it does not mean walking it again.
installers
Package installers reports downloaded installer files that have gone stale.
Package installers reports downloaded installer files that have gone stale.
lock
Package lock refuses to clean caches belonging to applications that are currently running.
Package lock refuses to clean caches belonging to applications that are currently running.
oplog
Package oplog records what the tool actually deleted.
Package oplog records what the tool actually deleted.
plan
Package plan decides which units run, in what order.
Package plan decides which units run, in what order.
probe
Package probe measures how much each unit would reclaim, without deleting anything.
Package probe measures how much each unit would reclaim, without deleting anything.
remove
Package remove deletes a directory tree without ever leaving it.
Package remove deletes a directory tree without ever leaving it.
report
Package report renders what was found and what happened.
Package report renders what was found and what happened.
runner
Package runner executes a plan.
Package runner executes a plan.
scan
Package scan finds reclaimable space inside project directories.
Package scan finds reclaimable space inside project directories.
system
Package system covers reclaimable space outside the user's home: the package manager cache, the journal, and superseded snap revisions.
Package system covers reclaimable space outside the user's home: the package manager cache, the journal, and superseded snap revisions.
testharness
Package testharness runs the reclaim binary inside a sealed sandbox.
Package testharness runs the reclaim binary inside a sealed sandbox.
unit
Package unit models a single reclaimable thing on disk and the registry that holds them.
Package unit models a single reclaimable thing on disk and the registry that holds them.
unitfile
Package unitfile loads unit definitions from files.
Package unitfile loads unit definitions from files.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL