Release 2.1.21 (2026-06-09)¶
Features¶
- add vrg-worktree-status and make the finalize sweep squash-merge-aware (#1553)
- docs(specs): add vrg-worktree-status design (#1552)
Read-only command listing canonical worktrees with derived lifecycle state so removable cruft is distinguishable from in-flight work. Approved brainstorm design; classification is a pure lib function, cleanup stays with vrg-finalize-pr.
- docs(specs): fold squash-merge-aware finalize sweep into design (#1552)
Adds the vrg-finalize-pr straggler-sweep fix as a coupled deliverable: widen the candidate set to include canonical worktree branches, keep the existing guards, and share classify_worktree so the status cruft verdict and the finalize removal set match by construction.
- docs(plans): add worktree-hygiene implementation plan (#1552)
Task-by-task TDD plan: commits_ahead helper, classify_worktree + gather_worktree_status, vrg-worktree-status command, and the squash-merge-aware finalize sweep sharing one classifier.
- feat(git): add commits_ahead helper (#1552)
Counts commits on a branch not reachable from a base via rev-list --count; used by worktree classification.
- feat(worktrees): add classify_worktree + gather_worktree_status (#1552)
Pure classifier maps PR state plus local signals to a WorktreeState (removable = merged/closed minus a dirty overlay); failed lookups surface as UNKNOWN, never a silent NO_PR. gather_worktree_status is the I/O wrapper shared by vrg-worktree-status and the finalize sweep.
- feat(worktree-status): add vrg-worktree-status command (#1552)
Read-only command listing canonical worktrees with their lifecycle state; cruft groups at the bottom and a summary counts active/stalled/cruft. UNKNOWN lookups print their reason. Cleanup stays vrg-finalize-pr's job.
- fix(finalize-pr): sweep squash-merged worktrees via classify_worktree (#1552)
The straggler sweep relied on git branch --merged, which is blind to squash-merged branches and orphaned their worktrees. Add a worktree arm that classifies every canonical worktree with gather_worktree_status and removes the removable ones; the ancestry arm still handles worktree-less branches. Inference tests updated since list_worktrees is now also a cleanup-path call.
- test(worktrees): satisfy lint/typecheck/coverage gates (#1552)
Use StrEnum for WorktreeState (ruff UP042); give the classify test helper explicit typed kwargs (ty); move the pytest import under TYPE_CHECKING (ruff TC002); add no-PR gather and worktree-arm delete-decline/eternal-branch tests for full branch coverage.
- docs(reference): document vrg-worktree-status in CLI reference (#1552)
Add the vrg-worktree-status entry to the CLI tools overview, alongside vrg-finalize-pr, describing its read-only worktree lifecycle classification.