-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
feat(worktree): add lifecycle management with automatic garbage collection #668
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
010a5c6
ad71809
ba3802e
6c3affb
ba4cafa
868fb62
058ee97
9647959
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,179 @@ | ||||||||||||||||||||||
| # Worktree Lifecycle Management | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Superpowers automatically manages the lifecycle of git worktrees, ensuring they're cleaned up when no longer needed. | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## How It Works | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 1. Registration | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| When `using-git-worktrees` creates a worktree, it registers it in `~/.config/superpowers/worktree-registry.json`: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ```json | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| "id": "wt_1234567890_feature_auth", | ||||||||||||||||||||||
| "path": "/tmp/worktrees/feature-auth", | ||||||||||||||||||||||
| "branch": "feature/auth-system", | ||||||||||||||||||||||
| "project_root": "/Users/jason/myapp", | ||||||||||||||||||||||
| "created_at": "2026-03-10T10:00:00Z", | ||||||||||||||||||||||
| "status": "active" | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 2. Status Tracking | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Worktrees progress through these states: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - **active** - Currently in development | ||||||||||||||||||||||
| - **pr_opened** - Pull request has been opened | ||||||||||||||||||||||
| - **merged** - Branch has been merged to main | ||||||||||||||||||||||
| - **abandoned** - Branch was deleted without merging | ||||||||||||||||||||||
| - **cleanup_pending** - Scheduled for garbage collection | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 3. Automatic Detection | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| The garbage collection daemon (or manual detection) checks: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - Does the branch still exist? | ||||||||||||||||||||||
| - Is there an open PR for this branch? | ||||||||||||||||||||||
| - Has the PR been merged? | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### 4. Safe Cleanup | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Cleanup only happens when: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 1. Status is `cleanup_pending` | ||||||||||||||||||||||
| 2. Worktree has no uncommitted changes | ||||||||||||||||||||||
| 3. Delay period has passed (default: 1 hour for merged, immediate for abandoned) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## Installation | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### Enable GC Daemon (Recommended) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||
| # macOS: Create a proper LaunchAgent plist | ||||||||||||||||||||||
| cat > ~/Library/LaunchAgents/com.superpowers.worktree-gc.plist << 'EOF' | ||||||||||||||||||||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||||||||||||||||||||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||||||||||||||||||||
| <plist version="1.0"> | ||||||||||||||||||||||
| <dict> | ||||||||||||||||||||||
| <key>Label</key> | ||||||||||||||||||||||
| <string>com.superpowers.worktree-gc</string> | ||||||||||||||||||||||
| <key>ProgramArguments</key> | ||||||||||||||||||||||
| <array> | ||||||||||||||||||||||
| <string>/bin/bash</string> | ||||||||||||||||||||||
| <string>-c</string> | ||||||||||||||||||||||
| <string>$HOME/.config/superpowers/lib/worktree-gc-daemon</string> | ||||||||||||||||||||||
| </array> | ||||||||||||||||||||||
|
Comment on lines
+62
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Property list files are XML and do not perform shell variable expansion. The literal string Consider using the full expanded path or a more reliable approach: 📝 Suggested fix using full path <key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
- <string>$HOME/.config/superpowers/lib/worktree-gc-daemon</string>
+ <string>"$HOME"/.config/superpowers/lib/worktree-gc-daemon</string>
</array>Alternatively, instruct users to replace 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| <key>RunAtLoad</key> | ||||||||||||||||||||||
| <true/> | ||||||||||||||||||||||
| <key>KeepAlive</key> | ||||||||||||||||||||||
| <false/> | ||||||||||||||||||||||
| </dict> | ||||||||||||||||||||||
| </plist> | ||||||||||||||||||||||
| EOF | ||||||||||||||||||||||
| launchctl load ~/Library/LaunchAgents/com.superpowers.worktree-gc.plist | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Linux: Append to existing crontab (preserves existing entries) | ||||||||||||||||||||||
| (crontab -l 2>/dev/null; echo "@reboot $HOME/.config/superpowers/lib/worktree-gc-daemon") | crontab - | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### Log Rotation (Optional) | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| To prevent log file growth, add this to `/etc/logrotate.d/superpowers-worktree-gc`: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
| $HOME/.config/superpowers/worktree-gc.log { | ||||||||||||||||||||||
| weekly | ||||||||||||||||||||||
| rotate 4 | ||||||||||||||||||||||
| compress | ||||||||||||||||||||||
| missingok | ||||||||||||||||||||||
| notifempty | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+84
to
+92
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Logrotate config has issues: missing language specifier and unexpanded
📝 Suggested fix-```
-$HOME/.config/superpowers/worktree-gc.log {
+```text
+# Replace /home/username with your actual home directory
+/home/username/.config/superpowers/worktree-gc.log {
weekly
rotate 4
compress
missingok
notifempty
}
```🧰 Tools🪛 markdownlint-cli2 (0.21.0)[warning] 84-84: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### Install Git Hooks | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| For automatic cleanup after merge: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||
| # In your repository | ||||||||||||||||||||||
| cp ~/.config/superpowers/lib/hooks/post-merge .git/hooks/ | ||||||||||||||||||||||
| chmod +x .git/hooks/post-merge | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## Manual Commands | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||
| # List worktrees for current project | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager list | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Check for status changes | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager detect | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Run garbage collection manually | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager gc | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Force cleanup of specific worktree | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager unregister <id> | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## Configuration | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Edit `~/.config/superpowers/worktree-registry.json`: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ```json | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| "metadata": { | ||||||||||||||||||||||
| "gc_policy": { | ||||||||||||||||||||||
| "enabled": true, | ||||||||||||||||||||||
| "interval_hours": 1, | ||||||||||||||||||||||
| "cleanup_delay_hours": 24, | ||||||||||||||||||||||
| "max_age_days": 30 | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| - **enabled**: Turn GC on/off | ||||||||||||||||||||||
| - **interval_hours**: How often to check for cleanup | ||||||||||||||||||||||
| - **cleanup_delay_hours**: Grace period after merge | ||||||||||||||||||||||
| - **max_age_days**: Auto-cleanup worktrees older than this | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## Safety Guarantees | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 1. **Never deletes worktrees with uncommitted changes** | ||||||||||||||||||||||
| 2. **Never deletes active worktrees** | ||||||||||||||||||||||
| 3. **Always provides grace period for merged branches** | ||||||||||||||||||||||
| 4. **Logs all cleanup actions** to `~/.config/superpowers/worktree-gc.log` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## Integration with Finishing Branch | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| When you use the `finishing-a-development-branch` skill: | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| 1. If merging locally, post-merge hook triggers cleanup | ||||||||||||||||||||||
| 2. If creating PR, worktree status updates to `pr_opened` | ||||||||||||||||||||||
| 3. When PR is merged, GitHub webhook (future) or GC daemon detects and schedules cleanup | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ## Troubleshooting | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### Worktree not cleaned up | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||
| # Check status | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager find <branch> | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Manually mark for cleanup | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager update <id> cleanup_pending | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| # Run GC | ||||||||||||||||||||||
| ~/.config/superpowers/lib/worktree-manager gc | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ### Accidentally cleaned up | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Check logs: | ||||||||||||||||||||||
| ```bash | ||||||||||||||||||||||
| cat ~/.config/superpowers/worktree-gc.log | ||||||||||||||||||||||
| ``` | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| The registry maintains history of all worktrees created. | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,45 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Git post-merge hook for automatic worktree cleanup | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Install: Copy to .git/hooks/post-merge and make executable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SUPERPOWERS_LIB="${HOME}/.config/superpowers/lib" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WORKTREE_MANAGER="${SUPERPOWERS_LIB}/worktree-manager" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Only run if superpowers is installed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ ! -x "$WORKTREE_MANAGER" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Get the branch that was merged (from reflog) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Post-merge hook fires after merge, so we parse the reflog to find source branch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MERGED_BRANCH=$(git reflog -1 --format='%gs' | sed -n 's/.*merge \([^:]*\).*/\1/p') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Fallback: if we can't determine merged branch, exit silently | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "$MERGED_BRANCH" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Find matching worktrees | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +# Get first matching worktree (there could be multiple across projects) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null | jq -s '.[0]' || true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +if [ -n "$WORKTREE_INFO" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Find matching worktrees | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null | jq -s '.[0]' || true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +if [ -n "$WORKTREE_INFO" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove the inverted early-exit block.
Suggested fix-# Find matching worktrees
-# Get first matching worktree (there could be multiple across projects)
-WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null | jq -s '.[0]' || true)
-
-if [ -n "$WORKTREE_INFO" ]; then
- exit 0
-fi
-
-# Find matching worktrees
-WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null | jq -s '.[0]' || true)
-
-if [ -n "$WORKTREE_INFO" ]; then
+# Find matching worktrees
+WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null | jq -s '.[0]' || true)
+
+if [ -n "$WORKTREE_INFO" ] && [ "$WORKTREE_INFO" != "null" ]; then
WORKTREE_ID=$(echo "$WORKTREE_INFO" | jq -r '.id')
WORKTREE_PATH=$(echo "$WORKTREE_INFO" | jq -r '.path')🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WORKTREE_ID=$(echo "$WORKTREE_INFO" | jq -r '.id') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| WORKTREE_PATH=$(echo "$WORKTREE_INFO" | jq -r '.path') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "🎉 Branch '$MERGED_BRANCH' merged!" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Update status to merged (daemon will handle cleanup) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$WORKTREE_MANAGER" update "$WORKTREE_ID" "merged" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "✅ Worktree marked as merged. GC daemon will clean up: $WORKTREE_PATH" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential issue with multiple worktrees for the same branch. If multiple worktrees are registered for the same branch (e.g., from different projects), 🛡️ Proposed fix to handle first match only-WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null || true)
+# Get first matching worktree (there could be multiple across projects)
+WORKTREE_INFO=$("$WORKTREE_MANAGER" find "$MERGED_BRANCH" 2>/dev/null | jq -s '.[0]' || true)
if [ -n "$WORKTREE_INFO" ]; then
+ if [ "$WORKTREE_INFO" = "null" ]; then
+ exit 0
+ fi
WORKTREE_ID=$(echo "$WORKTREE_INFO" | jq -r '.id')Alternatively, modify 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| #!/usr/bin/env bash | ||
| # Worktree Garbage Collection Daemon | ||
| # Runs periodically to clean up abandoned worktrees | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| SUPERPOWERS_LIB="${HOME}/.config/superpowers/lib" | ||
| WORKTREE_MANAGER="${SUPERPOWERS_LIB}/worktree-manager" | ||
| DAEMON_PID_FILE="/tmp/superpowers-worktree-gc.pid" | ||
| DAEMON_LOCK_FILE="/tmp/superpowers-worktree-gc.lock" | ||
| LOG_FILE="${HOME}/.config/superpowers/worktree-gc.log" | ||
|
|
||
| # Ensure log directory exists | ||
| mkdir -p "$(dirname "$LOG_FILE")" | ||
|
|
||
| # Handle shutdown signals | ||
| RUNNING=1 | ||
| shutdown() { | ||
| log "Daemon shutting down" | ||
| RUNNING=0 | ||
| } | ||
| trap 'shutdown' SIGTERM SIGINT | ||
|
|
||
| # Atomic lock acquisition using flock | ||
| exec 200>"$DAEMON_LOCK_FILE" | ||
| if ! flock -n 200; then | ||
| echo "Daemon already running (lock held)" >&2 | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Cleanup on exit | ||
| trap 'flock -u 200; rm -f "$DAEMON_PID_FILE"' EXIT | ||
|
|
||
| # Write PID while holding lock | ||
| echo $$ > "$DAEMON_PID_FILE" | ||
|
|
||
| log() { | ||
| echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE" | ||
| } | ||
|
|
||
| log "Worktree GC daemon started (PID: $$)" | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Main loop | ||
| while [ "$RUNNING" = "1" ]; do | ||
| # Detect status changes | ||
| if [ -x "$WORKTREE_MANAGER" ]; then | ||
| "$WORKTREE_MANAGER" detect >> "$LOG_FILE" 2>&1 || true | ||
|
|
||
| # Run garbage collection | ||
| "$WORKTREE_MANAGER" gc >> "$LOG_FILE" 2>&1 || true | ||
| fi | ||
|
|
||
| # Sleep for 1 hour (in short intervals to allow graceful shutdown) | ||
| for i in $(seq 1 360); do | ||
| if [ "$RUNNING" = "0" ]; then | ||
| break | ||
| fi | ||
| sleep 10 | ||
| done | ||
| done | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation inconsistency: default cleanup delay.
Line 46 states "default: 1 hour for merged", but the configuration example on line 130 shows
cleanup_delay_hours: 24. Please reconcile which is the actual default.🤖 Prompt for AI Agents