perf(init): hoist readdirSync and regex out of phase loop in manager (#1900)

cmdInitManager called fs.readdirSync(phasesDir) and compiled a new
RegExp inside the per-phase while loop. At 50 phases this produced
50 redundant directory scans and 50 regex compilations with full
ROADMAP content scans.

Move the directory listing before the loop and pre-extract all
checkbox states via a single matchAll pass. This reduces both
patterns from O(N^2) to O(N).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tibsfox
2026-04-07 14:25:09 -07:00
committed by GitHub
parent 28517f7b6d
commit 4334e49419

View File

@@ -870,6 +870,23 @@ function cmdInitManager(cwd, raw) {
const phasesDir = paths.phases;
const isDirInMilestone = getMilestonePhaseFilter(cwd);
// Pre-compute directory listing once (avoids O(N) readdirSync per phase)
const _phaseDirEntries = (() => {
try {
return fs.readdirSync(phasesDir, { withFileTypes: true })
.filter(e => e.isDirectory())
.map(e => e.name);
} catch { return []; }
})();
// Pre-extract all checkbox states in a single pass (avoids O(N) regex per phase)
const _checkboxStates = new Map();
const _cbPattern = /-\s*\[(x| )\]\s*.*Phase\s+(\d+[A-Z]?(?:\.\d+)*)[:\s]/gi;
let _cbMatch;
while ((_cbMatch = _cbPattern.exec(content)) !== null) {
_checkboxStates.set(_cbMatch[2], _cbMatch[1].toLowerCase() === 'x');
}
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
const phases = [];
let match;
@@ -900,8 +917,7 @@ function cmdInitManager(cwd, raw) {
let isActive = false;
try {
const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).filter(isDirInMilestone);
const dirs = _phaseDirEntries.filter(isDirInMilestone);
const dirMatch = dirs.find(d => phaseTokenMatches(d, normalized));
if (dirMatch) {
@@ -935,10 +951,8 @@ function cmdInitManager(cwd, raw) {
}
} catch { /* intentionally empty */ }
// Check ROADMAP checkbox status
const checkboxPattern = new RegExp(`-\\s*\\[(x| )\\]\\s*.*Phase\\s+${phaseNum.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}[:\\s]`, 'i');
const checkboxMatch = content.match(checkboxPattern);
const roadmapComplete = checkboxMatch ? checkboxMatch[1] === 'x' : false;
// Check ROADMAP checkbox status (pre-extracted above the loop)
const roadmapComplete = _checkboxStates.get(phaseNum) || false;
if (roadmapComplete && diskStatus !== 'complete') {
diskStatus = 'complete';
}