diff --git a/get-shit-done/bin/lib/milestone.cjs b/get-shit-done/bin/lib/milestone.cjs index 63c5e15fb..af473e59e 100644 --- a/get-shit-done/bin/lib/milestone.cjs +++ b/get-shit-done/bin/lib/milestone.cjs @@ -134,9 +134,16 @@ function cmdMilestoneComplete(cwd, version, options, raw) { if (fm['one-liner']) { accomplishments.push(fm['one-liner']); } - // Count tasks - const taskMatches = content.match(/##\s*Task\s*\d+/gi) || []; - totalTasks += taskMatches.length; + // Count tasks: prefer **Tasks:** N from Performance section, + // then ]/gi) || []; + const mdTaskMatches = content.match(/##\s*Task\s*\d+/gi) || []; + totalTasks += xmlTaskMatches.length || mdTaskMatches.length; + } } catch { /* intentionally empty */ } } } diff --git a/tests/milestone.test.cjs b/tests/milestone.test.cjs index fc00a37cd..7dcaee60d 100644 --- a/tests/milestone.test.cjs +++ b/tests/milestone.test.cjs @@ -424,6 +424,30 @@ describe('milestone complete command', () => { assert.strictEqual(output.phases, 2, 'should count only phases 456 and 457'); }); + test('counts tasks from **Tasks:** N in summary body', () => { + fs.writeFileSync( + path.join(tmpDir, '.planning', 'ROADMAP.md'), + `# Roadmap v1.0\n\n### Phase 1: Foundation\n**Goal:** Setup\n` + ); + fs.writeFileSync( + path.join(tmpDir, '.planning', 'STATE.md'), + `# State\n\n**Status:** In progress\n**Last Activity:** 2025-01-01\n**Last Activity Description:** Working\n` + ); + + const p1 = path.join(tmpDir, '.planning', 'phases', '01-foundation'); + fs.mkdirSync(p1, { recursive: true }); + fs.writeFileSync( + path.join(p1, '01-01-SUMMARY.md'), + `---\none-liner: Built the foundation\n---\n\n# Phase 1: Foundation Summary\n\n**Built the foundation**\n\n## Performance\n\n- **Duration:** 28 min\n- **Tasks:** 7\n- **Files modified:** 12\n` + ); + + const result = runGsdTools('milestone complete v1.0 --name MVP', tmpDir); + assert.ok(result.success, `Command failed: ${result.error}`); + + const output = JSON.parse(result.output); + assert.strictEqual(output.tasks, 7, 'should count tasks from **Tasks:** N field'); + }); + test('handles empty phases directory', () => { fs.writeFileSync( path.join(tmpDir, '.planning', 'ROADMAP.md'),