MCPcopy Index your code
hub / github.com/codeaashu/claude-code / collectMarkdown

Function collectMarkdown

src/utils/plugins/validatePlugin.ts:718–752  ·  view source on GitHub ↗

* Recursively collect .md files under a directory. Uses withFileTypes to * avoid a stat per entry. Returns absolute paths so error messages stay * readable.

(
  dir: string,
  isSkillsDir: boolean,
)

Source from the content-addressed store, hash-verified

716 * readable.
717 */
718async function collectMarkdown(
719 dir: string,
720 isSkillsDir: boolean,
721): Promise<string[]> {
722 let entries: Dirent[]
723 try {
724 entries = await readdir(dir, { withFileTypes: true })
725 } catch (e: unknown) {
726 const code = getErrnoCode(e)
727 if (code === 'ENOENT' || code === 'ENOTDIR') return []
728 throw e
729 }
730
731 // Skills use <name>/SKILL.md — only descend one level, only collect SKILL.md.
732 // Matches the runtime loader: single .md files in skills/ are NOT loaded,
733 // and subdirectories of a skill dir aren't scanned. Paths are speculative
734 // (the subdir may lack SKILL.md); the caller handles ENOENT.
735 if (isSkillsDir) {
736 return entries
737 .filter(e => e.isDirectory())
738 .map(e => path.join(dir, e.name, 'SKILL.md'))
739 }
740
741 // Commands/agents: recurse and collect all .md files.
742 const out: string[] = []
743 for (const entry of entries) {
744 const full = path.join(dir, entry.name)
745 if (entry.isDirectory()) {
746 out.push(...(await collectMarkdown(full, false)))
747 } else if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
748 out.push(full)
749 }
750 }
751 return out
752}
753
754/**
755 * Validate the content files inside a plugin directory — skills, agents,

Callers 1

validatePluginContentsFunction · 0.85

Calls 3

readdirFunction · 0.85
getErrnoCodeFunction · 0.85
pushMethod · 0.45

Tested by

no test coverage detected