Read skill properties from SKILL.md frontmatter. This function parses the frontmatter and returns properties. It does NOT perform full validation. Use validate() for that. Args: skill_dir: Path to the skill directory Returns: SkillProperties with parsed metadata
(skill_dir: Path)
| 65 | |
| 66 | |
| 67 | def read_properties(skill_dir: Path) -> SkillProperties: |
| 68 | """Read skill properties from SKILL.md frontmatter. |
| 69 | |
| 70 | This function parses the frontmatter and returns properties. |
| 71 | It does NOT perform full validation. Use validate() for that. |
| 72 | |
| 73 | Args: |
| 74 | skill_dir: Path to the skill directory |
| 75 | |
| 76 | Returns: |
| 77 | SkillProperties with parsed metadata |
| 78 | |
| 79 | Raises: |
| 80 | ParseError: If SKILL.md is missing or has invalid YAML |
| 81 | ValidationError: If required fields (name, description) are missing |
| 82 | """ |
| 83 | skill_dir = Path(skill_dir) |
| 84 | skill_md = find_skill_md(skill_dir) |
| 85 | |
| 86 | if skill_md is None: |
| 87 | raise ParseError(f"SKILL.md not found in {skill_dir}") |
| 88 | |
| 89 | content = skill_md.read_text() |
| 90 | metadata, _ = parse_frontmatter(content) |
| 91 | |
| 92 | if "name" not in metadata: |
| 93 | raise ValidationError("Missing required field in frontmatter: name") |
| 94 | if "description" not in metadata: |
| 95 | raise ValidationError("Missing required field in frontmatter: description") |
| 96 | |
| 97 | name = metadata["name"] |
| 98 | description = metadata["description"] |
| 99 | |
| 100 | if not isinstance(name, str) or not name.strip(): |
| 101 | raise ValidationError("Field 'name' must be a non-empty string") |
| 102 | if not isinstance(description, str) or not description.strip(): |
| 103 | raise ValidationError("Field 'description' must be a non-empty string") |
| 104 | |
| 105 | return SkillProperties( |
| 106 | name=name.strip(), |
| 107 | description=description.strip(), |
| 108 | license=metadata.get("license"), |
| 109 | compatibility=metadata.get("compatibility"), |
| 110 | allowed_tools=metadata.get("allowed-tools"), |
| 111 | metadata=metadata.get("metadata"), |
| 112 | ) |