{"version":3,"sources":["../src/escape.ts","../src/pages.ts","../src/validate.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Markdown-escaping helper for `llms.txt` link text.\n */\n\n/**\n * Escape the Markdown link characters `\\ [ ] ( )` in link *text* (titles and\n * notes) so a value like `A [beta] (x)` cannot break the surrounding\n * `[...](...)`. Escaping is idempotent-safe only for these characters and is\n * intended for the human-readable text portions — not for URLs.\n *\n * Opt-in: pass `{ escape: true }` to {@link llmsTxt} / the builders, or call\n * this directly. The default (unescaped) output is unchanged.\n *\n * @example\n * escapeLlmsText(\"Guide [v2] (beta)\"); // \"Guide \\\\[v2\\\\] \\\\(beta\\\\)\"\n */\nexport function escapeLlmsText(s: string): string {\n  return s.replace(/([\\\\\\[\\]()])/g, \"\\\\$1\");\n}\n\n/**\n * Reverse {@link escapeLlmsText} — turn `\\[`, `\\]`, `\\(`, `\\)` and `\\\\` back\n * into the literal character. {@link parseLlmsTxt} needs this to read a link\n * whose title was escaped on the way out; without it the writer and the parser\n * disagree about their own format.\n */\nexport function unescapeLlmsText(s: string): string {\n  return s.replace(/\\\\([\\\\[\\]()])/g, \"$1\");\n}\n","/**\n * Build `llms.txt` and `llms-full.txt` from a set of pages (title + url +\n * full Markdown content) — e.g. your rendered routes or docs.\n *\n * Zero dependencies · isomorphic.\n */\n\nimport type { LlmsDoc, LlmsLink, LlmsFullDoc, LlmsTxtOptions } from \"./index\";\nimport { llmsTxt, llmsFullTxt } from \"./index\";\n\n/** A single page: a link in `llms.txt` and a full section in `llms-full.txt`. */\nexport interface LlmsPage {\n  title: string;\n  /** Canonical URL. Pages without a `url` are inlined into `llms-full.txt` only. */\n  url?: string;\n  /** Full Markdown content for `llms-full.txt`. */\n  content: string;\n  /** Short note shown after the link in `llms.txt`. */\n  notes?: string;\n  /** Section heading to group under in `llms.txt`. Defaults to `defaultSection`. */\n  section?: string;\n  /** Route the page into the special `## Optional` block (links an LLM may skip). */\n  optional?: boolean;\n}\n\n/** Meta / options for the page-based builders. */\nexport interface PagesToLlmsMeta extends LlmsTxtOptions {\n  title: string;\n  summary?: string;\n  details?: string;\n  /** Section name for pages with no `section`. Default `\"Docs\"`. */\n  defaultSection?: string;\n}\n\n/** Group pages into an {@link LlmsDoc} (links grouped by section + Optional block). */\nfunction pagesToDoc(pages: LlmsPage[], meta: PagesToLlmsMeta): LlmsDoc {\n  const bySection = new Map<string, LlmsLink[]>();\n  const order: string[] = [];\n  const optional: LlmsLink[] = [];\n  for (const p of pages) {\n    if (!p.url) continue; // no URL → full-text only, not a link\n    const link: LlmsLink = { title: p.title, url: p.url, notes: p.notes };\n    if (p.optional) {\n      optional.push(link);\n      continue;\n    }\n    const section = p.section ?? meta.defaultSection ?? \"Docs\";\n    if (!bySection.has(section)) {\n      bySection.set(section, []);\n      order.push(section);\n    }\n    bySection.get(section)!.push(link);\n  }\n  const doc: LlmsDoc = {\n    title: meta.title,\n    summary: meta.summary,\n    details: meta.details,\n    sections: order.map((title) => ({ title, links: bySection.get(title)! })),\n  };\n  if (optional.length) doc.optional = optional;\n  return doc;\n}\n\n/**\n * Build the compact `llms.txt` from pages — a link per page (with `url`),\n * grouped by `section` (first-seen order preserved), and `optional` pages under\n * the `## Optional` block.\n */\nexport function llmsTxtFromPages(pages: LlmsPage[], meta: PagesToLlmsMeta): string {\n  return llmsTxt(pagesToDoc(pages, meta), { sort: meta.sort, escape: meta.escape });\n}\n\n/**\n * Build the expanded `llms-full.txt` from pages — every page's full Markdown\n * `content` inlined, in the given order, each with a `Source:` line when a `url`\n * is present.\n */\nexport function llmsFullTxtFromPages(\n  pages: LlmsPage[],\n  meta: { title: string; summary?: string },\n): string {\n  const doc: LlmsFullDoc = {\n    title: meta.title,\n    summary: meta.summary,\n    sections: pages.map((p) => ({ title: p.title, content: p.content, url: p.url })),\n  };\n  return llmsFullTxt(doc);\n}\n\n/**\n * Build BOTH files from one page list in a single call. Serve `txt` at\n * `/llms.txt` and `full` at `/llms-full.txt`.\n * @example\n * const { txt, full } = llmsFromPages(pages, { title: \"Acme\" });\n */\nexport function llmsFromPages(\n  pages: LlmsPage[],\n  meta: PagesToLlmsMeta,\n): { txt: string; full: string } {\n  return {\n    txt: llmsTxtFromPages(pages, meta),\n    full: llmsFullTxtFromPages(pages, { title: meta.title, summary: meta.summary }),\n  };\n}\n","/**\n * Validate an `llms.txt` string against the llmstxt.org shape.\n *\n * Zero dependencies · isomorphic.\n */\n\n/** A single validation finding. */\nexport interface LlmsIssue {\n  level: \"error\" | \"warning\";\n  message: string;\n  /** 1-based line number, when the issue is tied to a specific line. */\n  line?: number;\n}\n\n/** Result of {@link validateLlmsTxt}. `valid` is false when there is any error. */\nexport interface LlmsValidation {\n  valid: boolean;\n  issues: LlmsIssue[];\n}\n\nconst LINK_RE = /^-\\s*\\[([^\\]]+)\\]\\(([^)]+)\\)\\s*(?::\\s*(.*))?$/;\n\n/**\n * Check that a string is a well-formed `llms.txt`: it must have the required H1\n * title, and a one-line summary blockquote is recommended. Reports malformed\n * link lines, a missing/duplicate/mis-placed H1, and a missing summary.\n *\n * @returns `{ valid, issues }` — `valid` is true when there are no `error`s\n * (warnings do not fail validation).\n */\nexport function validateLlmsTxt(txt: string): LlmsValidation {\n  const issues: LlmsIssue[] = [];\n  const lines = txt.split(/\\r?\\n/);\n\n  const h1Lines: number[] = [];\n  let firstContentIdx = -1;\n  let hasSummary = false;\n  let summaryBeforeH1 = false;\n\n  lines.forEach((raw, i) => {\n    const line = raw.trim();\n    if (!line) return;\n    if (firstContentIdx === -1) firstContentIdx = i;\n    if (/^#\\s+\\S/.test(line)) {\n      h1Lines.push(i);\n    } else if (line.startsWith(\"> \")) {\n      hasSummary = true;\n      if (h1Lines.length === 0) summaryBeforeH1 = true;\n    } else if (/^-\\s*\\[/.test(line) && !LINK_RE.test(line)) {\n      issues.push({ level: \"warning\", message: \"Malformed link line.\", line: i + 1 });\n    }\n  });\n\n  if (h1Lines.length === 0) {\n    issues.push({\n      level: \"error\",\n      message: \"Missing required H1 title (a line starting with `# `).\",\n    });\n  } else {\n    if (h1Lines.length > 1) {\n      issues.push({\n        level: \"warning\",\n        message: `Found ${h1Lines.length} H1 titles; llms.txt should have exactly one.`,\n        line: h1Lines[1]! + 1,\n      });\n    }\n    if (firstContentIdx !== -1 && h1Lines[0] !== firstContentIdx) {\n      issues.push({\n        level: \"warning\",\n        message: \"The H1 title should be the first line of the file.\",\n        line: firstContentIdx + 1,\n      });\n    }\n  }\n\n  if (!hasSummary) {\n    issues.push({\n      level: \"warning\",\n      message: \"No summary blockquote (`> …`) found; a one-line summary is recommended.\",\n    });\n  } else if (summaryBeforeH1) {\n    issues.push({\n      level: \"warning\",\n      message: \"The summary blockquote appears before the H1 title.\",\n    });\n  }\n\n  return { valid: !issues.some((x) => x.level === \"error\"), issues };\n}\n","/**\n * @lacspace/llms-txt\n * Generate and parse llms.txt and llms-full.txt (the llmstxt.org standard).\n *\n * llms.txt is a Markdown file at your site root that gives LLMs a curated map of\n * your most useful content; llms-full.txt inlines the full text so a model can\n * read everything in one request.\n *\n * Zero dependencies · isomorphic · fully typed.\n */\n\nimport { escapeLlmsText, unescapeLlmsText } from \"./escape\";\n\nexport interface LlmsLink {\n  title: string;\n  url: string;\n  /** Short note shown after the link. */\n  notes?: string;\n}\n\nexport interface LlmsSection {\n  title: string;\n  links: LlmsLink[];\n}\n\nexport interface LlmsDoc {\n  /** The site / project name (rendered as the H1). */\n  title: string;\n  /** One-line summary (rendered as a blockquote). */\n  summary?: string;\n  /** Free-form Markdown shown before the sections. */\n  details?: string;\n  sections: LlmsSection[];\n  /**\n   * The special `## Optional` block (per the spec, links an LLM may skip).\n   * Rendered last, after {@link sections}. Round-trips through\n   * {@link parseLlmsTxt}. Omit or leave empty to emit nothing.\n   */\n  optional?: LlmsLink[];\n}\n\n/**\n * How to order the links inside each section.\n * - `\"title\"` / `\"url\"` — ascending by that field\n * - `\"title-desc\"` / `\"url-desc\"` — descending\n * - a comparator — full control\n * Sections keep their array order; only the links within a section are sorted.\n */\nexport type LinkSort =\n  | \"title\"\n  | \"url\"\n  | \"title-desc\"\n  | \"url-desc\"\n  | ((a: LlmsLink, b: LlmsLink) => number);\n\n/** Options accepted by the rendering helpers. */\nexport interface LlmsTxtOptions {\n  /** Order links within each section. Omit to keep the given order. */\n  sort?: LinkSort;\n  /**\n   * Escape the Markdown link characters `\\ [ ] ( )` in link titles/notes so a\n   * title like `A [beta]` cannot break the surrounding `[...](...)`.\n   *\n   * **On by default.** It used to be opt-in, which meant the default output was\n   * broken for an ordinary title: `- [Guide [v2]](/g)` is not a parseable\n   * Markdown link, and parseLlmsTxt() read it as NO LINK AT ALL — the page\n   * silently vanished from the file an LLM reads. Escaping only ever touches\n   * `\\ [ ] ( )`, so titles without them are byte-for-byte unchanged.\n   *\n   * Set `false` for the old behaviour. See {@link escapeLlmsText}.\n   * @default true\n   */\n  escape?: boolean;\n}\n\n/** Quote every line, so a multi-line summary stays inside the blockquote. */\nfunction blockquote(text: string): string[] {\n  return text.split(\"\\n\").map((line) => `> ${line}`);\n}\n\nfunction sortLinks(links: LlmsLink[], sort?: LinkSort): LlmsLink[] {\n  if (!sort) return links;\n  const copy = links.slice();\n  if (typeof sort === \"function\") return copy.sort(sort);\n  const [field, dir] = sort.split(\"-\") as [\"title\" | \"url\", \"desc\" | undefined];\n  const factor = dir === \"desc\" ? -1 : 1;\n  return copy.sort((a, b) => factor * a[field].localeCompare(b[field]));\n}\n\n/**\n * Render an `llms.txt` document.\n * @param opts optional rendering options (e.g. `{ sort: \"title\" }`).\n * @example\n * llmsTxt({\n *   title: \"Lacspace\",\n *   summary: \"Open-source TypeScript packages and products.\",\n *   sections: [{ title: \"Docs\", links: [{ title: \"Packages\", url: \"https://lacspace.com/packages\" }] }],\n * });\n */\nexport function llmsTxt(doc: LlmsDoc, opts: LlmsTxtOptions = {}): string {\n  const esc = opts.escape === false ? (s: string) => s : escapeLlmsText;\n  const renderLink = (l: LlmsLink) =>\n    `- [${esc(l.title)}](${l.url})${l.notes ? `: ${esc(l.notes)}` : \"\"}`;\n  const out: string[] = [`# ${doc.title}`];\n  // Every line needs its own \"> \", or a multi-line summary leaves the\n  // blockquote after line one and parseLlmsTxt() reads the rest as `details`.\n  if (doc.summary) out.push(\"\", ...blockquote(doc.summary));\n  if (doc.details) out.push(\"\", doc.details.trim());\n  for (const section of doc.sections) {\n    out.push(\"\", `## ${section.title}`, \"\");\n    for (const l of sortLinks(section.links, opts.sort)) {\n      out.push(renderLink(l));\n    }\n  }\n  if (doc.optional && doc.optional.length) {\n    out.push(\"\", \"## Optional\", \"\");\n    for (const l of sortLinks(doc.optional, opts.sort)) {\n      out.push(renderLink(l));\n    }\n  }\n  return out.join(\"\\n\") + \"\\n\";\n}\n\nexport interface LlmsFullSection {\n  title: string;\n  /** Full Markdown content for this section. */\n  content: string;\n  /** Optional source URL, added as a heading link. */\n  url?: string;\n}\n\nexport interface LlmsFullDoc {\n  title: string;\n  summary?: string;\n  sections: LlmsFullSection[];\n}\n\n/** Render an `llms-full.txt` document with the full content inlined. */\nexport function llmsFullTxt(doc: LlmsFullDoc): string {\n  const out: string[] = [`# ${doc.title}`];\n  // Every line needs its own \"> \", or a multi-line summary leaves the\n  // blockquote after line one and parseLlmsTxt() reads the rest as `details`.\n  if (doc.summary) out.push(\"\", ...blockquote(doc.summary));\n  for (const section of doc.sections) {\n    out.push(\"\", \"---\", \"\", `## ${section.title}`);\n    if (section.url) out.push(\"\", `Source: ${section.url}`);\n    out.push(\"\", section.content.trim());\n  }\n  return out.join(\"\\n\") + \"\\n\";\n}\n\n/** Parse an `llms.txt` string back into a structured document. */\nexport function parseLlmsTxt(txt: string): LlmsDoc {\n  const lines = txt.split(/\\r?\\n/);\n  const doc: LlmsDoc = { title: \"\", sections: [] };\n  let current: LlmsSection | null = null;\n  const detailBuf: string[] = [];\n  // `(?:[^\\]\\\\]|\\\\.)*` lets an escaped \\] sit inside the title. The old\n  // `[^\\]]+` stopped at the first ], so an escaped title matched nothing and\n  // the link was silently dropped from the parsed document.\n  const linkRe = /^-\\s*\\[((?:[^\\]\\\\]|\\\\.)*)\\]\\(([^)]+)\\)\\s*(?::\\s*(.*))?$/;\n\n  for (const raw of lines) {\n    const line = raw.trimEnd();\n    if (line.startsWith(\"# \")) {\n      doc.title = line.slice(2).trim();\n    } else if (line.startsWith(\"> \")) {\n      // Join with a newline, not a space, so a multi-line summary survives\n      // the round trip exactly as written.\n      doc.summary = (doc.summary ? doc.summary + \"\\n\" : \"\") + line.slice(2).trim();\n    } else if (line.startsWith(\"## \")) {\n      const heading = line.slice(3).trim();\n      if (heading === \"Optional\") {\n        // The special `## Optional` block round-trips into `doc.optional`.\n        const links: LlmsLink[] = [];\n        doc.optional = links;\n        current = { title: heading, links };\n      } else {\n        current = { title: heading, links: [] };\n        doc.sections.push(current);\n      }\n    } else if (current && linkRe.test(line)) {\n      const m = line.match(linkRe)!;\n      current.links.push({\n        title: unescapeLlmsText(m[1]!),\n        url: m[2]!,\n        notes: m[3]?.trim() ? unescapeLlmsText(m[3].trim()) : undefined,\n      });\n    } else if (!current && line && !line.startsWith(\"#\")) {\n      detailBuf.push(line);\n    }\n  }\n  const details = detailBuf.join(\"\\n\").trim();\n  if (details) doc.details = details;\n  return doc;\n}\n\n/* ------------------------------ from sitemap ------------------------------ */\n\n/** A sitemap-ish entry — accepts `url` or `loc`, plus optional title/section. */\nexport interface SitemapEntryLike {\n  url?: string;\n  loc?: string;\n  title?: string;\n  section?: string;\n}\n\nfunction titleFromUrl(url: string): string {\n  let path: string;\n  try {\n    path = new URL(url).pathname;\n  } catch {\n    path = url;\n  }\n  const seg = path.split(\"/\").filter(Boolean).pop();\n  if (!seg) return \"Home\";\n  let decoded: string;\n  try {\n    decoded = decodeURIComponent(seg);\n  } catch {\n    // Malformed percent-encoding — fall back to the raw segment instead of throwing.\n    decoded = seg;\n  }\n  return decoded.replace(/\\.[a-z]+$/i, \"\").replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** First path segment of a URL, title-cased, for auto-sectioning (\"/docs/x\" → \"Docs\"). */\nfunction sectionFromUrl(url: string): string {\n  let path: string;\n  try {\n    path = new URL(url).pathname;\n  } catch {\n    path = url;\n  }\n  const seg = path.split(\"/\").filter(Boolean)[0];\n  if (!seg) return \"Home\";\n  let decoded: string;\n  try {\n    decoded = decodeURIComponent(seg);\n  } catch {\n    decoded = seg;\n  }\n  return decoded.replace(/\\.[a-z]+$/i, \"\").replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\n/** Pull `<loc>` values out of a sitemap (or sitemap-index) XML string. */\nfunction parseSitemapXml(xml: string): SitemapEntryLike[] {\n  const out: SitemapEntryLike[] = [];\n  const re = /<loc>\\s*([\\s\\S]*?)\\s*<\\/loc>/gi;\n  let m: RegExpExecArray | null;\n  while ((m = re.exec(xml))) {\n    const loc = m[1]!\n      .trim()\n      .replace(/&amp;/g, \"&\")\n      .replace(/&lt;/g, \"<\")\n      .replace(/&gt;/g, \">\")\n      .replace(/&quot;/g, '\"')\n      .replace(/&apos;/g, \"'\");\n    if (loc) out.push({ loc });\n  }\n  return out;\n}\n\n/** Meta / options for {@link llmsTxtFromSitemap}. */\nexport interface SitemapToLlmsMeta extends LlmsTxtOptions {\n  title: string;\n  summary?: string;\n  details?: string;\n  /** Fallback section name when an entry has none. Default `\"Pages\"`. */\n  defaultSection?: string;\n  /**\n   * When an entry has no explicit `section`, derive one from the first path\n   * segment (\"/docs/x\" → \"Docs\") instead of using {@link defaultSection}.\n   */\n  sectionFromPath?: boolean;\n}\n\n/**\n * Build an `llms.txt` from sitemap entries — accepts either an **array** of\n * `{ loc | url, title?, section? }` entries or a raw **sitemap XML string**.\n * Groups by `section` (or, with `sectionFromPath`, by the first path segment),\n * derives titles from the URL when not given, and de-duplicates repeated URLs.\n * Pairs with `@lacspace/sitemap`. The original array signature is unchanged.\n */\nexport function llmsTxtFromSitemap(\n  entries: SitemapEntryLike[] | string,\n  meta: SitemapToLlmsMeta,\n): string {\n  const list = typeof entries === \"string\" ? parseSitemapXml(entries) : entries;\n  const bySection = new Map<string, LlmsLink[]>();\n  const order: string[] = [];\n  const seen = new Set<string>();\n  for (const e of list) {\n    const url = e.url ?? e.loc;\n    if (!url || seen.has(url)) continue;\n    seen.add(url);\n    const section =\n      e.section ?? (meta.sectionFromPath ? sectionFromUrl(url) : meta.defaultSection ?? \"Pages\");\n    if (!bySection.has(section)) {\n      bySection.set(section, []);\n      order.push(section);\n    }\n    bySection.get(section)!.push({ title: e.title ?? titleFromUrl(url), url });\n  }\n  const doc: LlmsDoc = {\n    title: meta.title,\n    summary: meta.summary,\n    details: meta.details,\n    sections: order.map((title) => ({ title, links: bySection.get(title)! })),\n  };\n  return llmsTxt(doc, { sort: meta.sort });\n}\n\n/* ------------------------------ from routes ------------------------------ */\n\n/** A single route/page entry for {@link llmsTxtFromRoutes}. */\nexport interface LlmsRoute {\n  title: string;\n  url: string;\n  notes?: string;\n  /** Section heading to group under. Defaults to {@link RoutesToLlmsMeta.defaultSection}. */\n  section?: string;\n}\n\n/** Meta / options for {@link llmsTxtFromRoutes}. */\nexport interface RoutesToLlmsMeta extends LlmsTxtOptions {\n  title: string;\n  summary?: string;\n  details?: string;\n  /** Section name for routes with no `section`. Default `\"Docs\"`. */\n  defaultSection?: string;\n}\n\n/**\n * Build an `llms.txt` from a flat list of route entries, grouping by `section`\n * (first-seen order preserved). Titles and notes are used verbatim.\n * @example\n * llmsTxtFromRoutes(\n *   [\n *     { title: \"Home\", url: \"https://acme.com/\", section: \"Start\" },\n *     { title: \"API\", url: \"https://acme.com/api\", notes: \"reference\", section: \"Docs\" },\n *   ],\n *   { title: \"Acme\", summary: \"Acme docs\" },\n * );\n */\nexport function llmsTxtFromRoutes(routes: LlmsRoute[], meta: RoutesToLlmsMeta): string {\n  const bySection = new Map<string, LlmsLink[]>();\n  const order: string[] = [];\n  for (const r of routes) {\n    const section = r.section ?? meta.defaultSection ?? \"Docs\";\n    if (!bySection.has(section)) {\n      bySection.set(section, []);\n      order.push(section);\n    }\n    bySection.get(section)!.push({ title: r.title, url: r.url, notes: r.notes });\n  }\n  const doc: LlmsDoc = {\n    title: meta.title,\n    summary: meta.summary,\n    details: meta.details,\n    sections: order.map((title) => ({ title, links: bySection.get(title)! })),\n  };\n  return llmsTxt(doc, { sort: meta.sort });\n}\n\n/* ------------------------------ adapters ------------------------------ */\n\n/** `llms.txt` as a Fetch/edge `Response` (text/plain) for app/llms.txt/route.ts. */\nexport function llmsTxtResponse(doc: LlmsDoc, init: ResponseInit = {}): Response {\n  return new Response(llmsTxt(doc), {\n    ...init,\n    headers: { \"content-type\": \"text/plain; charset=utf-8\", ...(init.headers ?? {}) },\n  });\n}\n\n/** `llms-full.txt` as a Fetch/edge `Response` (text/plain). */\nexport function llmsFullTxtResponse(doc: LlmsFullDoc, init: ResponseInit = {}): Response {\n  return new Response(llmsFullTxt(doc), {\n    ...init,\n    headers: { \"content-type\": \"text/plain; charset=utf-8\", ...(init.headers ?? {}) },\n  });\n}\n\n/* ------------------------------ new in 1.4 ------------------------------ */\n\nexport { escapeLlmsText, unescapeLlmsText } from \"./escape\";\nexport * from \"./pages\";\nexport * from \"./validate\";\n"]}