Two unrelated defects, both the "existed and was never reached" shape.
GitLab and Bitbucket pipelines had no review job
ciTemplateFor has taken a { review } option since those templates were written:
export function ciTemplateFor(provider: string, options: { review?: boolean } = {})Its only call site:
const template = ciTemplateFor(provider)So a repository on either platform set up by buddy setup got a pipeline that scheduled updates and never reviewed a merge request — while the GitHub workflow has carried the review job from the start. Passed now. The command honours ai.review at run time and works without a key, so it's as safe there as on GitHub.
Cleanup reported deletions that didn't happen
GitHub's deleteBranch:
this.logger.warn(`⚠️ Failed to delete remote branch ${branchName}: …`)
// Don't throw - branch deletion failures are not criticalcleanupStaleBranches has a per-branch catch that fills its failed bucket. It could never reach it. Every branch was reported deleted whether the push succeeded or not, and buddy update-check printed "N branches deleted, 0 failed" over a remote that still had them.
GitLab and Bitbucket already throw here. GitHub now does too, with one exception: a branch that's already gone is the outcome the caller wanted, so that failure is a success — failing cleanup over it would leave the same branch "failing" on every run.
Three of the four callers already wrapped the call. The fourth — auto-closing a superseded PR — is now guarded the same way: the PR is closed either way, and a branch that won't delete is a warning, not a failed run.
Tests
2160 → 2166.
Lint ✓ · typecheck ✓ · check:docs ✓ · 0 fail
🤖 Generated with Claude Code