Skip to content Navigation MenuSign inAppearance settingsPlatformAI CODE CREATIONGitHub CopilotWrite better code with AIGitHub Copilot appDirect agents from issue to mergeMCP RegistryIntegrate external toolsDEVELOPER WORKFLOWSActionsAutomate any workflowCodespacesInstant dev environmentsIssuesPlan and track workCode ReviewManage code changesCode QualityEnforce quality at mergeAPPLICATION SECURITYGitHub Advanced SecurityFind and fix vulnerabilitiesCode securitySecure your code as you buildSecret protectionStop leaks before they startEXPLOREWhy GitHubDocumentationBlogChangelogMarketplaceView all featuresSolutionsBY COMPANY SIZEEnterprisesSmall and medium teamsStartupsNonprofitsBY USE CASEApp ModernizationDevSecOpsDevOpsCI/CDView all use casesBY INDUSTRYHealthcareFinancial servicesManufacturingGovernmentView all industriesView all solutionsResourcesEXPLORE BY TOPICAISoftware DevelopmentDevOpsSecurityView all topicsEXPLORE BY TYPECustomer storiesEvents & webinarsEbooks & reportsBusiness insightsGitHub SkillsSUPPORT & SERVICESDocumentationCustomer supportCommunity forumTrust centerPartnersView all resourcesOpen SourceCOMMUNITYGitHub SponsorsFund open source developersPROGRAMSSecurity LabMaintainer CommunityGitHub StarsArchive ProgramREPOSITORIESTopicsTrendingCollectionsEnterpriseENTERPRISE SOLUTIONSEnterprise platformAI-powered developer platformAVAILABLE ADD-ONSGitHub Advanced SecurityEnterprise-grade security featuresCopilot for BusinessEnterprise-grade AI featuresPremium SupportEnterprise-grade 24/7 supportPricingSearch/Sign inSign upAppearance settings You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} openclawagent-skillsRepository navigationCodeIssues3 (3)Pull requestsActionsProjectsSecurity and qualityInsightsMore items FilesExpand file treemainBreadcrumbsagent-skills/scripts/validate-skillsCopy pathBlameMore file actionsBlameMore file actions Latest commit HistoryHistoryHistoryexecutable file·80 lines (61 loc) · 2.28 KBmainBreadcrumbsagent-skills/scripts/validate-skillsCopy pathTopFile metadata and controlsCodeBlameexecutable file·80 lines (61 loc) · 2.28 KBRawCopy raw fileDownload raw fileOpen symbols panelEdit and raw actions1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980#!/usr/bin/env python3 from __future__ import annotations import reimport sysfrom pathlib import Path try: import yamlexcept ModuleNotFoundError: print( "PyYAML is required; run: python3 -m pip install -r requirements-dev.txt", file=sys.stderr, ) raise SystemExit(2) class NoAliasSafeLoader(yaml.SafeLoader): def compose_node(self, parent: object, index: object) -> yaml.Node: if self.check_event(yaml.AliasEvent): event = self.get_event() raise yaml.YAMLError(f"YAML aliases are not allowed: {event.anchor}") return super().compose_node(parent, index) def load_frontmatter(text: str) -> tuple[dict[object, object] | None, str | None]: if not text.startswith("---\n"): return None, "missing YAML frontmatter" close = re.search(r"^---[ \t]*$", text[4:], re.MULTILINE) if close is None: return None, "unterminated YAML frontmatter" try: data = yaml.load(text[4:4 + close.start()], Loader=NoAliasSafeLoader) except yaml.YAMLError as error: return None, f"invalid YAML: {error}" if data is None: data = {} if not isinstance(data, dict): return None, "YAML frontmatter must be a mapping" return data, None def main() -> int: root = Path(__file__).resolve().parent.parent skill_files = sorted((root / "skills").glob("*/SKILL.md")) if not skill_files: print("No skills/*/SKILL.md files found.", file=sys.stderr) return 1 errors: list[str] = [] for path in skill_files: rel = path.relative_to(root) data, error = load_frontmatter(path.read_text(encoding="utf-8")) if error is not None: errors.append(f"{rel}: {error}") continue assert data is not None name = data.get("name") description = data.get("description") if not isinstance(name, str) or not name.strip(): errors.append(f"{rel}: missing name") if not isinstance(description, str) or not description.strip(): errors.append(f"{rel}: missing description") if errors: print("\n".join(errors), file=sys.stderr) return 1 print(f"validated {len(skill_files)} skills") return 0 if __name__ == "__main__": raise SystemExit(main()) You can’t perform that action at this time.