fix(gsd): filter non-milestone directories from findMilestoneIds (#1494) (#1508)

Directories under .gsd/milestones/ that don't match the M\d+ pattern
(e.g. slices/, temp-backup/) are now excluded instead of being returned
with their raw name. This prevents rogue directories from blocking
auto-mode milestone discovery.

Closes #1494

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
TÂCHES 2026-03-19 17:33:24 -06:00 committed by GitHub
parent 95f585d183
commit bae9cf83ba
2 changed files with 29 additions and 2 deletions

View file

@ -80,8 +80,9 @@ export function findMilestoneIds(basePath: string): string[] {
.filter((d) => d.isDirectory())
.map((d) => {
const match = d.name.match(/^(M\d+(?:-[a-z0-9]{6})?)/);
return match ? match[1] : d.name;
});
return match ? match[1] : null;
})
.filter((id): id is string => id !== null);
// Apply custom queue order if available, else fall back to numeric sort
const customOrder = loadQueueOrder(basePath);

View file

@ -244,6 +244,32 @@ console.log('\n=== E2E: backward compat without QUEUE-ORDER.json ===');
}
}
// ═══════════════════════════════════════════════════════════════════════════
// Test: non-milestone directories are filtered out (#1494)
// ═══════════════════════════════════════════════════════════════════════════
console.log('\n=== E2E: non-milestone directories filtered from findMilestoneIds (#1494) ===');
{
const base = createFixtureBase();
try {
writeContext(base, 'M001', '', 'First');
writeContext(base, 'M002', '', 'Second');
// Create a rogue non-milestone directory
mkdirSync(join(base, '.gsd', 'milestones', 'slices'), { recursive: true });
mkdirSync(join(base, '.gsd', 'milestones', 'temp-backup'), { recursive: true });
invalidateStateCache();
const ids = findMilestoneIds(base);
assertEq(ids.length, 2, 'only M001 and M002 returned');
assertTrue(!ids.includes('slices'), 'slices directory excluded');
assertTrue(!ids.includes('temp-backup'), 'temp-backup directory excluded');
assertTrue(ids.includes('M001'), 'M001 included');
assertTrue(ids.includes('M002'), 'M002 included');
} finally {
cleanup(base);
}
}
// ═══════════════════════════════════════════════════════════════════════════
// Test: depends_on inline array format removal
// ═══════════════════════════════════════════════════════════════════════════