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-skills.test.pyCopy pathBlameMore file actionsBlameMore file actions Latest commit HistoryHistoryHistory136 lines (108 loc) · 4.78 KBmainBreadcrumbsagent-skills/scripts/validate-skills.test.pyCopy pathTopFile metadata and controlsCodeBlame136 lines (108 loc) · 4.78 KBRawCopy raw fileDownload raw fileOpen symbols panelEdit and raw actions123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136from __future__ import annotations import shutilimport subprocessimport sysimport tempfileimport unittestfrom pathlib import Path SCRIPT = Path(__file__).with_name("validate-skills") class ValidateSkillsTest(unittest.TestCase): def run_validator( self, skills: dict[str, str] | None ) -> subprocess.CompletedProcess[str]: with tempfile.TemporaryDirectory() as tmp: repo = Path(tmp) / "repo" (repo / "scripts").mkdir(parents=True) shutil.copy2(SCRIPT, repo / "scripts" / "validate-skills") for name, content in (skills or {}).items(): skill_dir = repo / "skills" / name skill_dir.mkdir(parents=True) (skill_dir / "SKILL.md").write_text(content, encoding="utf-8") return subprocess.run( [sys.executable, str(repo / "scripts" / "validate-skills")], check=False, capture_output=True, text=True, ) def test_valid_frontmatter(self) -> None: result = self.run_validator( { "sample": ( '---\nname: sample\ndescription: "Example skill."\n' 'metadata:\n version: "1"\n---\n# Sample\n' ) } ) self.assertEqual(result.returncode, 0, result.stderr) self.assertEqual(result.stdout, "validated 1 skills\n") def test_missing_frontmatter(self) -> None: result = self.run_validator({"sample": "# Sample\n"}) self.assertEqual(result.returncode, 1) self.assertIn("missing YAML frontmatter", result.stderr) def test_unterminated_frontmatter(self) -> None: result = self.run_validator({"sample": "---\nname: sample\n"}) self.assertEqual(result.returncode, 1) self.assertIn("unterminated YAML frontmatter", result.stderr) def test_closing_delimiter_must_be_a_complete_line(self) -> None: for delimiter in ("----", "---suffix"): with self.subTest(delimiter=delimiter): result = self.run_validator( {"sample": f"---\nname: sample\ndescription: Example\n{delimiter}\n"} ) self.assertEqual(result.returncode, 1) self.assertIn("unterminated YAML frontmatter", result.stderr) def test_closing_delimiter_allows_trailing_whitespace(self) -> None: result = self.run_validator( {"sample": "---\nname: sample\ndescription: Example\n--- \t\n# Sample\n"} ) self.assertEqual(result.returncode, 0, result.stderr) def test_falsey_yaml_values_are_not_mappings(self) -> None: for value in ("false", "0", "[]", '""'): with self.subTest(value=value): result = self.run_validator({"sample": f"---\n{value}\n---\n"}) self.assertEqual(result.returncode, 1) self.assertIn("YAML frontmatter must be a mapping", result.stderr) def test_invalid_yaml(self) -> None: result = self.run_validator( {"sample": '---\nname: [sample\ndescription: "Example"\n---\n'} ) self.assertEqual(result.returncode, 1) self.assertIn("invalid YAML", result.stderr) def test_frontmatter_must_be_mapping(self) -> None: result = self.run_validator({"sample": "---\n- sample\n---\n"}) self.assertEqual(result.returncode, 1) self.assertIn("YAML frontmatter must be a mapping", result.stderr) def test_required_fields_must_be_nonempty_strings(self) -> None: result = self.run_validator( {"sample": '---\nname: true\ndescription: " "\n---\n'} ) self.assertEqual(result.returncode, 1) self.assertIn("missing name", result.stderr) self.assertIn("missing description", result.stderr) def test_aliases_are_rejected(self) -> None: result = self.run_validator( { "sample": ( '---\nname: &name sample\ndescription: *name\n---\n' ) } ) self.assertEqual(result.returncode, 1) self.assertIn("YAML aliases are not allowed", result.stderr) def test_unsafe_tags_are_rejected(self) -> None: result = self.run_validator( { "sample": ( "---\nname: sample\n" "description: !!python/object/apply:os.system ['false']\n---\n" ) } ) self.assertEqual(result.returncode, 1) self.assertIn("invalid YAML", result.stderr) def test_no_skills(self) -> None: result = self.run_validator(None) self.assertEqual(result.returncode, 1) self.assertEqual(result.stderr, "No skills/*/SKILL.md files found.\n") if __name__ == "__main__": unittest.main() You can’t perform that action at this time.