Skip to main content

Lysosome Disk Cleaner

· 7 min read
Scott Havird
Engineer at Georgia-Pacific · ex-WarnerMedia Innovation Lab (ContentAI) · decade shipping AI-powered platforms

My laptop filled up again. Cursor and Claude Code had left git worktrees on disk, with node_modules and target folders still in them. I wrote lysosome to list those and delete the safe ones.

TL;DR

lysosome scans dormant git worktrees, idle build artifacts, package caches, local models, Docker, and Xcode data. lysosome clean is a dry run until you pass --yes or type y, and deletes go to the Trash.

Motivation​

The branch gets merged. The worktree stays, dependencies and all. Ollama, Hugging Face, and LM Studio do the same thing with model weights.

I didn't want another afternoon of du, or a script that runs rm and hopes.

Teams running many agents hit the same leftover worktrees and caches.

What​

lysosome is a Rust CLI, MIT licensed. The README calls it "The disk cleaner for the agentic coding era."

lysosome scan       # artifacts, worktrees, caches
lysosome worktrees
lysosome caches # alias: system
lysosome clean # dry run unless --yes, or you answer y

scan labels every row.

  • REMOVABLE: idle and clean. The commits are merged into the default branch, fully pushed, or gh reports an exact HEAD squash-merge.
  • REVIEW: uncommitted changes, untracked files, a lock, or commits that exist nowhere else.
  • ORPHAN: the parent repo was moved or deleted.
  • ACTIVE: hidden unless you pass --all.

Build folders count only if git check-ignore agrees. Symlinks are never followed. Default staleness is --days 30 per project.

node_modules, .venv, venv, and Pods are regenerable_expensive. Other ignored build output is regenerable: target, .next, .nuxt, .svelte-kit, .turbo, dist, build, .gradle, .dart_tool, .build, coverage, .parcel-cache, .expo, DerivedData. clean removes regenerable only, unless you pass --tier regenerable_expensive. That adds dependencies, models, Docker images, and simulators. The review tier is never cleaned.

The shots below are a demo. I generated a folder of sample clutter on a Linux test box and pointed lysosome v0.3.0 at it. Not my laptop. Nothing was deleted.

Demo run of lysosome scan against a folder of sample clutter, not my actual laptop

Demo run against a folder of sample clutter, not my actual laptop.

Demo run of lysosome worktrees --all against a folder of sample clutter, not my actual laptop

Demo run against a folder of sample clutter, not my actual laptop. Passing --all includes the active worktree.

How​

Scans do not write. Git is invoked with --no-optional-locks.

Removable worktrees are removed with git, then pruned. The branch is kept. git worktree remove is called without --force. REVIEW, ACTIVE, and ORPHAN are never cleaned.

git -C <repo> worktree remove <path>

.env and other precious ignored files are moved to the Trash before that remove. The home folder is never deleted.

The default is Trash (macOS Trash, freedesktop trash on Linux). --permanent has to be paired with --yes. lysosome checks the target again right before it deletes, and skips the row if anything changed.

lysosome clean -i walks the list. On macOS the log is ~/Library/Logs/lysosome/actions.log. --json prints a versioned schema. It does not send telemetry.

Squash-merge lookups use gh, and only if it is installed and you are signed in. --no-gh or --offline skips that call.

lysosome caches reports:

  • Package caches: npm, pnpm, yarn, bun, pip, uv, conda, cargo, go, gradle, maven, Homebrew, CocoaPods.
  • Models: Ollama by name, Hugging Face hub, LM Studio, ~/.cache/torch, whisper.
  • Docker images, build cache, and volumes. OrbStack stays in review.
  • Xcode DerivedData, iOS DeviceSupport, simulators, Archives.
  • Android AVDs and SDK images.
  • VS Code, Cursor, and JetBrains caches.

lysosome caches on that same demo folder. Each row names the tool's own cleanup command.

Demo run of lysosome caches against a folder of sample clutter, not my actual laptop

Same demo folder, not my laptop.

Found a Bug​

Unfortunately v0.3.0 under-counts sizes on overlay filesystems. That is what Docker and containers use. Regular files report a different st_dev than their folders, and the same-filesystem check skipped every file.

A 20 MB file in an ignored node_modules showed as 4.1 KB. The demo clutter showed 3.3 MB instead of 3.8 GB. I filed issue #36.

PR #37 only applies the device check to directories. On a real overlay filesystem the fixed build matches du byte for byte, and it still skips a separately mounted filesystem inside a folder. The PR is open. It is not in a release yet.

v0.3.0 scan of a 20 MB node_modules on overlayfs, reported as 4.1 KB

v0.3.0 on the repro. The 20 MB file showed as 4.1 KB.

PR #37 build of the same overlayfs repro, reported as 21.0 MB. Not in a release yet.

Same repro, PR #37 build. It shows 21.0 MB. Not released yet.

The demo shots above are from an ext4 disk image, where this bug does not show up.

Setup​

macOS (Apple silicon and Intel) and Linux (x86_64 and arm64). git needs to be on your PATH.

brew install lysosome-dev/tap/lysosome
curl -fsSL https://lysosome.dev/install.sh | sh
cargo install --locked lysosome # Rust 1.85+

When I wrote this, lysosome --version was v0.3.0, published October 10, 2026.

lysosome --help on v0.3.0

Help from v0.3.0. This is the real command, not the demo folder.

One Long Day​

The GitHub repo went up October 10, 2026, around 03:01 UTC. I did not ship the milestones in number order.

The worktree scanner landed first (PR #2, 03:49). Distribution came next, before the rest of the scanner existed: cargo-dist, the install script, Homebrew, and shell completions (PR #6, 04:52). v0.1.0 went out at 04:56. That release is the worktree scanner and the installers.

Caches merged before project artifacts. PR #8 at 05:11, then PR #7 (lysosome scan) at 05:29. I had opened #7 a minute before #8. PR #11 at 05:43 made scan include the caches.

lysosome clean landed at 06:34 (PR #12). v0.2.0 at 06:39. v0.2.1 at 07:21 stopped a scan from running corepack shims (PR #14).

The afternoon was smaller. Interactive clean, crates.io publishing, squash-merge checks through gh, parallel sizing, JSON errors, brand colors. PR #31 cut the release. v0.3.0 was published at 16:49.

Future Ideas​

  • A Mac app on the same engine. There is a waitlist at lysosome.dev.

Summary​

Lysosome lists dormant worktrees, idle build folders, dev caches, and local models. It leaves REVIEW, ACTIVE, and ORPHAN rows alone. clean waits for a confirmation, and removals go to the Trash.

The pictures above are that demo folder. Run lysosome scan on your own machine to see what it finds.

Source Code​