Conversation
`askConfirmation` returns false when stdin is not a TTY, and `teamai remove` had no flag to skip it, so every scripted run printed "Cancelled" and exited 0. The command could not be used from a script, and it had no end-to-end test, which is how both defects in Tencent#576 survived. `--force` is spelled and described the same way as `teamai uninstall --force`, and the prompt keeps the same guard shape so the two stay refactorable together. The command's action was also dropping its `cmdOpts` argument, so the option is wired through the way `uninstall` does it. The new end-to-end test drives the built CLI against a bare repository and asserts the whole contract. The deployed copy goes immediately, and the deletion plus its tombstone are published as a branch for review. `checkoutMaster` returns the clone to the default branch, so the clone's own working tree keeps the file until that branch merges. Fixes Tencent#591
SaulMoro
force-pushed
the
feat/remove-force-flag-591
branch
from
September 16, 2026 11:19
04b5932 to
6b3fb50
Compare
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
askConfirmationreturnsfalsewhen stdin is not a TTY, andteamai removehad no flag to skip it. Every scripted run printedCancelledand exited 0, which reads like success. The command could not be used from a script, and it had no end-to-end test at all. That is how both defects in #576 survived.--forceis spelled and described the same way asteamai uninstall --force, and the prompt keeps that command's guard shape so the two stay refactorable together. The command's action was also dropping itscmdOptsargument, so the option is wired through the wayuninstalldoes it:.command('remove <type> <names...>') +.option('--force', 'Skip confirmation prompt') -.action(async (type, names) => { +.action(async (type, names, cmdOpts) => { const globalOpts = program.opts() as GlobalOptions; - await remove(type, names, globalOpts); + await remove(type, names, { ...globalOpts, ...cmdOpts }); });Type of Change
Test Plan
npx tsc --noEmitpassesnpx vitest runpasses (233 files, 3265 tests)New end-to-end file,
src/__tests__/e2e/remove-force.test.ts, driving the built CLI against a bare repository:The first test went red before the change on
error: unknown option '--force'. The second is what makes the first meaningful. A non-interactive run without the flag still cancels and deletes nothing, so the deletions in test 1 can only come from--force.The fixture gives the clone a real
origin, so the run reachespushRepoBranchinstead of stopping at the local delete, and the test asserts the whole contract rather than a snapshot of the clone:0.claude/rules/doomed.mdgone,keeper.mduntouchedteamai/push/, and on itrules/doomed.mdis absent andrules/.removedcontainsdoomedcheckoutMasterreturns the clone to the default branch after the push, so the clone's own working tree keeps the file until the branch merges. That is what "Remove a resource and open MR" means, and asserting otherwise would pin the wrong contract.Each test builds its own sandbox. The e2e config retries once, and test 1 mutates the team repo, so a shared fixture would have the retry run against a used repository.
Related Issues
Fixes #591
Notes for Reviewers
What this unlocks beyond the flag itself.
teamai removehad no end-to-end coverage, because no test could drive it. Both defects in #576 lived on this path and neither had a test at the command level. This PR adds the first one.GlobalOptions.forcecarries two meanings, and this PR adds the second usage rather than the second meaning.pull --forceignores the unchanged-rev fast path;remove --forceskips the prompt, asuninstall --forcealready does. The field's comment now says both.uninstallandinitdeclare their ownforceon their own option types, so the comment describes only the two commands that read it fromGlobalOptions.Exit codes are unchanged and still uniform. Cancel, a failed push, an unsupported type, and "no matching resources" all exit 0. A script can now remove a resource but still cannot tell success from cancel. Changing that is a behaviour change beyond adding a flag, so it wants its own issue rather than a quiet ride here.