agent-runner: prune .claude/worktrees/agent-* on session/branch end
Summary
When the Agent tool is invoked with isolation: \"worktree\", Claude Code creates a git worktree at .claude/worktrees/agent-<id>/ and a paired worktree-agent-<id> branch. After the agent thread terminates (success, failure, or timeout), neither the worktree directory nor its branch is pruned. Disk usage grows unbounded across project sessions.
Repro
In any moderately active project (mine: ~9 days of dispatch-heavy planning waves), check:
$ ls .claude/worktrees/ | wc -l
48
$ du -sh .claude/worktrees/
11G
$ git branch | grep -c worktree-agent-
46
48 directories, 46 stale branches, 11 GB on disk — none of those agent threads are still alive. PIDs in the worktree .git/locked files are long dead. Each worktree carries a full checkout (~230 MB) plus whatever the agent built into it.
Why it bites harder than just disk
There's a related correctness hazard: the worktree-merge \"silent no-op\" pattern where a leftover worktree leaves the parent repo's HEAD on worktree-agent-* instead of main, and a subsequent git merge --no-ff <agent-branch> reports \"Already up to date\" against the wrong branch. Pruning closed-thread worktrees eagerly cuts the surface area for this.
(I run a dedicated ## Worktree discipline section in my repo's CLAUDE.md warning every session to verify pwd and git branch --show-current before any merge — but that's a workaround for the cleanup gap, not a fix.)
Proposal
When an agent thread reaches a terminal state, the runner should:
git worktree unlockthe agent's worktree (currently auto-locked with the runner's pid).git worktree remove --force <path>to drop the directory.git branch -D worktree-agent-<id>if the branch's commits are merged into the agent's target (or if the agent thread errored out without committing anything).- If the branch carries unmerged commits AND the agent succeeded, leave it but log a one-liner so the user can rescue the work; otherwise prune.
- As a backstop, ship a
claude doctor-style command that bulk-prunes any.claude/worktrees/agent-*whose owning pid is no longer alive.
References
- 2026-05-01 manual cleanup of 46 stale agent worktrees (~10.93 GB reclaimed) was Wave F P8.3 of an internal hygiene plan; tracked in change_proposal
0767d626-1866-4a9d-a148-6708d0b4dc1f(private repo) under goal #18 + Pattern D \"agent worktree leak\". - Plan ID for the cleanup wave:
fe2acff3-efc0-439b-8da5-988e628b10c7.
Happy to share the cleanup workflow we ran if helpful.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗