MCPcopy
hub / github.com/claude-code-best/claude-code / validatePluginContents

Function validatePluginContents

src/utils/plugins/validatePlugin.ts:763–809  ·  view source on GitHub ↗
(
  pluginDir: string,
)

Source from the content-addressed store, hash-verified

761 * plugin returns an empty array.
762 */
763export async function validatePluginContents(
764 pluginDir: string,
765): Promise<ValidationResult[]> {
766 const results: ValidationResult[] = []
767
768 const dirs: Array<['skill' | 'agent' | 'command', string]> = [
769 ['skill', path.join(pluginDir, 'skills')],
770 ['agent', path.join(pluginDir, 'agents')],
771 ['command', path.join(pluginDir, 'commands')],
772 ]
773
774 for (const [fileType, dir] of dirs) {
775 const files = await collectMarkdown(dir, fileType === 'skill')
776 for (const filePath of files) {
777 let content: string
778 try {
779 content = await readFile(filePath, { encoding: 'utf-8' })
780 } catch (e: unknown) {
781 // ENOENT is expected for speculative skill paths (subdirs without SKILL.md)
782 if (isENOENT(e)) continue
783 results.push({
784 success: false,
785 errors: [
786 { path: 'file', message: `Failed to read: ${errorMessage(e)}` },
787 ],
788 warnings: [],
789 filePath,
790 fileType,
791 })
792 continue
793 }
794 const r = validateComponentFile(filePath, content, fileType)
795 if (r.errors.length > 0 || r.warnings.length > 0) {
796 results.push(r)
797 }
798 }
799 }
800
801 const hooksResult = await validateHooksJson(
802 path.join(pluginDir, 'hooks', 'hooks.json'),
803 )
804 if (hooksResult.errors.length > 0 || hooksResult.warnings.length > 0) {
805 results.push(hooksResult)
806 }
807
808 return results
809}
810
811/**
812 * Validate a manifest file or directory (auto-detects type)

Callers 1

pluginValidateHandlerFunction · 0.85

Calls 7

collectMarkdownFunction · 0.85
readFileFunction · 0.85
isENOENTFunction · 0.85
validateComponentFileFunction · 0.85
validateHooksJsonFunction · 0.85
errorMessageFunction · 0.50
pushMethod · 0.45

Tested by

no test coverage detected