{"version":3,"file":"parse-frontmatter.mjs","names":[],"sources":["../../../../../../../../ai/src/skills/sources/parse-frontmatter.ts"],"sourcesContent":["/** The parsed front-matter (cheap metadata) plus the stripped body. */\nexport type ParsedFrontmatter = {\n  /** Every `key: value` line from the front-matter block, values quote-stripped. */\n  meta: Record<string, string>;\n  /** Everything after the closing `---`, verbatim (the skill body). */\n  body: string;\n};\n\n/**\n * Parse simple `key: value` YAML front-matter — the only form `SKILL.md`\n * uses (no nested objects, no block arrays). Ported verbatim from the\n * package's `scripts/generate-llms.mjs` `parseFrontmatter()` so the\n * runtime catalog and the docs `llms.txt` index agree byte-for-byte on\n * what a skill's `description` is.\n *\n * When the text has no `---`-delimited front-matter block, returns an\n * empty `meta` and the full text as `body`.\n */\nexport function parseFrontmatter(text: string): ParsedFrontmatter {\n  const match = text.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\n  if (!match) {\n    return { meta: {}, body: text };\n  }\n\n  const meta: Record<string, string> = {};\n\n  for (const line of match[1].split(\"\\n\")) {\n    const colon = line.indexOf(\":\");\n\n    if (colon === -1) {\n      continue;\n    }\n\n    const key = line.slice(0, colon).trim();\n    let value = line.slice(colon + 1).trim();\n\n    if (\n      (value.startsWith(\"'\") && value.endsWith(\"'\")) ||\n      (value.startsWith('\"') && value.endsWith('\"'))\n    ) {\n      value = value.slice(1, -1).replace(/''/g, \"'\").replace(/\\\\\"/g, '\"');\n    }\n\n    meta[key] = value;\n  }\n\n  return { meta, body: match[2] };\n}\n\n/**\n * Split a front-matter `tags:` value into a string array. Accepts a\n * comma-separated inline list (`tags: frontend, react`) — the simple\n * inline form that fits the `key: value` parser. Returns `undefined` when\n * the value is absent or blank so a tagless skill stays `tags: undefined`.\n */\nexport function parseTags(value: string | undefined): string[] | undefined {\n  if (!value) {\n    return undefined;\n  }\n\n  const tags = value\n    .split(\",\")\n    .map((tag) => tag.trim())\n    .filter((tag) => tag.length > 0);\n\n  return tags.length > 0 ? tags : undefined;\n}\n"],"mappings":";;;;;;;;;;;AAkBA,SAAgB,iBAAiB,MAAiC;CAChE,MAAM,QAAQ,KAAK,MAAM,mCAAmC;CAE5D,IAAI,CAAC,OACH,OAAO;EAAE,MAAM,CAAC;EAAG,MAAM;CAAK;CAGhC,MAAM,OAA+B,CAAC;CAEtC,KAAK,MAAM,QAAQ,MAAM,EAAE,CAAC,MAAM,IAAI,GAAG;EACvC,MAAM,QAAQ,KAAK,QAAQ,GAAG;EAE9B,IAAI,UAAU,IACZ;EAGF,MAAM,MAAM,KAAK,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK;EACtC,IAAI,QAAQ,KAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK;EAEvC,IACG,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,IAAG,KAAK,MAAM,SAAS,IAAG,GAE5C,QAAQ,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,QAAQ,OAAO,GAAG,CAAC,CAAC,QAAQ,QAAQ,IAAG;EAGpE,KAAK,OAAO;CACd;CAEA,OAAO;EAAE;EAAM,MAAM,MAAM;CAAG;AAChC;;;;;;;AAQA,SAAgB,UAAU,OAAiD;CACzE,IAAI,CAAC,OACH;CAGF,MAAM,OAAO,MACV,MAAM,GAAG,CAAC,CACV,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CACxB,QAAQ,QAAQ,IAAI,SAAS,CAAC;CAEjC,OAAO,KAAK,SAAS,IAAI,OAAO;AAClC"}