What Claude Code Leaves on Your Mac's Disk, and What Not to Delete
A read-only prompt makes Claude Code sort its scratch folders, worktrees and session history into in use, recoverable or unknown, with evidence for each.

On this page
TL;DR
Do not delete these folders yet. Claude Code’s scratch checkouts, its worktrees and its ~/.claude directory can hold unpushed commits and session history that exist nowhere else. Paste the prompt below into Claude Code in plan mode (opens in a new tab). Claude Code measures every large item and every worktree and classifies each as IN USE, RECOVERABLE or UNKNOWN, with a line of evidence. Treat UNKNOWN as the default, and never treat a session transcript as recoverable, because a stopped session can be resumed from it. Read the limits before you act on RECOVERABLE, and approve removals one item at a time; the prompt tells Claude Code to delete nothing until you do.
On October 20 I measured the folders that Claude Code leaves behind on my Mac again. Size and age won’t sort them: a folder that looks abandoned can hold the only copy of a commit, or a session you can still resume. This page is part of a series on cleaning up a developer Mac’s disk. If you don’t yet know that agents are what fills your disk, finding what’s taking up the space comes first. If the space is a uv cache that agents filled through MCP servers, that has its own cleanup.
Tested with
- macOS
- 27.0.1 (26A434), APFS, Claude Code=2.1.304
- Date
- October 2026
Run the prompt
Paste this into Claude Code in plan mode (opens in a new tab). Plan mode doesn’t limit Bash to read-only commands on its own, and it writes a plan file of its own. The prompt’s no-write rule is the guard, so watch the first tool calls; see Common failures. I ran it in a fresh session started with claude -p "<prompt>" --permission-mode plan. A -p run is one-shot and ends after the report, so I haven’t tested the prompt’s approval step, which applies only in an interactive session.
You are helping me find out how much disk space my coding agents and their git worktrees are using, and which of it is safe to remove. Do not delete, move, or modify anything, and do not write any file, including a plan or notes file; answer in the chat only. Do not run any command that writes. Use the read-only form of git (git --no-optional-locks status) because plain git status can rewrite the index. If I want something removed, you will propose it and wait for my approval.
1. Measure. Report the size of: (a) the agent temporary scratch area (for tools that use a per-session scratchpad under the system temp folder, list each session's scratchpad with its size), (b) the agent's configuration and session-history directory in my home folder, broken down by its largest subdirectories, (c) every git worktree: run `git worktree list` in each repository under my projects folder and give each linked worktree's path and size. Use du; note that du counts APFS clones at full size, so totals are an upper bound.
2. Classify every item over 100 MB, and every worktree, as exactly one of:
- IN USE: a running process has its working directory or files there (check with ps and lsof on the process list, not by assumption), or it is the scratchpad of a session that is running now (including this one).
- RECOVERABLE: nothing is running there, `git status` shows no uncommitted changes, no untracked files you cannot regenerate, and every local commit is pushed (compare with the upstream branch); or it is a plain build or dependency folder (node_modules, .build, .venv) that can be rebuilt.
- UNKNOWN: anything else, including when you could not check. A session transcript or history folder is never RECOVERABLE: a stopped session can still be resumed from it, and it cannot be regenerated. A folder holding a worktree whose branch has commits that exist nowhere else is UNKNOWN even if the folder itself is missing.
For each item give the evidence in one line: the process found or not found, the git status result, the unpushed commit count, the last-modified time.
3. Report as a table: path, size, class, evidence. Then totals per class. State what your checks could not see, for example a session that is stopped but could be resumed, or a worktree with a stash.
4. Stop. Do not delete anything. Ask which items I want removed, and say for each which tool's own command you would use (`git worktree remove`, `swift package reset`, deleting the folder).The prompt avoids Claude Code’s names, but I tested it only in Claude Code.
Read the table by class
A session transcript or history folder is never RECOVERABLE: a stopped session can be resumed from it with --resume, and it can’t be regenerated. In my run, a running session’s transcripts came back IN USE and the rest UNKNOWN. Claude Code already deletes transcripts older than its cleanupPeriodDays setting (see the settings reference (opens in a new tab)); change that setting rather than deleting transcripts by hand.
A worktree whose folder is gone can still matter. A worktree is a second working folder for a repository, and git records it in the repository itself. If the worktree was on a detached HEAD, its HEAD in the repository may be the only reference to its commits, even though the folder is gone. A named branch survives removing the worktree; its unpushed commits are at risk only if you later delete the branch. The prompt classes such a worktree as UNKNOWN.
The report ends with totals per class and a list of what the checks couldn’t see. Read the list before the totals.
What the report cannot see
Claude Code can’t check everything, and the prompt makes it say so. In my run it listed these:
- A stopped session that could be resumed. The check finds that no process is running, not whether you’ll come back to it.
- Short-lived processes. A process that wasn’t running at the moment of the check doesn’t show up in
ps. - Remote-tracking refs last fetched months ago. The unpushed count compares local commits with the last-fetched state of the remote, so it can be wrong in either direction. In the test Claude Code didn’t run
git ls-remote, which contacts the network. - A stash. Stashes are repository-wide, and a worktree’s
git statusdoesn’t show them. - Ignored files in clones. Files that git ignores don’t appear in
git status, so a RECOVERABLE clone can still hold something you made.
du has a limit of its own. It counts APFS clones at full size, so every total is an upper bound on what deleting frees. Measure the container’s free space before and after, as in finding what’s taking up the space, to see what the Mac actually got back.
Approve removals one item at a time
The prompt’s last step tells Claude Code to stop after the report and ask which items you want removed. For each item it names the tool’s own command: git worktree remove for a worktree, swift package reset for a Swift package’s build state, or deleting the folder. My test run was one-shot, so I haven’t seen this step in an interactive session.
Decide per item, not per class. RECOVERABLE means the checks found nothing to lose, not that the item is certain to be safe, so go through the limits in the previous section first. A line of evidence you can’t explain is a reason to refuse that item.
Warning
Do not let the agent run git worktree prune while a missing worktree in the repository is on a detached HEAD. Pruning clears every missing worktree in a repository, not only the one you have in mind. A detached worktree’s HEAD can be the only reference to its commits (git worktree (opens in a new tab)). Git also removes a missing worktree’s records on its own after a while (gc.worktreePruneExpire), so do not leave those commits without a branch. Give each one a branch first: read the commit from git worktree list --porcelain and run git branch keep-<name> <commit>. Remove a worktree whose folder still exists with git worktree remove <path>; removing it without a branch drops the reference exactly as pruning does. The report drew the same line: it called pruning safe for worktrees whose branches existed and unsafe for those on a detached HEAD.
What one run found
Numbers from one Mac on October 20. The prompt asks about all my coding agents, so the report also measured a second agent’s directory, ~/.codex. It was the largest item, and this page doesn’t cover cleaning it. Worktrees whose folders were gone still referenced commits.
| Item | Size | What it was |
|---|---|---|
| Claude Code temporary scratch area | 2.0 GB | 66 per-session scratchpads; the largest 1.3 GB, the next 246 MB |
~/.claude | 3.7 GB | Session transcripts (projects) 2.6 GB, the largest part |
A second agent’s directory, ~/.codex | 7.8 GB | Packages 2.0 GB, sessions 1.9 GB, a history database 1.5 GB, generated images 1.1 GB |
Claude Code classed the second agent’s package folder IN USE, because a running process executed from it. It classed three worktrees on a detached HEAD, whose folders were gone, as UNKNOWN.
The class totals were about 2.6 GB IN USE, 1.5 GB RECOVERABLE and 8.7 GB UNKNOWN; most of the UNKNOWN was the rest of the second agent’s directory. The totals cover only what the prompt classifies, items over 100 MB and worktrees, so they don’t add up to the table.
I checked the Claude Code sizes against my own du; the ~/.codex figures are the agent’s. I checked that the second run wrote no plan file. I didn’t check each classification line. Treat the classes as the agent’s report, not as my measurement.
Claude Code counted 19 linked worktrees across 9 repositories. My own search, to six directory levels, found 16, plus 12 .claude/worktrees directories under my projects folder.
Common failures
Plan file appears after a read-only run
A new file appears in ~/.claude/plans after the report. Plan mode writes a plan file by a mechanism of its own, and a prompt that only says not to modify anything doesn’t stop it. My first run, with that wording, wrote one. Keep the prompt’s line that forbids writing any file, including a plan or notes file; with it, my second run wrote none. After a run, list the folder newest first and check for a file from that run:
$ ls -lt ~/.claude/plans