From 59fd17251ae94abfa426e194cef3b1b916a0f7c1 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 4 May 2026 23:22:20 -0400 Subject: [PATCH 1/3] fix(phase): clarify insert preconditions and reject unsupported dry-run flag --- .../bin/lib/phase-command-router.cjs | 3 +++ get-shit-done/bin/lib/phase.cjs | 4 ++++ tests/phase.test.cjs | 22 +++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/get-shit-done/bin/lib/phase-command-router.cjs b/get-shit-done/bin/lib/phase-command-router.cjs index e4f4a6653..979088ef4 100644 --- a/get-shit-done/bin/lib/phase-command-router.cjs +++ b/get-shit-done/bin/lib/phase-command-router.cjs @@ -33,6 +33,9 @@ function routePhaseCommand({ phase, args, cwd, raw, error }) { } phase.cmdPhaseAddBatch(cwd, descriptions, raw); } else if (subcommand === 'insert') { + if (args.includes('--dry-run')) { + error('phase insert does not support --dry-run'); + } phase.cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw); } else if (subcommand === 'remove') { const forceFlag = args.includes('--force'); diff --git a/get-shit-done/bin/lib/phase.cjs b/get-shit-done/bin/lib/phase.cjs index 9c078e0aa..b1acadfcc 100644 --- a/get-shit-done/bin/lib/phase.cjs +++ b/get-shit-done/bin/lib/phase.cjs @@ -556,6 +556,10 @@ function cmdPhaseInsert(cwd, afterPhase, description, raw) { const afterPhaseEscaped = unpadded.replace(/\./g, '\\.'); const targetPattern = new RegExp(`#{2,4}\\s*Phase\\s+0*${afterPhaseEscaped}:`, 'i'); if (!targetPattern.test(content)) { + const checklistPattern = new RegExp(`-\\s*\\[[ x]\\]\\s*\\*\\*Phase\\s+0*${afterPhaseEscaped}:`, 'i'); + if (checklistPattern.test(content)) { + error(`Phase ${afterPhase} exists in roadmap summary but is missing a detail section (### Phase ${afterPhase}: ...).`); + } error(`Phase ${afterPhase} not found in ROADMAP.md`); } diff --git a/tests/phase.test.cjs b/tests/phase.test.cjs index 68779c1af..0af6ab12c 100644 --- a/tests/phase.test.cjs +++ b/tests/phase.test.cjs @@ -1237,6 +1237,28 @@ describe('phase insert command', () => { assert.ok(roadmap.includes('**Requirements**: TBD'), 'inserted phase entry should include Requirements TBD'); }); + test('reports actionable error for summary-only placeholder phase without detail section (#3098)', () => { + fs.writeFileSync( + path.join(tmpDir, '.planning', 'ROADMAP.md'), + `# Roadmap\n\n- [ ] **Phase 5: Placeholder**\n` + ); + + const result = runGsdTools('phase insert 5 Hotfix', tmpDir); + assert.ok(!result.success, 'should fail when phase is summary-only placeholder'); + assert.ok(result.error.includes('missing a detail section')); + }); + + test('phase insert rejects unsupported --dry-run flag explicitly (#3098)', () => { + fs.writeFileSync( + path.join(tmpDir, '.planning', 'ROADMAP.md'), + `# Roadmap\n\n### Phase 1: Foundation\n**Goal:** Setup\n` + ); + + const result = runGsdTools('phase insert 1 Hotfix --dry-run', tmpDir); + assert.ok(!result.success, 'phase insert should reject unsupported --dry-run'); + assert.ok(result.error.includes('does not support --dry-run')); + }); + test('handles #### heading depth from multi-milestone roadmaps', () => { fs.writeFileSync( path.join(tmpDir, '.planning', 'ROADMAP.md'), From 313f170cf0da393c717c102b5986458d863d8a88 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 4 May 2026 23:32:04 -0400 Subject: [PATCH 2/3] chore(changeset): add release fragment for PR #3125 --- .changeset/pr-3125-release-note.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pr-3125-release-note.md diff --git a/.changeset/pr-3125-release-note.md b/.changeset/pr-3125-release-note.md new file mode 100644 index 000000000..650382d2e --- /dev/null +++ b/.changeset/pr-3125-release-note.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 3125 +--- +Fixes for issue #3125 were applied to keep command/workflow behavior and SDK parity aligned with current documented usage. From 9987792c465a4a108a194a6a0e13d51157089b6d Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Mon, 4 May 2026 23:49:00 -0400 Subject: [PATCH 3/3] chore(changeset): correct issue reference for PR #3125 fragment --- .changeset/pr-3125-release-note.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pr-3125-release-note.md b/.changeset/pr-3125-release-note.md index 650382d2e..3c2cbf937 100644 --- a/.changeset/pr-3125-release-note.md +++ b/.changeset/pr-3125-release-note.md @@ -2,4 +2,4 @@ type: Fixed pr: 3125 --- -Fixes for issue #3125 were applied to keep command/workflow behavior and SDK parity aligned with current documented usage. +Fixes for issue #3098 were applied to keep command/workflow behavior and SDK parity aligned with current documented usage.