( baseDir: string, type: SkillType, toolId: string, namingMode: NamingMode = "auto" )
| 96 | } |
| 97 | |
| 98 | function scanFlatMd( |
| 99 | baseDir: string, |
| 100 | type: SkillType, |
| 101 | toolId: string, |
| 102 | namingMode: NamingMode = "auto" |
| 103 | ): SkillItem[] { |
| 104 | if (!existsSync(baseDir)) return []; |
| 105 | const items: SkillItem[] = []; |
| 106 | |
| 107 | for (const entry of readdirSync(baseDir, { withFileTypes: true })) { |
| 108 | const fullPath = join(baseDir, entry.name); |
| 109 | const isDir = entry.isDirectory() || (entry.isSymbolicLink() && statSync(fullPath, { throwIfNoEntry: false })?.isDirectory()); |
| 110 | |
| 111 | if (isDir) { |
| 112 | const skillFile = join(fullPath, "SKILL.md"); |
| 113 | if (existsSync(skillFile)) { |
| 114 | const item = parseSkillFile(skillFile, type, toolId, "flat-md", namingMode); |
| 115 | if (item) items.push(item); |
| 116 | continue; |
| 117 | } |
| 118 | const mdFiles = readdirSync(fullPath).filter( |
| 119 | (f) => f.endsWith(".md") && !IGNORED_FILES.has(f.toLowerCase()) |
| 120 | ); |
| 121 | const preferred = |
| 122 | mdFiles.find( |
| 123 | (f) => f.toLowerCase() === `${entry.name.toLowerCase()}.md` |
| 124 | ) || mdFiles[0]; |
| 125 | if (preferred) { |
| 126 | const item = parseSkillFile( |
| 127 | join(fullPath, preferred), |
| 128 | type, |
| 129 | toolId, |
| 130 | "flat-md", |
| 131 | namingMode |
| 132 | ); |
| 133 | if (item) items.push(item); |
| 134 | } |
| 135 | continue; |
| 136 | } |
| 137 | |
| 138 | const fname = entry.name.toLowerCase(); |
| 139 | if (!fname.endsWith(".md") || IGNORED_FILES.has(fname)) continue; |
| 140 | const item = parseSkillFile(fullPath, type, toolId, "flat-md", namingMode); |
| 141 | if (item) items.push(item); |
| 142 | } |
| 143 | return items; |
| 144 | } |
| 145 | |
| 146 | function scanMdc( |
| 147 | baseDir: string, |
no test coverage detected