Files
2026-08-28 11:43:34 -04:00

116 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""
OpenJarvis Skills Compatibility Checker
Verifies that all frontmatter fields are properly mapped in FIELD_MAPPING.
Usage: python3 check_skill_compatibility.py
"""
import re
import sys
from pathlib import Path
def extract_field_mapping(parser_path):
"""Extract FIELD_MAPPING from parser.py"""
content = parser_path.read_text()
# Find FIELD_MAPPING dictionary
match = re.search(r'FIELD_MAPPING: Dict\[str, tuple\[str, str\]\] = \{(.*?)\}',
content, re.DOTALL)
if not match:
print("ERROR: Could not find FIELD_MAPPING in parser.py")
return {}
mapping_text = match.group(1)
# Extract key-value pairs
fields = {}
for line in mapping_text.split('\n'):
m = re.search(r'"(\w+)":\s*\("(\w+)",\s*"(\w+)"\)', line)
if m:
fields[m.group(1)] = (m.group(2), m.group(3))
return fields
def check_skill_frontmatter(skill_md_path, mapped_fields):
"""Check a skill's frontmatter for unmapped fields"""
content = skill_md_path.read_text()
if not content.startswith('---'):
return []
# Extract frontmatter
parts = content.split('---', 2)
if len(parts) < 3:
return []
frontmatter = parts[1]
# Find all field names
field_pattern = r'^(\w+):'
found_fields = re.findall(field_pattern, frontmatter, re.MULTILINE)
# Standard SPEC_FIELDS from parser.py
spec_fields = {"name", "description", "license", "compatibility",
"metadata", "allowed-tools"}
unmapped = []
for field in found_fields:
if field not in spec_fields and field not in mapped_fields:
unmapped.append(field)
return unmapped
def main():
# Default paths (adjust based on your setup)
parser_path = Path("src/openjarvis/skills/parser.py")
skills_dir = Path("~/.openjarvis/skill-cache/hermes/skills").expanduser()
if not parser_path.exists():
print(f"ERROR: {parser_path} not found")
print("Please run from OpenJarvis source directory")
sys.exit(1)
print("OpenJarvis Skills Compatibility Checker")
print("=" * 50)
# Extract current FIELD_MAPPING
mapped_fields = extract_field_mapping(parser_path)
print(f"\nFound {len(mapped_fields)} mapped fields in FIELD_MAPPING:")
for field, (target, attr) in sorted(mapped_fields.items()):
print(f" {field} -> {target}.{attr}")
if not skills_dir.exists():
print(f"\nNote: Skills cache not found at {skills_dir}")
print("Run 'jarvis skill sync hermes' first")
sys.exit(0)
# Check all skills
print(f"\nChecking skills in {skills_dir}...")
skill_dirs = [d for d in skills_dir.iterdir() if d.is_dir()]
total_skills = 0
total_unmapped = 0
for skill_dir in skill_dirs:
skill_md = skill_dir / "SKILL.md"
if not skill_md.exists():
continue
total_skills += 1
unmapped = check_skill_frontmatter(skill_md, mapped_fields)
if unmapped:
total_unmapped += len(unmapped)
print(f" \033[93m⚠ {skill_dir.name}: {', '.join(unmapped)}\033[0m")
print(f"\n{'='*50}")
print(f"Total skills checked: {total_skills}")
print(f"Total unmapped fields: {total_unmapped}")
if total_unmapped == 0:
print("\n✅ All frontmatter fields properly mapped!")
else:
print(f"\n\033[91m⚠ Found {total_unmapped} unmapped field(s)\033[0m")
print("Add them to FIELD_MAPPING in parser.py")
return 0 if total_unmapped == 0 else 1
if __name__ == "__main__":
sys.exit(main())