feat: support removing multiple worktrees at once#19
Merged
Conversation
Add multi-select to both interactive and non-interactive modes: - CLI argument changes from [target] to variadic [target...] - Interactive mode uses checkbox (multi-select) instead of single select - Batch path resolves all targets upfront, checks uncommitted changes once, confirms in a single prompt, then removes in parallel (p-limit) - Single target still uses the existing removeWorktree flow
…ccounting
performWorktreeRemoval has failure paths that return without throwing,
causing Promise.allSettled to count them as fulfilled. The batch summary
would over-report success (e.g. "Removed 2 of 2" when one failed).
Return { ok: boolean } so removeBatch can accurately track outcomes.
Route all targets through removeBatch, eliminating the duplicated resolution/preflight logic in removeWorktree. The batch path now handles n=1 with appropriate singular grammar and compact confirmation prompts. Delete remove-worktree.ts entirely. Extract cwd-switch detection and handling into handle-cwd-switch.ts to keep remove-batch.ts within complexity thresholds.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
- Return ok:false from performWorktreeRemoval when git unregister fails - Force-skip internal prompts in multi-target batch (prevents concurrent readline races since user already confirmed in Phase 2) - Use "Would remove" instead of "Removed" in dry-run summary - Log explicit failure line for fulfilled-but-not-ok results - Deduplicate targets by normalized path before processing
- prepareCwdSwitch now finds the actual target containing cwd instead of always using the first target's name - performWorktreeRemoval returns ok:false when git unregister fails - Multi-target batch passes force:true to skip internal prompts - Dry-run summary uses "Would remove" wording - Batch summary logs explicit failure for fulfilled-but-not-ok results
Add `skipTrashFailurePrompt` to `performWorktreeRemoval` so batch mode can prevent concurrent readline races without also enabling destructive fallback when trash fails. Multi-target batches now report trash failures as errors instead of silently proceeding with `git worktree remove --force`. Also error when all batch targets resolve to empty instead of silently returning success (regression from the single-target path).
Single-target failures now exit with code 1, matching multi-target behavior. Previously, single-target mode skipped Phase 4 entirely, causing performWorktreeRemoval failures to silently exit 0.
Use a discriminated union (status: "ok" | "failed" | "cancelled") for PerformWorktreeRemovalResult instead of a boolean. Single-target user cancellation (declining the trash-failure prompt) now exits cleanly with code 0 instead of being misreported as a failure with code 1.
Add comment explaining why resolution exits immediately on invalid targets — it runs before confirmation or removal, so no worktrees are modified yet.
Wrap the OutputWriter with target-name prefixes (e.g., [foo] Moving directory to trash...) for multi-target batches so interleaved parallel output is attributable. Single-target mode is unchanged. Extract prefixOutput into output-writer.ts and batch result reporting into report-batch-results.ts to keep remove-batch.ts under the FTA complexity threshold.
|
🎉 This PR is included in version 1.4.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
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.
Summary
[target]to variadic[target...], allowingworktree-remove feat/a feat/b feat/c-i) now uses a multi-select checkbox instead of single-selectremoveBatch, eliminating the duplicated resolution/preflight logic that previously existed inremoveWorktreep-limit, concurrency 4)performWorktreeRemovalreturns a discriminated union (status: "ok" | "failed" | "cancelled") so batch accounting accurately tracks failures and user cancellations exit cleanlyTest plan
pnpm exec vitest run— all 53 tests passpnpm exec tsc -b --noEmit— type-check passespnpm exec eslint src/— no lint errorspnpm run fta— all files under complexity thresholdnode --experimental-strip-types src/cli.ts -i— shows checkbox multi-selectnode --experimental-strip-types src/cli.ts branch1 branch2— removes bothnode --experimental-strip-types src/cli.ts --dry-run -i— shows what would be removed for multiple selections