Smarter cbox cleanup: detect squash-merged PRs, ignore sandbox artifacts, scan all worktrees
Problem
The cbox cleanup command fails to reclaim most stale worktrees for three reasons: it cannot detect squash-merged PRs (only fast-forward merges), it treats .claude-sessions-sandbox/ and .claude/ directories as meaningful dirty state preventing cleanup, and it only scans cbox tmux sessions while ignoring worktrees created by Cursor or Codex. Over time, this leads to significant worktree sprawl — dozens of orphaned branches and worktrees consuming disk space and cluttering git worktree list output. During the pilot, worktree sprawl became a real developer friction point that required manual cleanup.
Context
- Squash-merged PRs detected via
gh pr list --head <branch> --state merged. .claude-sessions-sandbox/and.claude/ignored when computing dirty state.- Branches with 0 commits ahead of main classified as safe-to-clean.
--worktreesflag scans all git worktrees, not just cbox sessions.- Local branch deleted after worktree removal.
Possible Solutions
Plan
- Update
_get_session_git_info()to check GitHub PR merge status. - Filter
.claude-sessions-sandbox/and.claude/from dirty check. - Add commits-ahead check (
git rev-list --count origin/main..HEAD). - Add
--worktreesflag to scangit worktree listin addition to cbox sessions. - Delete local branch after worktree removal in cleanup execution.
- Add tests for the new classification logic.
Implementation Progress
- Directly reduces developer friction during pilot — worktree sprawl is a real pain point.
- No spillover expected; self-contained in cbox CLI.
Completion notes
Implemented in libs/cbox/cbox/cli.py. Key changes:
- _get_session_git_info() now returns commits_ahead and squash_merged fields; uses three-tier merge detection (ancestor → commits-ahead → GH PR).
- _IGNORED_DIRTY_PREFIXES tuple filters .claude-sessions-sandbox/, .claude/, .claude-sessions- from porcelain dirty check.
- _remove_worktree() accepts branch= kwarg and runs git worktree prune before branch delete.
- _list_git_worktrees() helper parses git worktree list --porcelain.
- cleanup() accepts --worktrees flag, scans non-cbox worktrees, passes explicit branch name to _remove_worktree().
- 7 new test cases in libs/cbox/test_cleanup.py covering all features.
- GitHub issue: #412
- Affected code:
libs/cbox/cbox/cli.py—_get_session_git_info(),cleanup()
Review Feedback
- [ ] Review cleared