#!/usr/bin/env python3 """Test script to verify local skills are properly set up.""" import sys from pathlib import Path from adapters.base import InboundMessage, MessageType from adapters.skill_integration import SkillInvoker def test_skill_discovery() -> bool: """Test that skills are discovered correctly.""" print("=" * 60) print("Testing Skill Discovery") print("=" * 60) invoker = SkillInvoker() skills = invoker.list_available_skills() print(f"\nFound {len(skills)} skill(s):") for skill in skills: print(f" + {skill}") if not skills: print(" ! No skills found!") print( " Create skills in: " ".claude/skills//SKILL.md" ) return len(skills) > 0 def test_skill_info() -> bool: """Test skill info retrieval.""" print("\n" + "=" * 60) print("Testing Skill Info") print("=" * 60) invoker = SkillInvoker() skills = invoker.list_available_skills() for skill in skills: info = invoker.get_skill_info(skill) print(f"\n/{skill}:") if info: fields = [ ("Name", "name"), ("Description", "description"), ("User-invocable", "user-invocable"), ("Disable auto-invoke", "disable-model-invocation"), ("Allowed tools", "allowed-tools"), ("Context", "context"), ("Agent", "agent"), ("Path", "path"), ] for label, key in fields: print(f" {label}: {info.get(key, 'N/A')}") body_preview = info.get("body", "")[:100] print(f" Instructions preview: {body_preview}...") else: print(" ! Could not load skill info") return True def test_skill_structure() -> bool: """Test skill directory structure.""" print("\n" + "=" * 60) print("Testing Skill Structure") print("=" * 60) skills_dir = Path(".claude/skills") if not skills_dir.exists(): print( " ! Skills directory not found: " ".claude/skills/" ) return False print(f"\nSkills directory: {skills_dir.absolute()}") for skill_dir in skills_dir.iterdir(): if not skill_dir.is_dir(): continue skill_md = skill_dir / "SKILL.md" examples_dir = skill_dir / "examples" md_icon = "+" if skill_md.exists() else "x" ex_icon = "+" if examples_dir.exists() else "-" print(f"\n {skill_dir.name}/") print(f" SKILL.md: {md_icon}") print(f" examples/: {ex_icon} (optional)") if examples_dir.exists(): for ef in examples_dir.glob("*.md"): print(f" - {ef.name}") return True def test_preprocessor() -> bool: """Test skill preprocessor logic.""" print("\n" + "=" * 60) print("Testing Skill Preprocessor") print("=" * 60) test_message = InboundMessage( platform="test", user_id="test123", username="testuser", text="/adapter-dev create WhatsApp adapter", channel_id="test-channel", thread_id=None, reply_to_id=None, message_type=MessageType.TEXT, metadata={}, raw=None, ) print(f"\nTest message: {test_message.text}") if not test_message.text.startswith("/"): return False parts = test_message.text.split(maxsplit=1) skill_name = parts[0][1:] args = parts[1] if len(parts) > 1 else "" print(f" Detected skill: {skill_name}") print(f" Arguments: {args}") invoker = SkillInvoker() if skill_name in invoker.list_available_skills(): print(" + Skill exists and can be invoked") return True print(" ! Skill not found") return False def main() -> bool: """Run all tests.""" print("\nAjarbot Skills Test Suite\n") results = [ ("Skill Discovery", test_skill_discovery()), ("Skill Info", test_skill_info()), ("Skill Structure", test_skill_structure()), ("Skill Preprocessor", test_preprocessor()), ] print("\n" + "=" * 60) print("Test Summary") print("=" * 60) for test_name, passed in results: status = "+ PASS" if passed else "x FAIL" print(f" {status}: {test_name}") passed_count = sum(1 for _, p in results if p) total_count = len(results) print(f"\n{passed_count}/{total_count} tests passed") if passed_count == total_count: print("\nAll tests passed! Skills are ready to use.") print("\nNext steps:") print(" 1. Try invoking a skill: /adapter-dev") print( " 2. Test in bot: " "python example_bot_with_skills.py" ) print(" 3. Create your own skills in: .claude/skills/") else: print("\nSome tests failed. Check the output above.") return passed_count == total_count if __name__ == "__main__": success = main() sys.exit(0 if success else 1)