Group of 6 Under the hood
Sessions and worktrees can now be force-removed when git or hooks can't clean them up, with new safety checks and a fleet-view confirmation
What
- Job/session deletion logic now supports an explicit force-remove path for a worktree's directory, used when the normal removal (via git or the WorktreeRemove hook) can't clean it up.
- Before force-removing, Claude Code checks for nested git repositories, tracked (not just uncommitted) changes, and verifies the worktree is actually registered in git's own worktree list; the worktree-state check now separately reports
trackedChanges(real edits) versus plaindirty(which includes untracked files). - If removal is still withheld, the reason is one of
tracked_changes,nested_repositories,nested_unverified, ornot_registered, and a newaFtmessage generator produces detailed explanations for every possible refusal reason (dirty, unpushed, unpushed_shared, in_use, live_lock, occupied, shared_record, records_unreadable, unverified, identity_changed, and the remove_failed sub-reasons above). - The
claude rmCLI command gains two new flags:--discard-unpushed <commit>@<worktree-id>to discard unpushed/uncommitted changes on a worktree still at a given commit, and--force-remove-worktree <worktree-id>to force-delete a worktree directory. - The fleet view's job-delete action gained a second confirm-and-retry path for force-removing a worktree (alongside the existing 'discard unpushed changes' offer), and reports whether the branch was preserved.
- Deletion telemetry and results now distinguish a forced removal from the existing 'left worktree in place' outcome, via a new
worktree_force_removedevent and aforcedWorktreeRemoval/forceRemoveWithheldresult field.
Why
Worktrees (the separate folders git uses for each session's checkout) can get stuck when git or a cleanup hook can't remove them, blocking session/job deletion. This gives users and the CLI an explicit, safety-checked way to force the removal through instead of leaving orphaned directories behind, while refusing to blow away directories with nested repos or real tracked changes without being told to.