Skip to main content

scripts-repair-skill-frontmatter-v2

#!/usr/bin/env python3 """ Repair corrupted skill frontmatter v2 - handles misplaced tag items.

The issue: Tag list items appear after cef_ fields at wrong indentation.

Usage: python3 scripts/repair-skill-frontmatter-v2.py [--dry-run] """

import argparse import re import sys from pathlib import Path

def repair_skill_file(skill_path: Path, dry_run: bool = False) -> bool: """Repair a single skill file.""" content = skill_path.read_text()

# Check if file has cef_track
if 'cef_track:' not in content:
return False

# Split into frontmatter and body
match = re.match(r'^(---\s*\n)(.*?)(\n---\s*\n)', content, re.DOTALL)
if not match:
return False

separator = match.group(1)
frontmatter = match.group(2)
body = content[match.end():]

# Check for corruption pattern: tag items after cef_ fields
# Pattern: cef_secondary: [...] followed by unindented list items
corruption_pattern = r'(cef_secondary: \[[^\]]*\]\n)(- \w+)'

if not re.search(corruption_pattern, frontmatter):
# Already repaired or no corruption
return False

# Parse the frontmatter line by line
lines = frontmatter.split('\n')

# Find and extract misplaced tag items
tag_items = []
other_lines = []
i = 0

while i < len(lines):
line = lines[i]
stripped = line.strip()

# Check for unindented list items after cef fields (these are misplaced tags)
if stripped.startswith('- ') and not line.startswith(' '):
# This is a misplaced tag item
tag_items.append(' ' + stripped) # Add proper indentation
i += 1
continue

other_lines.append(line)
i += 1

# Now rebuild with tags in correct location
result_lines = []
tags_inserted = False

for line in other_lines:
result_lines.append(line)

# Insert tag items right after tags: line
if line.strip() == 'tags:' and tag_items and not tags_inserted:
for tag in tag_items:
result_lines.append(tag)
tags_inserted = True

# If tags: wasn't found, add it before cef fields
if not tags_inserted and tag_items:
new_result = []
for line in result_lines:
if line.strip().startswith('cef_') and not tags_inserted:
new_result.append('tags:')
for tag in tag_items:
new_result.append(tag)
new_result.append('') # Empty line
tags_inserted = True
new_result.append(line)
result_lines = new_result

new_frontmatter = '\n'.join(result_lines)
new_content = separator + new_frontmatter + '\n---\n' + body

if dry_run:
print(f"Would repair: {skill_path}")
return True

skill_path.write_text(new_content)
print(f"✅ Repaired: {skill_path}")
return True

def main(): parser = argparse.ArgumentParser(description="Repair corrupted skill frontmatter v2") parser.add_argument("--dry-run", action="store_true", help="Preview changes without applying") args = parser.parse_args()

skills_dir = Path("skills")
skill_files = list(skills_dir.glob("*/SKILL.md"))

print(f"Checking {len(skill_files)} skill files...")
print(f"Mode: {'DRY RUN' if args.dry_run else 'LIVE'}")
print()

repaired = 0
checked = 0

for skill_path in skill_files:
checked += 1
if repair_skill_file(skill_path, args.dry_run):
repaired += 1

print()
print(f"Checked: {checked} files")
print(f"Repaired: {repaired} files")

if args.dry_run:
print("\nRun without --dry-run to apply repairs")

return 0

if name == "main": sys.exit(main())