| 13 | ZIP_DIR = Path("skills-zip") |
| 14 | |
| 15 | def parse_skill(content: str, file_path: Path) -> dict: |
| 16 | # Normalizar saltos de línea |
| 17 | content = content.replace('\r\n', '\n').replace('\r', '\n') |
| 18 | lines = content.split('\n') |
| 19 | |
| 20 | meta = { |
| 21 | 'name': None, # Será igual a folder |
| 22 | 'folder': None, |
| 23 | 'source': None, |
| 24 | 'description': [], |
| 25 | 'triggers': [], |
| 26 | 'body': [] |
| 27 | } |
| 28 | |
| 29 | state = 'INIT' |
| 30 | |
| 31 | for line in lines: |
| 32 | stripped = line.strip() |
| 33 | if not stripped: |
| 34 | if state in ('DESCRIPTION', 'BODY'): |
| 35 | # Preservar saltos de línea en descripción y cuerpo |
| 36 | if state == 'DESCRIPTION' and meta['description']: |
| 37 | meta['description'].append('') |
| 38 | elif state == 'BODY': |
| 39 | meta['body'].append('') |
| 40 | continue |
| 41 | |
| 42 | # Detectar headers Markdown (## Section) |
| 43 | header_match = re.match(r'^##\s+(.+)', stripped, re.I) |
| 44 | if header_match: |
| 45 | section = header_match.group(1).strip().lower() |
| 46 | if section == 'metadata': |
| 47 | state = 'METADATA' |
| 48 | elif section == 'description': |
| 49 | state = 'DESCRIPTION' |
| 50 | elif section == 'trigger phrases': |
| 51 | state = 'TRIGGER' |
| 52 | elif section == 'instructions for claude': |
| 53 | state = 'BODY' |
| 54 | meta['body'].append('# Instructions for Claude') |
| 55 | elif section == 'full methodology': |
| 56 | state = 'BODY' |
| 57 | meta['body'].append('## Full Methodology') |
| 58 | continue |
| 59 | |
| 60 | # Procesar según estado |
| 61 | if state == 'METADATA' and stripped.startswith('- **'): |
| 62 | # Formato: - **Field Name**: value |
| 63 | match = re.match(r'-\s*\*\*([^*]+)\*\*\s*:\s*(.+)', stripped) |
| 64 | if match: |
| 65 | key = match.group(1).strip().lower().replace(' ', '_') |
| 66 | val = match.group(2).strip() |
| 67 | if key == 'skill_name': |
| 68 | pass # No usamos este para name |
| 69 | elif key == 'folder': |
| 70 | meta['folder'] = val |
| 71 | # name = folder (según requerimiento) |
| 72 | meta['name'] = re.sub(r'[^a-z0-9]+', '-', val.lower()).strip('-') |