// Regenerate skill-reviews/improved/**/SKILL.md from the content collection. // // Source of truth: src/content/reviews/{id}.md. Each file's frontmatter holds // the review metadata (id, author, focus, wins, improve, extras, // description); its body is the Markdown that becomes the SKILL.md file. // This script reconstructs the SKILL.md frontmatter (name + description) and // concatenates it with the body, so the committed output stays byte-identical // to what the legacy catalog produced: // // --- <- SKILL.md frontmatter starts // name: // description: // --- // // # // <- body, as written in the .md file // ... // // Run from the repository root: // // node scripts/build-skill-review.mjs && git diff --exit-code skill-reviews/ // // A non-empty diff means the collection drifted from the committed output; // regenerate after every entry edit. import { mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const here = dirname(fileURLToPath(import.meta.url)); const root = dirname(here); const REVIEWS_DIR = join(root, 'src', 'content', 'reviews'); const OUTPUT_DIR = join(root, 'skill-reviews', 'improved'); const parseFrontmatter = (text) => { // Strict shape: starts with `---\n`, ends at the next `---\n`, then body. if (!text.startsWith('---\n')) throw new Error('missing leading ---'); const end = text.indexOf('\n---\n', 4); if (end === -1) throw new Error('missing closing ---'); const yaml = text.slice(4, end); const body = text.slice(end + 5); const id = yaml.match(/^id:\s*"?([^"\n]+)"?\s*$/m)?.[1]; const name = yaml.match(/^name:\s*"?([^"\n]+)"?\s*$/m)?.[1]; const description = yaml.match(/^description:\s*"?((?:\\.|[^"\\])*)"?\s*$/m)?.[1]; if (!id) throw new Error('frontmatter missing id'); if (!name) throw new Error('frontmatter missing name'); if (!description) throw new Error('frontmatter missing description'); return { id, name, description, body }; }; const files = readdirSync(REVIEWS_DIR) .filter((f) => f.endsWith('.md')) .sort(); let count = 0; for (const file of files) { const source = readFileSync(join(REVIEWS_DIR, file), 'utf8'); const { id, name, description, body } = parseFrontmatter(source); // The body in the .md file starts with `# \n\n` then the Markdown // content; strip a single leading newline if present so the reconstructed // SKILL.md matches the legacy `skill(...)` output exactly. const stripped = body.startsWith('\n') ? body.slice(1) : body; const output = `---\nname: ${name}\ndescription: ${description}\n---\n\n${stripped.trim()}\n`; const outPath = join(OUTPUT_DIR, id, 'SKILL.md'); mkdirSync(dirname(outPath), { recursive: true }); writeFileSync(outPath, output); count += 1; } console.log(`wrote ${count} improved skill drafts`);