From a9f49f8f9d0f812e8c73aa6352021415c3a1fda1 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 26 Apr 2026 09:46:57 -0400 Subject: [PATCH] fix(phase-lifecycle): prevent plan-line overwrite when **Plans:** is bare \s* after **Plans:** matches newlines, causing [^\n]+ to consume the first plan checkbox when the **Plans:** field has no value on the same line. Additionally, the lazy [\s\S]*? could cross section boundaries when the current section had no **Plans:** value, corrupting a later section. Fix 1: replace \s* with [ \t]* to restrict post-colon match to horizontal whitespace only. Fix 2: replace [\s\S]*? with (?:(?!\n#{2,4})[\s\S])*? to prevent the pattern from crossing into a new section heading. Closes #2728 --- sdk/package-lock.json | 2 +- sdk/src/query/phase-lifecycle.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/package-lock.json b/sdk/package-lock.json index 81d09b38f..2c5feb86b 100644 --- a/sdk/package-lock.json +++ b/sdk/package-lock.json @@ -22,7 +22,7 @@ "vitest": "^3.1.1" }, "engines": { - "node": ">=20" + "node": ">=22.0.0" } }, "node_modules/@anthropic-ai/claude-agent-sdk": { diff --git a/sdk/src/query/phase-lifecycle.ts b/sdk/src/query/phase-lifecycle.ts index 5211c46a6..c02e81ee2 100644 --- a/sdk/src/query/phase-lifecycle.ts +++ b/sdk/src/query/phase-lifecycle.ts @@ -1194,7 +1194,7 @@ export const phaseComplete: QueryHandler = async (args, projectDir, workstream) // Update plan count in phase section const planCountPattern = new RegExp( - `(#{2,4}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`, + `(#{2,4}\\s*Phase\\s+${phaseEscaped}(?:(?!\\n#{2,4})[\\s\\S])*?\\*\\*Plans:\\*\\*[ \\t]*)[^\\n]+`, 'i', ); roadmapContent = replaceInCurrentMilestone(