Clean up abandoned worktrees, lock files, and orphaned branches
Removes abandoned git worktrees, lock files, and orphaned branches to free up system resources.
/plugin marketplace add cowwoc/cat/plugin install cat@claude-code-cathaikuAll abandoned CAT artifacts (worktrees, locks, branches) are identified and cleaned up safely.
git -C <path> insteadRun all survey commands to gather current artifact state.
Worktrees:
git worktree list
Task locks:
if [[ -d .claude/cat/locks ]]; then
"${CLAUDE_PLUGIN_ROOT}/scripts/task-lock.sh" list "${CLAUDE_PROJECT_DIR}" 2>/dev/null
else
echo "[]"
fi
Context files:
ls -la .cat-execution-context 2>/dev/null || echo "No context file"
CAT branches:
git branch -a | grep -E '(release/|worktree|[0-9]+\.[0-9]+-)' || echo "No CAT branches"
Remote branch staleness (1-7 days idle):
git fetch --prune 2>/dev/null
for remote_branch in $(git branch -r 2>/dev/null | grep -E 'origin/[0-9]+\.[0-9]+-' | tr -d ' '); do
COMMIT_DATE=$(git log -1 --format='%ct' "$remote_branch" 2>/dev/null)
NOW=$(date +%s)
AGE_DAYS=$(( (NOW - COMMIT_DATE) / 86400 ))
if [ "$AGE_DAYS" -ge 1 ] && [ "$AGE_DAYS" -le 7 ]; then
AUTHOR=$(git log -1 --format='%an' "$remote_branch" 2>/dev/null)
RELATIVE=$(git log -1 --format='%cr' "$remote_branch" 2>/dev/null)
echo "STALE: $remote_branch (last: $AUTHOR, $RELATIVE)"
fi
done
Invoke handler to generate display:
{
"handler": "cleanup",
"context": {
"phase": "survey",
"worktrees": [{"path": "<path>", "branch": "<branch>", "state": "<state>"}],
"locks": [{"task_id": "<id>", "session": "<session-id>", "age": <seconds>}],
"branches": ["<branch-name>"],
"stale_remotes": [{"branch": "<name>", "author": "<author>", "relative": "<time>"}],
"context_file": "<path-or-null>"
}
}
Output the PRE-COMPUTED SURVEY DISPLAY from the handler exactly as provided. Do NOT copy the example below - it shows format only. Use the handler output.
Analyze survey results to classify artifacts:
Abandoned worktree indicators:
Stale lock indicators:
For each lock, check status:
task_id="<from-survey>"
"${CLAUDE_PLUGIN_ROOT}/scripts/task-lock.sh" check "${CLAUDE_PROJECT_DIR}" "$task_id"
The output shows: {"locked":true,"session_id":"...","age_seconds":...,"worktree":"..."}
Present classification:
## Abandoned Artifacts
### Likely Abandoned
- <artifact>: <reason>
### Possibly Active
- <artifact>: <reason for caution>
### Safe to Keep
- <artifact>: <reason>
CRITICAL: Use git -C <path> - NEVER cd into a worktree that will be deleted.
For each worktree identified as abandoned:
WORKTREE_PATH="<path-from-survey>"
git -C "$WORKTREE_PATH" status --porcelain
If output is non-empty, there is uncommitted work.
Present findings:
## Uncommitted Work Check
### <worktree-path>
Status: CLEAN | HAS UNCOMMITTED WORK
If uncommitted:
Modified files:
- <file1>
- <file2>
Options:
1. Commit changes first
2. Stash: git -C <path> stash
3. Discard: git -C <path> checkout -- . (DESTRUCTIVE)
4. Skip this worktree
BLOCKING: Do NOT proceed with removal until user confirms action for each worktree with uncommitted work.
Invoke handler to generate display:
{
"handler": "cleanup",
"context": {
"phase": "plan",
"locks_to_remove": ["<task-id>"],
"worktrees_to_remove": [{"path": "<path>", "branch": "<branch>"}],
"branches_to_remove": ["<branch-name>"],
"stale_remotes": [{"branch": "<name>", "staleness": "<info>"}]
}
}
Output the PRE-COMPUTED PLAN DISPLAY from the handler exactly as provided. Do NOT copy any example boxes - use the handler output.
BLOCKING: Do NOT execute cleanup without explicit user confirmation.
Execute in strict order. Errors should propagate - do not suppress with || true.
Order matters:
Remove stale locks:
task_id="<from-plan>"
"${CLAUDE_PLUGIN_ROOT}/scripts/task-lock.sh" force-release "${CLAUDE_PROJECT_DIR}" "$task_id"
Remove worktrees:
WORKTREE_PATH="<from-plan>"
git worktree remove "$WORKTREE_PATH" --force
Remove orphaned branches:
BRANCH_NAME="<from-plan>"
git branch -D "$BRANCH_NAME"
Remove context file (if applicable):
rm .cat-execution-context
Report each action:
## Cleanup Progress
- [x] Removed lock: <task-id>
- [x] Removed worktree: <path>
- [x] Removed branch: <branch>
- [x] Removed context file
Run verification commands:
echo "Remaining worktrees:"
git worktree list
echo "Remaining CAT branches:"
git branch -a | grep -E '(release/|worktree|[0-9]+\.[0-9]+-)' || echo "None"
echo "Remaining locks:"
if [[ -d .claude/cat/locks ]]; then
ls .claude/cat/locks/*.lock 2>/dev/null || echo "None"
else
echo "None"
fi
Invoke handler to generate display:
{
"handler": "cleanup",
"context": {
"phase": "verify",
"remaining_worktrees": ["<path>"],
"remaining_branches": ["<branch>"],
"remaining_locks": ["<lock-id>"],
"removed_counts": {"locks": <n>, "worktrees": <n>, "branches": <n>}
}
}
Output the PRE-COMPUTED VERIFY DISPLAY from the handler exactly as provided. Do NOT copy any example boxes - use the handler output.
Symptoms: Lock file exists, worktree may have partial work
Action:
Symptoms: Multiple stale worktrees and lock files
Action:
Symptoms: "Task locked by another session" error but no active session
Action:
Symptoms: Branches exist but no worktrees reference them
Action:
/cleanupUnified codebase cleanup orchestrating bloat removal, code refinement, and hygiene auditing