feat: complete SHD MCP plugin workflows and widget
Validate SHD MCP plugin / validate (push) Has been cancelled
Validate SHD MCP plugin / validate (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user