MCPcopy Create free account
hub / github.com/FIND-Lab/AgentWard / scanSkillDirectory

Function scanSkillDirectory

layers/foundation-scan.ts:782–815  ·  view source on GitHub ↗
(
  skill: Skill,
  llmContext: LlmCallContext | null,
  logger: LoggerLike,
  options: Required<FoundationScanConfig>,
)

Source from the content-addressed store, hash-verified

780
781
782async function scanSkillDirectory(
783 skill: Skill,
784 llmContext: LlmCallContext | null,
785 logger: LoggerLike,
786 options: Required<FoundationScanConfig>,
787): Promise<Warning | null> {
788 if (!skill.filePath) {
789 logger?.warn(`[FoundationScan] skip skill without filePath: ${skill.name ?? "(unknown)"}`);
790 return null;
791 }
792
793 const baseDir = skill.baseDir || path.dirname(skill.filePath);
794 const textFiles = listTextFilesRecursively(baseDir);
795 logger?.info(`[FoundationScan] scanning skill=${skill.name ?? "(unknown)"}, files=${textFiles.length}`);
796
797 const { metadataSummary, warning: metadataWarning } = (options.detectMaliciousSkills.semanticDetection && llmContext)
798 ? await scanSkillMetadata(skill, llmContext, logger)
799 : { metadataSummary: "", warning: null as Warning | null };
800
801 if (metadataWarning) {
802 return metadataWarning;
803 }
804
805 for (const filePath of textFiles) {
806 if (options.detectMaliciousSkills.semanticDetection && llmContext) {
807 const warning = await scanSkillFile(skill, filePath, metadataSummary, llmContext, logger, options);
808 if (warning) {
809 return warning;
810 }
811 }
812 }
813
814 return null;
815}
816
817export async function detectMaliciousSkills(
818 workspaceDir: string,

Callers 1

detectMaliciousSkillsFunction · 0.85

Calls 3

listTextFilesRecursivelyFunction · 0.85
scanSkillMetadataFunction · 0.85
scanSkillFileFunction · 0.85

Tested by

no test coverage detected