Подготовка к переходу на 'claude agents' dashboard как daily driver:
- scripts/cleanup-merged-worktrees.sh: removes worktrees whose branch is
ancestor of forgejo/main. Run weekly via cron or manually after merge
bursts. Safe — skips unmerged branches and current worktree.
- .worktreeinclude: copies .env files + .mcp.json into every new worktree
(otherwise backend/frontend/MCP fail to start in fresh worktrees Claude
creates for background sessions).
- .claude/rules/git-pr.md:
- new MANDATORY workflow: default 'claude --bg --name X' background
session (auto worktree, auto baseRef=fresh) vs foreground fallback
- session naming convention (--name kebab-case)
- polling section: preferred (agents view row status ●) vs foreground
fallback (Skill loop)
- new 'Multi-session workflow (Agent View)' section: parallelism budget,
Ctrl+T pin, deprecated 'manual git worktree add', weekly cleanup ref
Local-only (not in this PR):
- .claude/settings.json: worktree.{baseRef:fresh, bgIsolation:worktree}
(gitignored as personal preference)
Pre-cleanup state: 102 worktrees / 14GB. After: 99 / 14GB — only 3 squash-
merged branches removed via safe --is-ancestor check; 99 retained as
unmerged WIP. Aggressive cleanup (by age + Forgejo PR check) — future PR.
71 lines
2.5 KiB
Bash
Executable file
71 lines
2.5 KiB
Bash
Executable file
#!/bin/bash
|
||
# Cleanup merged Claude Code background-session worktrees.
|
||
#
|
||
# `claude agents` / `claude --bg` создают `.claude/worktrees/agent-*` для
|
||
# каждой background session. После merge PR worktree остаётся locked
|
||
# и не удаляется автоматически — за неделю накапливаются десятки.
|
||
#
|
||
# Скрипт сравнивает branch каждого worktree с `forgejo/main`; если branch
|
||
# полностью в main (merged) — удаляет worktree с `--force` (worktree
|
||
# заперт супервизором). Затем `git worktree prune` чистит references.
|
||
#
|
||
# Запускать вручную или через cron (weekly recommended):
|
||
# 0 9 * * MON cd /path/to/gendesign && ./scripts/cleanup-merged-worktrees.sh
|
||
#
|
||
# Safe:
|
||
# - Не трогает unmerged branches (in-progress work, PR ещё не merged)
|
||
# - Не трогает worktree.lock с твоими running sessions (force нужен только
|
||
# потому что Claude Code ставит lock автоматически)
|
||
# - Логи action — каждый удалённый branch выводится отдельной строкой
|
||
#
|
||
# Reference: https://code.claude.com/docs/en/worktrees#clean-up-worktrees
|
||
|
||
set -e
|
||
|
||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||
cd "$REPO_ROOT"
|
||
|
||
echo "Fetching forgejo/main..."
|
||
git fetch forgejo main --quiet
|
||
|
||
BEFORE=$(git worktree list | wc -l)
|
||
SIZE_BEFORE=$(du -sh .claude/worktrees/ 2>/dev/null | awk '{print $1}')
|
||
|
||
echo "Scanning $((BEFORE - 1)) worktrees (skip main)..."
|
||
|
||
REMOVED=0
|
||
KEPT=0
|
||
|
||
# Parse `git worktree list --porcelain` into "path branch" pairs.
|
||
git worktree list --porcelain | awk '/^worktree/{w=$2} /^branch/{b=$2} /^$/{print w" "b}' | \
|
||
while read path branch; do
|
||
# Skip main worktree (no branch field) and detached HEADs.
|
||
[ -z "$branch" ] && continue
|
||
|
||
short="${branch#refs/heads/}"
|
||
|
||
# Don't touch the worktree we're standing in.
|
||
if [ "$path" = "$REPO_ROOT" ]; then
|
||
continue
|
||
fi
|
||
|
||
if git merge-base --is-ancestor "$short" forgejo/main 2>/dev/null; then
|
||
if git worktree remove --force "$path" 2>/dev/null; then
|
||
echo " removed: $short"
|
||
REMOVED=$((REMOVED + 1))
|
||
else
|
||
echo " failed: $short ($path)"
|
||
fi
|
||
else
|
||
KEPT=$((KEPT + 1))
|
||
fi
|
||
done
|
||
|
||
git worktree prune
|
||
|
||
AFTER=$(git worktree list | wc -l)
|
||
SIZE_AFTER=$(du -sh .claude/worktrees/ 2>/dev/null | awk '{print $1}')
|
||
|
||
echo ""
|
||
echo "Before: $((BEFORE - 1)) worktrees, $SIZE_BEFORE"
|
||
echo "After: $((AFTER - 1)) worktrees, $SIZE_AFTER"
|