diff --git a/src/resources/extensions/gsd/pre-execution-checks.ts b/src/resources/extensions/gsd/pre-execution-checks.ts index f0a4b692e..7d682b6bf 100644 --- a/src/resources/extensions/gsd/pre-execution-checks.ts +++ b/src/resources/extensions/gsd/pre-execution-checks.ts @@ -237,9 +237,12 @@ export async function checkPackageExistence( */ export function normalizeFilePath(filePath: string): string { if (!filePath) return filePath; - + + // Strip backtick wrapping from LLM-generated paths (#3649) + let normalized = filePath.replace(/`/g, ""); + // Normalize path separators to forward slashes - let normalized = filePath.replace(/\\/g, "/"); + normalized = normalized.replace(/\\/g, "/"); // Remove leading ./ while (normalized.startsWith("./")) { @@ -272,10 +275,13 @@ function getExpectedOutputsUpTo(tasks: TaskRow[], taskIndex: number): Set = { function validatePlanSlice(content: string): ContentViolation[] { const violations: ContentViolation[] = []; - // Must have at least 2 task entries (checkbox pattern) + // Must have at least 1 task entry — single-task slices are valid (#3649) const taskCount = (content.match(/- \[[ x]\] \*\*T\d+/g) || []).length; - if (taskCount < 2) { + if (taskCount < 1) { violations.push({ severity: "warning", - reason: `Slice plan has only ${taskCount} task(s) — expected at least 2`, + reason: `Slice plan has ${taskCount} task(s) — expected at least 1`, }); }