Merge pull request #922 from j2h4u/fix/plan-checkboxes-progress

fix(roadmap): mark individual plan checkboxes when summaries exist
This commit is contained in:
Tom Boucher
2026-03-19 12:09:03 -04:00
committed by GitHub
2 changed files with 48 additions and 0 deletions

View File

@@ -287,6 +287,18 @@ function cmdRoadmapUpdatePlanProgress(cwd, phaseNum, raw) {
roadmapContent = replaceInCurrentMilestone(roadmapContent, checkboxPattern, `$1x$2 (completed ${today})`);
}
// Mark completed plan checkboxes (e.g. "- [ ] 50-01-PLAN.md" or "- [ ] 50-01:")
for (const summaryFile of phaseInfo.summaries) {
const planId = summaryFile.replace('-SUMMARY.md', '').replace('SUMMARY.md', '');
if (!planId) continue;
const planEscaped = escapeRegex(planId);
const planCheckboxPattern = new RegExp(
`(-\\s*\\[) (\\]\\s*${planEscaped})`,
'i'
);
roadmapContent = roadmapContent.replace(planCheckboxPattern, '$1x$2');
}
fs.writeFileSync(roadmapPath, roadmapContent, 'utf-8');
output({

View File

@@ -756,6 +756,42 @@ describe('roadmap update-plan-progress command', () => {
assert.strictEqual(output.updated, false, 'should not update');
assert.ok(output.reason.includes('ROADMAP.md not found'), 'reason should mention missing ROADMAP.md');
});
test('marks completed plan checkboxes', () => {
const roadmapContent = `# Roadmap
- [ ] Phase 50: Build
- [ ] 50-01-PLAN.md
- [ ] 50-02-PLAN.md
### Phase 50: Build
**Goal:** Build stuff
**Plans:** 2 plans
## Progress
| Phase | Plans Complete | Status | Completed |
|-------|---------------|--------|-----------|
| 50. Build | 0/2 | Planned | |
`;
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), roadmapContent);
const p50 = path.join(tmpDir, '.planning', 'phases', '50-build');
fs.mkdirSync(p50, { recursive: true });
fs.writeFileSync(path.join(p50, '50-01-PLAN.md'), '# Plan 1');
fs.writeFileSync(path.join(p50, '50-02-PLAN.md'), '# Plan 2');
// Only plan 1 has a summary (completed)
fs.writeFileSync(path.join(p50, '50-01-SUMMARY.md'), '# Summary 1');
const result = runGsdTools('roadmap update-plan-progress 50', tmpDir);
assert.ok(result.success, `Command failed: ${result.error}`);
const roadmap = fs.readFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), 'utf-8');
assert.ok(roadmap.includes('[x] 50-01-PLAN.md') || roadmap.includes('[x] 50-01'),
'completed plan checkbox should be marked');
assert.ok(roadmap.includes('[ ] 50-02-PLAN.md') || roadmap.includes('[ ] 50-02'),
'incomplete plan checkbox should remain unchecked');
});
});
// ─────────────────────────────────────────────────────────────────────────────