Update skill-creator and make scripts executable (#350)

- Add `compatibility` optional field to SKILL.md frontmatter spec
- Add validation for `compatibility` field in quick_validate.py
- Rename "hyphen-case" to "kebab-case" terminology in init_skill.py
  and quick_validate.py
- Update max skill name length from 40 to 64 characters
- Make scripts executable (chmod +x) for accept_changes.py,
  comment.py, extract_form_structure.py, add_slide.py, thumbnail.py,
  and recalc.py

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Keith Lazuka
2026-02-06 16:19:32 -05:00
committed by GitHub
parent a5bcdd7e58
commit 1ed29a03dc
9 changed files with 16 additions and 7 deletions

0
skills/docx/scripts/accept_changes.py Normal file → Executable file
View File

0
skills/docx/scripts/comment.py Normal file → Executable file
View File

0
skills/pdf/scripts/extract_form_structure.py Normal file → Executable file
View File

0
skills/pptx/scripts/add_slide.py Normal file → Executable file
View File

0
skills/pptx/scripts/thumbnail.py Normal file → Executable file
View File

View File

@@ -53,7 +53,8 @@ skill-name/
├── SKILL.md (required)
│ ├── YAML frontmatter metadata (required)
│ │ ├── name: (required)
│ │ ── description: (required)
│ │ ── description: (required)
│ │ └── compatibility: (optional, rarely needed)
│ └── Markdown instructions (required)
└── Bundled Resources (optional)
├── scripts/ - Executable code (Python/Bash/etc.)
@@ -65,7 +66,7 @@ skill-name/
Every SKILL.md consists of:
- **Frontmatter** (YAML): Contains `name` and `description` fields. These are the only fields that Claude reads to determine when the skill gets used, thus it is very important to be clear and comprehensive in describing what the skill is, and when it should be used.
- **Frontmatter** (YAML): Contains `name` and `description` fields (required), plus optional fields like `license`, `metadata`, and `compatibility`. Only `name` and `description` are read by Claude to determine when the skill triggers, so be clear and comprehensive about what the skill is and when it should be used. The `compatibility` field is for noting environment requirements (target product, system packages, etc.) but most skills don't need it.
- **Body** (Markdown): Instructions and guidance for using the skill. Only loaded AFTER the skill triggers (if at all).
#### Bundled Resources (optional)

View File

@@ -274,9 +274,9 @@ def main():
if len(sys.argv) < 4 or sys.argv[2] != '--path':
print("Usage: init_skill.py <skill-name> --path <path>")
print("\nSkill name requirements:")
print(" - Hyphen-case identifier (e.g., 'data-analyzer')")
print(" - Kebab-case identifier (e.g., 'my-data-analyzer')")
print(" - Lowercase letters, digits, and hyphens only")
print(" - Max 40 characters")
print(" - Max 64 characters")
print(" - Must match directory name exactly")
print("\nExamples:")
print(" init_skill.py my-new-skill --path skills/public")

View File

@@ -39,7 +39,7 @@ def validate_skill(skill_path):
return False, f"Invalid YAML in frontmatter: {e}"
# Define allowed properties
ALLOWED_PROPERTIES = {'name', 'description', 'license', 'allowed-tools', 'metadata'}
ALLOWED_PROPERTIES = {'name', 'description', 'license', 'allowed-tools', 'metadata', 'compatibility'}
# Check for unexpected properties (excluding nested keys under metadata)
unexpected_keys = set(frontmatter.keys()) - ALLOWED_PROPERTIES
@@ -61,9 +61,9 @@ def validate_skill(skill_path):
return False, f"Name must be a string, got {type(name).__name__}"
name = name.strip()
if name:
# Check naming convention (hyphen-case: lowercase with hyphens)
# Check naming convention (kebab-case: lowercase with hyphens)
if not re.match(r'^[a-z0-9-]+$', name):
return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)"
return False, f"Name '{name}' should be kebab-case (lowercase letters, digits, and hyphens only)"
if name.startswith('-') or name.endswith('-') or '--' in name:
return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens"
# Check name length (max 64 characters per spec)
@@ -83,6 +83,14 @@ def validate_skill(skill_path):
if len(description) > 1024:
return False, f"Description is too long ({len(description)} characters). Maximum is 1024 characters."
# Validate compatibility field if present (optional)
compatibility = frontmatter.get('compatibility', '')
if compatibility:
if not isinstance(compatibility, str):
return False, f"Compatibility must be a string, got {type(compatibility).__name__}"
if len(compatibility) > 500:
return False, f"Compatibility is too long ({len(compatibility)} characters). Maximum is 500 characters."
return True, "Skill is valid!"
if __name__ == "__main__":

0
skills/xlsx/scripts/recalc.py Normal file → Executable file
View File