| import { join } from 'path' |
| import { logForDebugging } from '../debug.js' |
| import { getFsImplementation } from '../fsOperations.js' |
|
|
| const SKILL_MD_RE = /^skill\.md$/i |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export async function walkPluginMarkdown( |
| rootDir: string, |
| onFile: (fullPath: string, namespace: string[]) => Promise<void>, |
| opts: { stopAtSkillDir?: boolean; logLabel?: string } = {}, |
| ): Promise<void> { |
| const fs = getFsImplementation() |
| const label = opts.logLabel ?? 'plugin' |
|
|
| async function scan(dirPath: string, namespace: string[]): Promise<void> { |
| try { |
| const entries = await fs.readdir(dirPath) |
|
|
| if ( |
| opts.stopAtSkillDir && |
| entries.some(e => e.isFile() && SKILL_MD_RE.test(e.name)) |
| ) { |
| |
| await Promise.all( |
| entries.map(entry => |
| entry.isFile() && entry.name.toLowerCase().endsWith('.md') |
| ? onFile(join(dirPath, entry.name), namespace) |
| : undefined, |
| ), |
| ) |
| return |
| } |
|
|
| await Promise.all( |
| entries.map(entry => { |
| const fullPath = join(dirPath, entry.name) |
| if (entry.isDirectory()) { |
| return scan(fullPath, [...namespace, entry.name]) |
| } |
| if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) { |
| return onFile(fullPath, namespace) |
| } |
| return undefined |
| }), |
| ) |
| } catch (error) { |
| logForDebugging( |
| `Failed to scan ${label} directory ${dirPath}: ${error}`, |
| { level: 'error' }, |
| ) |
| } |
| } |
|
|
| await scan(rootDir, []) |
| } |
|
|