import json import re import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] PLUGIN = ROOT / "plugins" / "shd-mcp-plugin" SKILLS = PLUGIN / "skills" EXPECTED_SKILLS = { "shd-active-projects", "shd-analytics", "shd-agents-operations", "shd-discussions", "shd-documents", "shd-entity-resolution", "shd-estimate-management", "shd-event-positions", "shd-finance-crm", "shd-financial-account-audit", "shd-gitea", "shd-inventory", "shd-notifications", "shd-organizations-acl", "shd-project-db-audit", "shd-project-files", "shd-project-status", "shd-realtime-activity", "shd-routing", "shd-safe-bulk-change", "shd-status-page", "shd-task-workflow", "shd-terms-contracts", "shd-wiki-management", } class PluginPackageTests(unittest.TestCase): @classmethod def setUpClass(cls): cls.manifest = json.loads( (PLUGIN / ".codex-plugin" / "plugin.json").read_text(encoding="utf-8") ) def test_manifest_points_to_real_package_parts(self): self.assertEqual(self.manifest["name"], "shd-mcp-plugin") self.assertRegex(self.manifest["version"], r"^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$") self.assertTrue((PLUGIN / self.manifest["skills"].removeprefix("./")).is_dir()) self.assertTrue((PLUGIN / self.manifest["mcpServers"].removeprefix("./")).is_file()) interface = self.manifest["interface"] for field in ("composerIcon", "logo"): asset = interface[field] self.assertTrue((PLUGIN / asset.removeprefix("./")).is_file(), field) self.assertLessEqual(len(interface["defaultPrompt"]), 3) def test_all_expected_skills_have_contract_files(self): actual = {path.parent.name for path in SKILLS.glob("*/SKILL.md")} self.assertEqual(actual, EXPECTED_SKILLS) routing = (SKILLS / "shd-routing" / "SKILL.md").read_text(encoding="utf-8") for name in EXPECTED_SKILLS - {"shd-routing"}: self.assertIn(f"`{name}`", routing, name) for name in sorted(EXPECTED_SKILLS): skill_dir = SKILLS / name skill_text = (skill_dir / "SKILL.md").read_text(encoding="utf-8") self.assertTrue(skill_text.startswith("---\n"), name) self.assertRegex(skill_text, r"(?m)^name:\s*\S+", name) self.assertRegex(skill_text, r"(?m)^description:\s*.+", name) self.assertNotIn("[TODO:", skill_text, name) references = list((skill_dir / "references").glob("*.md")) self.assertTrue(references, f"{name} has no reference contract") agents = skill_dir / "agents" / "openai.yaml" agent_text = agents.read_text(encoding="utf-8") self.assertIn("interface:", agent_text, name) self.assertIn("display_name:", agent_text, name) self.assertIn("short_description:", agent_text, name) self.assertIn("allow_implicit_invocation: false", agent_text, name) if __name__ == "__main__": unittest.main()