Skip to the content

Capsid menu

llms.mjs

46 lines and 4 functions in DrDustinEdwards/prelum, at commit e389900 on 2026-10-24. This file on GitHub.

Functions

The functions of llms.mjs
FunctionLinesComplexityCoveredCRAPMutation
llmsDocument32 to 426100%WatchCRAP 6No data: mutation testing has not run on this repo yet
llmsLink45 to 512100%OkCRAP 2No data: mutation testing has not run on this repo yet
oneLine47 to 471100%OkCRAP 1No data: mutation testing has not run on this repo yet
<anonymous:48>48 to 481100%OkCRAP 1No data: mutation testing has not run on this repo yet

Imports

It imports no other module of this repo. Imported by index.mjs.

Source

/**
 * @typedef {object} LlmsLink
 * @property {string} title
 * @property {string} url
 * @property {string} [description]
 */

/**
 * @typedef {object} LlmsLinkSection
 * @property {string} heading
 * @property {LlmsLink[]} links
 */

/**
 * @typedef {object} LlmsProseSection
 * @property {string} heading
 * @property {string[]} body paragraphs, kept as written and separated by a blank line
 */

/** @typedef {LlmsLinkSection | LlmsProseSection} LlmsSection */

/**
 * The llms.txt skeleton (llmstxt.org): title, a blockquote summary, optional intro paragraphs, then H2 sections of link lists.
 * A link's title is Markdown link text, so `[` and `]` are escaped; everything else is kept as written, because the titles are
 * prose and the sites' own files carry quotes and ampersands in them. A section with no links is dropped rather than left a
 * bare heading. A prose section (`body` in place of `links`) is its heading, a blank line, then its paragraphs as written, for a
 * file that mixes prose with its lists; one with no paragraphs is dropped the same way.
 *
 * @param {{ title: string, summary: string, intro?: string[], sections: LlmsSection[] }} doc
 * @returns {string}
 */
export function llmsDocument(doc) {
  const blocks = [`# ${doc.title}`, `> ${doc.summary}`, ...(doc.intro ?? [])];
  for (const section of doc.sections) {
    if ("body" in section) {
      if (section.body.length > 0) blocks.push(`## ${section.heading}`, ...section.body);
    } else if (section.links.length > 0) {
      blocks.push(`## ${section.heading}\n${section.links.map(llmsLink).join("\n")}`);
    }
  }
  return `${blocks.join("\n\n")}\n`;
}

/** @param {LlmsLink} link */
export function llmsLink(link) {
  // One line per link: a newline in the title or description would end the list item, and a ")" in the URL would end the link.
  const oneLine = (/** @type {string} */ text) => text.replace(/\s*[\r\n]+\s*/g, " ");
  const title = oneLine(link.title).replace(/[[\]]/g, (bracket) => "\\" + bracket);
  const url = link.url.replace(/\)/g, "%29");
  return `- [${title}](${url})${link.description ? `: ${oneLine(link.description)}` : ""}`;
}