fix(#1588): ignore fenced and backlog roadmap phases (#1845)

* fix(#1588): ignore fenced and backlog roadmap phases

* chore(#1588): add changeset fragment

* chore(#1588): fix changeset body

* test(#1588): fold init regression into init suite
This commit is contained in:
Tom Boucher
2026-06-30 20:43:25 -04:00
committed by GitHub
parent 8161fcc667
commit 9e32462dd8
6 changed files with 159 additions and 46 deletions

View File

@@ -209,19 +209,22 @@ interface RoadmapPhaseResult {
}
function findRoadmapPhaseInContent(content: string, phaseNum: unknown, phaseSource?: string): RoadmapPhaseResult | null {
const phasePattern = new RegExp(
`#{2,4}\\s*(?:\\[[^\\]]+\\]\\s*)?Phase\\s+${phaseSource ?? phaseMarkdownRegexSource(phaseNum)}:\\s*([^\\n]+)`,
const headingPattern = new RegExp(
`^(?:\\[[^\\]]+\\]\\s*)?Phase\\s+${phaseSource ?? phaseMarkdownRegexSource(phaseNum)}:\\s*(.+)$`,
'i'
);
const headerMatch = content.match(phasePattern);
const headings = tokenizeHeadings(content);
const headingIndex = headings.findIndex((heading) => headingPattern.test(heading.text));
if (headingIndex === -1) return null;
const heading = headings[headingIndex];
const headerMatch = heading.text.match(headingPattern);
if (!headerMatch) return null;
const phaseName = headerMatch[1].trim();
const headerIndex = headerMatch.index!;
const restOfContent = content.slice(headerIndex);
const nextHeaderMatch = restOfContent.match(/\n#{2,4}\s+(?:\[[^\]]+\]\s*)?Phase\s+[\w]/i);
const sectionEnd = nextHeaderMatch ? headerIndex + nextHeaderMatch.index! : content.length;
const section = content.slice(headerIndex, sectionEnd).trim();
const nextHeading = headings.slice(headingIndex + 1).find((candidate) => candidate.level <= heading.level);
const sectionEnd = nextHeading ? nextHeading.offset : content.length;
const section = content.slice(heading.offset, sectionEnd).trim();
const goalMatch = section.match(/\*\*Goal(?:\*\*:|\*?\*?:\*\*)\s*([^\n]+)/i);
const goal = goalMatch ? goalMatch[1].trim() : null;
@@ -254,6 +257,8 @@ function roadmapPhaseLookupSources(phaseNum: unknown): string[] {
function getRoadmapPhaseInternal(cwd: string, phaseNum: unknown): RoadmapPhaseResult | null {
if (!phaseNum) return null;
const normalizedPhase = stripProjectCodePrefix(phaseNum);
if (/^999(?:\.|$)/.test(normalizedPhase)) return null;
const roadmapPath = path.join(planningDir(cwd), 'ROADMAP.md');
if (!fs.existsSync(roadmapPath)) return null;