From 8270f177738ca3c90292db370d44ebd90a74bcaa Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 26 Apr 2026 11:21:33 -0400 Subject: [PATCH] fix(phase-lifecycle): handle project-code-prefixed dirs in phaseAdd fallback scan Filesystem fallback regex /^(\d+)-/ missed directories like CK-45-foundation when project_code is configured. Updated to /^(?:[A-Z][A-Z0-9]*-)?(\d+)-/i. Addresses coderabbit finding on PR #2737. --- sdk/src/query/phase-lifecycle.test.ts | 23 +++++++++++++++++++++++ sdk/src/query/phase-lifecycle.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/sdk/src/query/phase-lifecycle.test.ts b/sdk/src/query/phase-lifecycle.test.ts index 256e7cc2f..9fab1b81b 100644 --- a/sdk/src/query/phase-lifecycle.test.ts +++ b/sdk/src/query/phase-lifecycle.test.ts @@ -316,6 +316,29 @@ describe('phaseAdd', () => { // Should detect phases 45 and 46 on disk, so new phase = 47 expect(data.phase_number).toBe(47); }); + + it('filesystem fallback handles project-code-prefixed phase directories (regression coderabbit)', async () => { + const { phaseAdd } = await import('./phase-lifecycle.js'); + + const roadmap = '# Roadmap\n\n## Current Milestone: v5.0\n\nSome content\n'; + + await setupTestProject(tmpDir, { + roadmap, + state: MINIMAL_STATE, + phases: [], + }); + + // Create prefixed directories manually (project_code = "CK" scenario) + const phasesDir = join(tmpDir, '.planning', 'phases'); + await mkdir(join(phasesDir, 'CK-45-legacy-phase'), { recursive: true }); + await mkdir(join(phasesDir, 'CK-46-another-phase'), { recursive: true }); + + const result = await phaseAdd(['new-feature'], tmpDir); + const data = result.data as Record; + + // Should detect CK-45 and CK-46, so new phase = 47 + expect(data.phase_number).toBe(47); + }); }); // ─── phaseAddBatch ───────────────────────────────────────────────────── diff --git a/sdk/src/query/phase-lifecycle.ts b/sdk/src/query/phase-lifecycle.ts index f3b4f4236..576d0169c 100644 --- a/sdk/src/query/phase-lifecycle.ts +++ b/sdk/src/query/phase-lifecycle.ts @@ -209,7 +209,7 @@ export const phaseAdd: QueryHandler = async (args, projectDir, workstream) => { const entries = await readdir(phasesDir, { withFileTypes: true }); for (const entry of entries) { if (!entry.isDirectory()) continue; - const dirMatch = /^(\d+)[A-Z]?(?:\.\d+)*-/.exec(entry.name); + const dirMatch = /^(?:[A-Z][A-Z0-9]*-)?(\d+)[A-Z]?(?:\.\d+)*-/i.exec(entry.name); if (dirMatch) { const num = parseInt(dirMatch[1], 10); if (num >= 999) continue;