Skills/Python: harden script edge cases and add regression tests (#24277)

* Skill creator: skip self-including .skill output

* Skill creator tests: cover output-dir-inside-skill case

* Skill validator: parse frontmatter robustly across newlines

* Skill validator tests: add CRLF and malformed frontmatter coverage

* Model usage: require positive --days value

* Model usage tests: cover --days validation and filtering

* Nano banana: close input image handles after loading

* Skill validator: keep type hints compatible with older python

* Changelog: credit @vincentkoc for Python skills hardening
This commit is contained in:
Vincent Koc
2026-02-23 02:34:23 -05:00
committed by GitHub
parent 36400df086
commit c8a62e1cea
8 changed files with 137 additions and 11 deletions

View File

@@ -6,12 +6,23 @@ Quick validation script for skills - minimal version
import re
import sys
from pathlib import Path
from typing import Optional
import yaml
MAX_SKILL_NAME_LENGTH = 64
def _extract_frontmatter(content: str) -> Optional[str]:
lines = content.splitlines()
if not lines or lines[0].strip() != "---":
return None
for i in range(1, len(lines)):
if lines[i].strip() == "---":
return "\n".join(lines[1:i])
return None
def validate_skill(skill_path):
"""Basic validation of a skill"""
skill_path = Path(skill_path)
@@ -20,16 +31,15 @@ def validate_skill(skill_path):
if not skill_md.exists():
return False, "SKILL.md not found"
content = skill_md.read_text()
if not content.startswith("---"):
return False, "No YAML frontmatter found"
try:
content = skill_md.read_text(encoding="utf-8")
except OSError as e:
return False, f"Could not read SKILL.md: {e}"
match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
if not match:
frontmatter_text = _extract_frontmatter(content)
if frontmatter_text is None:
return False, "Invalid frontmatter format"
frontmatter_text = match.group(1)
try:
frontmatter = yaml.safe_load(frontmatter_text)
if not isinstance(frontmatter, dict):