Follow-up to #1919 (archive-then-remove core). Closes the remaining #1871 acceptance criteria so phase history is preserved across the full milestone lifecycle, not just at phases.clear: - #2 src/milestone.cts + src/phases-command-router.cts: extract shared archivePhaseDirectories() helper; add cmdPhasesArchive (the previously half-wired phases.archive alias now routes instead of erroring Unknown). - #4 gsd-tools.cjs + src/milestone.cts: milestone complete archives phase dirs by default (--no-archive-phases opts out; --archive-phases is now a harmless no-op). complete-milestone.md updated to drop the redundant manual Yes/Skip archive prompt. - #3 gsd-core/workflows/new-milestone.md: §6 stages the archive move + source removal (git add .planning/milestones/ .planning/phases/) in the same commit as the milestone start, so the archive lands atomically — no orphaned uncommitted deletions, no un-archived dirs inherited. - docs/CLI-TOOLS.md (+ ja/zh/ko/pt) + help/modes/full.md: flag accuracy. - tests: phases archive command (#2) + milestone complete default archive / --no-archive-phases opt-out (#4). Goldens + workflow size baseline refreshed. Closes #1871
This commit is contained in:
@@ -759,3 +759,43 @@ describe('#1911 — milestone complete --ws archives to the workstream', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// #1871: milestone complete archives phase dirs by default
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('#1871 — milestone complete archives phase dirs by default', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => { tmpDir = createTempProject(); });
|
||||
afterEach(() => cleanup(tmpDir));
|
||||
|
||||
function seedCompletableMilestone() {
|
||||
writeRoadmap(tmpDir, '# Roadmap v1.0 MVP\n\n### Phase 1: Foundation\n**Goal:** Setup\n');
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'REQUIREMENTS.md'), '# Requirements\n- [ ] x\n');
|
||||
writeState(tmpDir);
|
||||
mkPhaseDir(tmpDir, '01-foundation', { oneLiner: 'Set up project infrastructure' });
|
||||
}
|
||||
|
||||
test('archives phase dirs by default (no --archive-phases flag needed)', () => {
|
||||
seedCompletableMilestone();
|
||||
const result = runGsdTools('milestone complete v1.0 --name MVP', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
const out = JSON.parse(result.output);
|
||||
assert.ok(out.archived.phases, 'phases should be archived by default');
|
||||
assert.ok(
|
||||
fs.existsSync(path.join(tmpDir, '.planning', 'milestones', 'v1.0-phases', '01-foundation')),
|
||||
'phase dir should be archived under milestones/v1.0-phases/',
|
||||
);
|
||||
});
|
||||
|
||||
test('--no-archive-phases opts out of default archiving', () => {
|
||||
seedCompletableMilestone();
|
||||
const phaseDir = path.join(tmpDir, '.planning', 'phases', '01-foundation');
|
||||
const result = runGsdTools('milestone complete v1.0 --name MVP --no-archive-phases', tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
const out = JSON.parse(result.output);
|
||||
assert.ok(!out.archived.phases, 'phases should NOT be archived with --no-archive-phases');
|
||||
assert.ok(fs.existsSync(phaseDir), 'phase dir should remain in place with --no-archive-phases');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user