| 38 | let visited = 0; |
| 39 | |
| 40 | async function walk(dir: string, depth: number): Promise<void> { |
| 41 | if (visited >= maxVisited || depth > 8 || hits.length >= maxResults * 4) return; |
| 42 | let entries; |
| 43 | try { entries = await fs.readdir(dir, { withFileTypes: true }); } catch { return; } |
| 44 | for (const e of entries) { |
| 45 | if (visited >= maxVisited) return; |
| 46 | visited++; |
| 47 | if (e.name.startsWith('.') && e.name !== '.env') continue; |
| 48 | const abs = path.join(dir, e.name); |
| 49 | if (e.isDirectory()) { |
| 50 | if (SKIP_DIRS.has(e.name)) continue; |
| 51 | await walk(abs, depth + 1); |
| 52 | } else { |
| 53 | const base = e.name.toLowerCase(); |
| 54 | if (base === wantBase) { |
| 55 | hits.push({ rel: path.relative(root, abs), score: 3 }); // exact basename |
| 56 | } else if (base.replace(path.extname(base), '') === wantStem) { |
| 57 | hits.push({ rel: path.relative(root, abs), score: 2 }); // same stem, diff ext |
| 58 | } |
| 59 | } |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | await walk(root, 0); |
| 64 | return hits |