fix: require reference files at root of references/ directory (#32)

Remove support for nested subdirectories in references/.
All markdown reference files must now be placed directly in
the references/ directory (e.g., references/auth-signup.md).

- Replace getMarkdownFilesRecursive with getMarkdownFiles (flat)
- Simplify parseAllSections to only read root _sections.md
- Update getReferenceFiles to skip subdirectories
- Keep deprecated getMarkdownFilesRecursive alias for compatibility

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Pedro Rodrigues
2026-01-30 13:39:59 +00:00
committed by GitHub
parent 5e27342d4a
commit 22e466937a
2 changed files with 26 additions and 43 deletions

View File

@@ -29,9 +29,9 @@ function generateSectionMap(sections: Section[]): Record<string, number> {
} }
/** /**
* Recursively get all markdown files from a directory * Get all markdown files from a directory (flat, no subdirectories)
*/ */
function getMarkdownFilesRecursive(dir: string): string[] { function getMarkdownFiles(dir: string): string[] {
const files: string[] = []; const files: string[] = [];
if (!existsSync(dir)) { if (!existsSync(dir)) {
@@ -49,10 +49,8 @@ function getMarkdownFilesRecursive(dir: string): string[] {
const fullPath = join(dir, entry); const fullPath = join(dir, entry);
const stat = statSync(fullPath); const stat = statSync(fullPath);
if (stat.isDirectory()) { // Only include files, skip directories
// Recursively scan subdirectories if (stat.isFile() && entry.endsWith(".md")) {
files.push(...getMarkdownFilesRecursive(fullPath));
} else if (entry.endsWith(".md")) {
files.push(fullPath); files.push(fullPath);
} }
} }
@@ -60,6 +58,13 @@ function getMarkdownFilesRecursive(dir: string): string[] {
return files; return files;
} }
/**
* @deprecated Use getMarkdownFiles instead - nested directories are not supported
*/
function getMarkdownFilesRecursive(dir: string): string[] {
return getMarkdownFiles(dir);
}
/** /**
* Parse section definitions from _sections.md (legacy function for validation) * Parse section definitions from _sections.md (legacy function for validation)
*/ */
@@ -171,36 +176,20 @@ function parseSectionsFromFile(filePath: string): Section[] {
} }
/** /**
* Parse all _sections.md files from references directory and subdirectories * Parse _sections.md from references directory root only
* Note: Nested directories are not supported - all reference files should be in references/ root
*/ */
function parseAllSections(referencesDir: string): Section[] { function parseAllSections(referencesDir: string): Section[] {
const allSections: Section[] = []; const sectionsFile = join(referencesDir, "_sections.md");
if (existsSync(sectionsFile)) {
// Parse root _sections.md return parseSectionsFromFile(sectionsFile);
const rootSectionsFile = join(referencesDir, "_sections.md");
if (existsSync(rootSectionsFile)) {
allSections.push(...parseSectionsFromFile(rootSectionsFile));
} }
return [];
// Scan subdirectories for _sections.md files
if (existsSync(referencesDir)) {
const entries = readdirSync(referencesDir);
for (const entry of entries) {
const fullPath = join(referencesDir, entry);
if (statSync(fullPath).isDirectory()) {
const subSectionsFile = join(fullPath, "_sections.md");
if (existsSync(subSectionsFile)) {
allSections.push(...parseSectionsFromFile(subSectionsFile));
}
}
}
}
return allSections;
} }
/** /**
* Get all reference files (excluding _sections.md) * Get all reference files from references/ root (excluding _sections.md)
* Note: Nested directories are not supported - all reference files should be in references/ root
*/ */
function getReferenceFiles(referencesDir: string): string[] { function getReferenceFiles(referencesDir: string): string[] {
const files: string[] = []; const files: string[] = [];
@@ -220,15 +209,8 @@ function getReferenceFiles(referencesDir: string): string[] {
const fullPath = join(referencesDir, entry); const fullPath = join(referencesDir, entry);
const stat = statSync(fullPath); const stat = statSync(fullPath);
if (stat.isDirectory()) { // Only include files at root level, skip directories
// Recursively scan subdirectories if (stat.isFile() && entry.endsWith(".md")) {
const subEntries = readdirSync(fullPath);
for (const subEntry of subEntries) {
if (!subEntry.startsWith("_") && subEntry.endsWith(".md")) {
files.push(join(fullPath, subEntry));
}
}
} else if (entry.endsWith(".md")) {
files.push(fullPath); files.push(fullPath);
} }
} }
@@ -416,7 +398,8 @@ if (isMainModule) {
export { export {
buildSkill, buildSkill,
generateSectionMap, generateSectionMap,
getMarkdownFilesRecursive, getMarkdownFiles,
getMarkdownFilesRecursive, // deprecated, use getMarkdownFiles
getReferenceFiles, getReferenceFiles,
parseAllSections, parseAllSections,
parseSections, parseSections,

View File

@@ -2,7 +2,7 @@ import { existsSync } from "node:fs";
import { basename } from "node:path"; import { basename } from "node:path";
import { import {
generateSectionMap, generateSectionMap,
getMarkdownFilesRecursive, getMarkdownFiles,
parseAllSections, parseAllSections,
parseSections, parseSections,
} from "./build.js"; } from "./build.js";
@@ -158,8 +158,8 @@ function validateSkill(paths: SkillPaths): boolean {
const sections = parseAllSections(paths.referencesDir); const sections = parseAllSections(paths.referencesDir);
const sectionMap = generateSectionMap(sections); const sectionMap = generateSectionMap(sections);
// Get all markdown files recursively (excluding _ prefixed files) // Get all markdown files from references/ root (excluding _ prefixed files)
const files = getMarkdownFilesRecursive(paths.referencesDir); const files = getMarkdownFiles(paths.referencesDir);
if (files.length === 0) { if (files.length === 0) {
console.log(` No rule files found.`); console.log(` No rule files found.`);