Add opt-in remote-branch deletion with open-PR guard - #29
Merged
Conversation
The inline worktree-delete confirm strip now offers an opt-in "Also delete the remote branch origin/<branch>" checkbox, shown only when the branch exists on origin and unticked by default, so the remote is never touched unless asked. When the GitHub CLI (gh) reports an open pull request for the branch, the checkbox is disabled and the strip names the PR with a link to open it in the browser; the confirmed delete is guarded so origin is left alone while a PR is open, even if the flag is forced on. PR detection is a thin wrapper over `gh pr list` (GitHubCli) mirroring the existing injectable-runner seam, degrading to "no PR known" whenever gh is missing, unauthenticated, or the remote isn't GitHub. - New: GitHubCli, PullRequestInfo, UrlLauncher - WorktreeDeletion carries the open PR (RemoteDeletionBlocked); OpenerService queries gh when a remote branch exists - MainWindowViewModel + confirm-strip XAML expose the checkbox and PR link - Tests: gh parsing/degradation unit tests; E2E for tick-deletes-origin, open-PR-blocks-and-links, and option-hidden-when-not-on-origin - Docs: Features.md, CHANGELOG.md, README.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mc2djY95KPQyGwJpqHfy9m
Adversarial review of the previous commit surfaced robustness and defense-in-depth gaps around the gh PR check and the remote-delete guard: - GitHubCli parsing could throw on well-formed-but-wrong-typed gh JSON (GetInt32/GetString on unexpected value kinds), which — since gh runs on every delete-arm of a pushed branch — would abort the whole delete-arm rather than degrade to "no PR". Parsing is now lenient (TryGetInt32 + value-kind-checked string reads) with a catch-all backstop, honouring the "never throws" contract. - The gh subprocess had no timeout; a network stall would freeze the delete-confirm flow. Bounded with a 10s linked-cancellation timeout that degrades to "no PR known". - The open-PR guard lived only in the view. DeleteBranchesAsync now also checks RemoteDeletionBlocked, so the invariant holds at the point git runs regardless of caller. - The success log now leads with a warning (not a green tick) when an opted-in remote delete failed. Tests: gh parsing of unexpected field types and non-integer numbers; a service-layer test proving an open PR withholds the remote delete even with WorktreeDeletionChoice.All. Full suite: 175 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mc2djY95KPQyGwJpqHfy9m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The inline worktree-delete confirm strip now offers an opt-in
"Also delete the remote branch origin/" checkbox, shown only when the
branch exists on origin and unticked by default, so the remote is never touched
unless asked. When the GitHub CLI (gh) reports an open pull request for the
branch, the checkbox is disabled and the strip names the PR with a link to open
it in the browser; the confirmed delete is guarded so origin is left alone while
a PR is open, even if the flag is forced on.
PR detection is a thin wrapper over
gh pr list(GitHubCli) mirroring theexisting injectable-runner seam, degrading to "no PR known" whenever gh is
missing, unauthenticated, or the remote isn't GitHub.
queries gh when a remote branch exists
open-PR-blocks-and-links, and option-hidden-when-not-on-origin
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01Mc2djY95KPQyGwJpqHfy9m