From 4d8236e26ca9041263cd5d6fc37cb80ee709f914 Mon Sep 17 00:00:00 2001 From: rictus Date: Fri, 16 Jan 2026 15:50:18 -0800 Subject: [PATCH] fix(polecat): clean up orphan .beads/ directories on gt done (gt-1l3my9) When a polecat runs gt done, the worktree is removed but the parent polecat directory could be left behind containing only .beads/. This caused gt polecat list to show ghost entries since exists() checks if the polecatDir exists. The fix adds explicit cleanup of .beads/ directories: 1. After git worktree remove succeeds, clean up any leftover .beads/ in the clonePath that was not fully removed 2. For new structure polecats, also clean up any .beads/ at the polecatDir level before trying to remove the parent directory Co-Authored-By: Claude Opus 4.5 --- internal/polecat/manager.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/polecat/manager.go b/internal/polecat/manager.go index a761845e..421fad60 100644 --- a/internal/polecat/manager.go +++ b/internal/polecat/manager.go @@ -443,11 +443,22 @@ func (m *Manager) RemoveWithOptions(name string, force, nuclear bool) error { if removeErr := os.RemoveAll(clonePath); removeErr != nil { return fmt.Errorf("removing clone path: %w", removeErr) } + } else { + // GT-1L3MY9: git worktree remove may leave untracked directories behind. + // Clean up any leftover .beads/ directory that wasn't fully removed. + cloneBeadsDir := filepath.Join(clonePath, ".beads") + _ = os.RemoveAll(cloneBeadsDir) + // Remove the now-empty clonePath if it still exists + _ = os.Remove(clonePath) } // Also remove the parent polecat directory if it's now empty // (for new structure: polecats// contains only polecats///) if polecatDir != clonePath { + // GT-1L3MY9: Clean up any orphaned .beads/ directory at polecat level. + // This can happen if the worktree cleanup was incomplete or from old state. + polecatBeadsDir := filepath.Join(polecatDir, ".beads") + _ = os.RemoveAll(polecatBeadsDir) _ = os.Remove(polecatDir) // Non-fatal: only removes if empty }