fix: accept flag-first syntax for phase remove (#3416)

* fix(phase): parse remove --force regardless of position

* chore(changeset): add fragment for phase-remove flag fix

* fix(phase): fail when phase.remove target is missing
This commit is contained in:
Tom Boucher
2026-05-11 21:13:07 -04:00
committed by GitHub
parent 5c35eceb41
commit b5676b59c0
5 changed files with 100 additions and 7 deletions

View File

@@ -972,6 +972,22 @@ describe('phaseRemove', () => {
expect(data.directory_deleted).toBeTruthy();
});
it('bug-3409: accepts --force before phase id', async () => {
const { phaseRemove } = await import('./phase-lifecycle.js');
const phasesDir = join(tmpDir, '.planning', 'phases');
await setupTestProject(tmpDir, {
roadmap: ROADMAP_FOR_REMOVE,
state: STATE_FOR_REMOVE,
phases: ['05-auth', '06-dashboard', '07-api'],
});
await writeFile(join(phasesDir, '06-dashboard', '06-01-SUMMARY.md'), 'summary', 'utf-8');
const result = await phaseRemove(['--force', '6'], tmpDir);
const data = result.data as Record<string, unknown>;
expect(data.removed).toBe('6');
expect(data.directory_deleted).toBeTruthy();
});
it('throws GSDError when ROADMAP.md is missing', async () => {
const { phaseRemove } = await import('./phase-lifecycle.js');
// Set up without ROADMAP.md
@@ -994,6 +1010,19 @@ describe('phaseRemove', () => {
await expect(phaseRemove([], tmpDir)).rejects.toThrow('phase number required');
});
it('throws GSDError when target phase does not exist and does not mutate STATE.md', async () => {
const { phaseRemove } = await import('./phase-lifecycle.js');
await setupTestProject(tmpDir, {
roadmap: ROADMAP_FOR_REMOVE,
state: STATE_FOR_REMOVE,
phases: ['05-auth', '06-dashboard', '07-api'],
});
await expect(phaseRemove(['99'], tmpDir)).rejects.toThrow('Phase 99 not found');
const stateContent = await readFile(join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
expect(stateContent).toMatch(/total_phases:\s*7/);
});
it('updates ROADMAP.md by removing phase section and renumbering', async () => {
const { phaseRemove } = await import('./phase-lifecycle.js');
await setupTestProject(tmpDir, {