export function externalSkillName(skillDir: string, frontmatterName?: string): string { if (skillDir === '.' || skillDir === '') return 'gstack'; const baseName = frontmatterName && frontmatterName !== skillDir ? frontmatterName : skillDir; if (baseName.startsWith('gstack-')) return baseName; return `gstack-${baseName}`; } export function extractNameAndDescription(content: string): { name: string; description: string } { const fmStart = content.indexOf('---\n'); if (fmStart !== 0) return { name: '', description: '' }; const fmEnd = content.indexOf('\n---', fmStart + 4); if (fmEnd === -1) return { name: '', description: '' }; const frontmatter = content.slice(fmStart + 4, fmEnd); const nameMatch = frontmatter.match(/^name:\s*(.+)$/m); const name = nameMatch ? nameMatch[1].trim() : ''; let description = ''; const lines = frontmatter.split('\n'); let inDescription = false; const descLines: string[] = []; for (const line of lines) { if (line.match(/^description:\s*\|?\s*$/)) { inDescription = true; continue; } if (line.match(/^description:\s*\S/)) { description = line.replace(/^description:\s*/, '').trim(); break; } if (inDescription) { if (line === '' || line.match(/^\s/)) { descLines.push(line.replace(/^ /, '')); } else { break; } } } if (descLines.length > 0) description = descLines.join('\n').trim(); return { name, description }; }