{"id":"8aa97249-29d7-4273-9818-cf85368b1580","slug":"freespace","kind":"skill","name":"freespace","summary":"Frees disk space on a Mac used for development: rebuildable caches, build output and merged git worktrees. Dry run first. Also installs as an agent skill for Claude Code, Codex, Gemini CLI and Grok.","owner":"jcobhams","repoUrl":"https://github.com/jcobhams/freespace","license":"MIT","licenseTier":"permissive","trust":"community","stars":5,"match":null,"fewStars":false,"format":"skill","createdAt":"2026-10-17T23:02:40.000Z","addedAt":"2026-10-21T11:46:01.925Z","logoUrl":"https://avatars.githubusercontent.com/u/5455248?u=f949aff8f96b0eb52f01711bc93fe8fab408eaa4&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools"],"tags":["claude-code","codex","developer-tools","disk-cleanup","gemini","grok","macos"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-26T19:01:43.348Z","sample":false,"url":"https://conduits.dev/tools/freespace","language":"Shell","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# freespace\n\n`freespace` frees disk space on a Mac. It clears caches and build output that your tools can rebuild, and git worktrees whose work is already merged.\n\nIt shows what it would remove before it removes anything. A plain `freespace` is always a dry run.\n\n## Install\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/jcobhams/freespace/master/install.sh | bash\n```\n\nThis downloads freespace into `~/.local/share/freespace` and links the `freespace` command into `~/.local/bin`. It also links the agent skill into every AI coding agent it finds, as described in [Use it from an AI agent](#use-it-from-an-ai-agent). Run the same command again to update.\n\nTo uninstall:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/jcobhams/freespace/master/install.sh | bash -s -- --uninstall\n```\n\n`FREESPACE_BIN` changes where the command goes, `FREESPACE_HOME` changes where the download goes, and `FREESPACE_REF` installs a branch or tag other than `master`. The installer never replaces a folder it didn't create.\n\nIf you'd rather work from a clone, run the installer from it. The links then point into the clone, so `git pull` updates them:\n\n```bash\ngit clone https://github.com/jcobhams/freespace.git\ncd freespace\n./install.sh\n```\n\nYou can also skip the installer and run `./freespace` from the clone.\n\nIt needs macOS and git. It runs on the bash that ships with macOS. Each section checks for its tool first, so one you don't use (Docker, Rust, Xcode) skips itself.\n\n## Use\n\n```bash\nfreespace                      # dry run: what would go, and how big it is\nfreespace --apply              # remove it\nfreespace --ask                # go through it item by item, asking before each one\nfreespace --only node,python   # just these sections\nfreespace --skip docker,xcode  # everything except these\nfreespace --help               # all sections and options\n```\n\nTo choose what goes, pick sections with `--only` and `--skip`, and folders with `--scan` and `--exclude`. For example, this removes one old project's `node_modules` and nothing else:\n\n```bash\nfreespace --only node --scan ~/code/old-project --project-days 0 --apply\n```\n\n`--ask` lets you decide item by item instead. It shows each item with its size and asks before removing it. Enter keeps it, so nothing goes unless you type `y`.\n\nIn a dry run, a line that starts with a size is something `--apply` removes. Lines that start with \"kept\" explain what it left alone and why. Commands it would run are shown as `would run:`.\n\n```\nNode and Next build output\n  10.9 GB  ~/code/dash/.next\n  802.5 MB  ~/code/videos/node_modules (project untouched for 14+ days)\n  kept 55 folders in use now or in projects changed in the last 14 days\n\nGit worktrees\n  kept ~/code/api/.worktrees/deposits: used in the last 2 days\n  183.0 MB  ~/code/api/.worktrees/search (feature/search, merged into main)\n    would run: git -C ~/code/api worktree remove --force ~/code/api/.worktrees/search\n\nTotal\n  281.4 GB  this run frees with --apply\n  336.9 GB  with every option on:\n    +35.9 GB  --project-days 0\n    +3.5 GB  --days 0\n    +8.3 GB  --include-unmerged\n    +7.8 GB  --min-ios 27\n```\n\nThe dry run ends with a total. The first line is what this run frees. The second is what you'd free with every opt-in option turned on, followed by what each option adds. Simulator clones, the pnpm store, conda and dangling Docker images aren't counted, because their size can't be measured reliably up front. A dry run that measures the options takes a few minutes, since it sizes everything it keeps too.\n\nAfter `--apply` it prints your free space before and after.\n\n## Use it from an AI agent\n\n`skills/freespace` is an [Agent Skill](https://agentskills.io): a folder with a `SKILL.md` that tells a coding agent when and how to run `freespace`. Once it's installed, you can ask your agent things like \"why is my disk full?\" or \"free up some space\". The skill tells the agent to run a dry run first, show you the total, and only run `--apply` after you say yes.\n\nThe installer links it for every agent it finds:\n\n| Agent | Skill folder |\n|---|---|\n| Claude Code | `~/.claude/skills/freespace`, and `$CLAUDE_CONFIG_DIR/skills/freespace` when that is set |\n| Codex, Gemini CLI | `~/.agents/skills/freespace` |\n| Grok | `~/.grok/skills/freespace` |\n\nTo add it to another agent that reads Agent Skills, link `~/.local/share/freespace/skills/freespace` into the skills folder that agent's docs name, as a folder called `freespace`. From a clone, link `skills/freespace` inside the clone instead.\n\nCopy it with `cp -RL` instead of `cp -R` if you'd rather not link it. The skill's `scripts/freespace` is a link to the script at the top of the repo, and `-L` copies the real file. Start a new agent session afterwards so it picks the skill up.\n\n## What it removes\n\n| Section | Removes | Comes back with |\n|---|---|---|\n| `claude-tmp` | Claude Code session temp folders untouched for 2 days, and Xcode build folders inside newer sessions' scratchpads | Claude Code makes new ones |\n| `go-cache` | The Go build cache | The next `go build` or `go test` |\n| `jetbrains` | Caches and logs of JetBrains IDE versions that a newer version replaced | Nothing needed |\n| `packages` | bun, yarn and npm caches (including npx downloads), Homebrew downloads and old formula versions, unreferenced pnpm packages | The next install downloads them |\n| `node` | `.next`, `.open-next` and `.turbo`, plus `node_modules` in projects untouched for 14 days | `next dev` or `next build`, and `npm install` or `bun install` |\n| `rust` | `target/` in Cargo projects untouched for 14 days, and cargo's unpacked registry sources and git checkouts | `cargo build` |\n| `cpp` | CMake, CLion (`cmake-build-*`) and Meson build folders in projects untouched for 14 days, and the ccache cache | Configure and build again |\n| `python` | pip, uv, poetry, conda and pre-commit caches; `__pycache__`, pytest, mypy, ruff, tox and nox caches; `.venv` and `venv` in projects untouched for 14 days | `uv sync`, `poetry install` or `pip install -r requirements.txt` |\n| `docker` | Build cache and dangling images. With `--docker-all`, also images no container uses, stopped containers and unused networks | `docker build` or `docker pull` |\n| `xcode` | Simulator clones from parallel testing, DerivedData, simulators for runtimes that are no longer installed | The next build or test run |\n| `old-ios` | iOS simulator runtimes older than `--min-ios`, and their simulators. Off unless you pass `--min-ios` | Xcode, Settings, Components |\n| `worktrees` | Git worktrees that are merged, clean and idle, plus their local branches and empty leftover worktree folders | `git worktree add` |\n\n`node`, `rust`, `cpp`, `python` and `worktrees` search every folder in your home folder except hidden ones, `Library`, `Applications`, `Movies`, `Music`, `Pictures`, `Public`, `OrbStack` and the Go module cache. They also search `~/.config/superpowers/worktrees`. Use `--scan` to search only the folders you name, and `--exclude` to skip one.\n\n## How it stays safe\n\n- Nothing is deleted without `--apply` or `--ask`, and the config file can't turn either on.\n- It only deletes inside your home folder and the Claude Code temp folder. It resolves parent symlinks and `..` before checking containment, then checks again before deletion. The roots themselves and final symlinks are kept.\n- Build output written in the last hour is kept, so a running dev server or build keeps its files.\n- `node_modules`, Rust `target/` folders, C++ build folders and virtual environments are only removed from projects with no file changes in 14 days (`--project-days`).\n- Worktree paths are resolved before checking them against scan roots, exclusions, and your home folder. These checks run again after confirmation, immediately before removal. The same boundaries apply to empty leftover worktree folders.\n- A worktree is only removed when all of these hold:\n  - its branch is merged into the repo's `main` or `master`;\n  - it has no uncommitted changes (Finder's `.DS_Store` files don't count);\n  - it had no commits or checkouts in the last 2 days (`--days`);\n  - it isn't locked.\n- Its branch is then deleted with `git branch -d`, which refuses anything unmerged.\n- An unmerged worktree is kept. With `--include-unmerged`, its folder goes but its branch stays, and the output shows the command that brings it back.\n- A worktree whose repo has moved gets its `.git` link repaired before it's checked.\n- C++ builds inside the source folder (in-source builds) are never removed, and neither are virtual environments without a `pyproject.toml`, `requirements*.txt`, `Pipfile`, `setup.py` or `uv.lock` to rebuild them from.\n- Docker volumes and poetry's virtualenvs are never removed.\n- Nothing is removed from hidden folders in your home folder, so tools like `~/.nvm` and `~/.vscode` keep their own `node_modules`.\n- The Xcode section waits while `xcodebuild` is running, and cargo's sources are kept while `cargo` is running.\n\n## Options\n\n| Option | Default | What it does |\n|---|---|---|\n| `--apply` | off | Remove things instead of listing them |\n| `--ask` | off | Like `--apply`, but asks before each item. `y` removes it, Enter or `n` keeps it, `s` keeps the rest of that section, `q` stops |\n| `--only a,b` | all | Run only these sections |\n| `--skip a,b` | none | Run every section except these |\n| `--days N` | 2 | How long a Claude Code session or a worktree must sit unused |\n| `--project-days N` | 14 | How long a project must sit unchanged before its dependencies and builds go |\n| `--min-ios N` | off | Remove iOS simulator runtimes older than iOS N |\n| `--include-unmerged` | off | Also remove clean, idle worktrees of unmerged branches (the branches stay) |\n| `--docker-all` | off | Also remove unused Docker images, stopped containers and unused networks |\n| `--scan DIR` | home folder | Search only this folder. Repeat it for more than one |\n| `--exclude DIR` | none | Skip this folder. Repeat it for more than one |\n\n`--days 0` and `--project-days 0` drop the waiting period. The one-hour guard still applies.\n\n## Config file\n\nPut options you always want in `~/.config/freespace/options`, one per line. Command-line options override them.\n\n```\n# Docker keeps its data here\n--exclude ~/docker-data\n--min-ios 26\n--project-days 30\n```\n\n`FREESPACE_CONFIG` points it at a different file. Use one option per line, with its value on the same line when required. Paths may contain spaces. Invalid lines stop the run; `--apply` and `--ask` are only allowed on the command line.\n\n## Good to know\n\n- `du` over-reports simulator clones, because APFS copies share disk blocks. That's why the summary compares free space before and after instead of adding up folder sizes.\n- macOS removes deleted simulator runtimes in the background. Check your free space again a few minutes later.\n- Docker Desktop and OrbStack keep images inside a disk image. Space can take a while to return to your Mac after Docker deletes things.\n- The Go build cache can grow by hundreds of gigabytes in a few days if you build in many worktrees. `freespace --only go-cache --apply` is worth running often.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n"}