@lacspace/llms-txt 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -94,6 +94,17 @@ const doc = parseLlmsTxt(existing); // { title, summary, details, sections: [{ t
94
94
  | [`@lacspace/rss`](https://www.npmjs.com/package/@lacspace/rss) | RSS / Atom / JSON feeds |
95
95
  | [`@lacspace/slugify`](https://www.npmjs.com/package/@lacspace/slugify) | SEO URL slugs |
96
96
 
97
+ ## New in 1.1 — Response helpers
98
+
99
+ ```ts
100
+ import { llmsTxtResponse, llmsFullTxtResponse } from "@lacspace/llms-txt";
101
+
102
+ // app/llms.txt/route.ts — served as text/plain
103
+ export function GET() {
104
+ return llmsTxtResponse({ title: "Lacspace", summary: "…", sections });
105
+ }
106
+ ```
107
+
97
108
  ## Licensing
98
109
 
99
110
  This package is **free** under the **[Lacspace Free Licence](https://lacspace.com/licenses/lacspace-free-1.0)** — MIT-equivalent freedoms. Use it in personal and commercial projects at no cost; just keep the notice.
package/dist/index.cjs CHANGED
@@ -49,9 +49,23 @@ function parseLlmsTxt(txt) {
49
49
  if (details) doc.details = details;
50
50
  return doc;
51
51
  }
52
+ function llmsTxtResponse(doc, init = {}) {
53
+ return new Response(llmsTxt(doc), {
54
+ ...init,
55
+ headers: { "content-type": "text/plain; charset=utf-8", ...init.headers ?? {} }
56
+ });
57
+ }
58
+ function llmsFullTxtResponse(doc, init = {}) {
59
+ return new Response(llmsFullTxt(doc), {
60
+ ...init,
61
+ headers: { "content-type": "text/plain; charset=utf-8", ...init.headers ?? {} }
62
+ });
63
+ }
52
64
 
53
65
  exports.llmsFullTxt = llmsFullTxt;
66
+ exports.llmsFullTxtResponse = llmsFullTxtResponse;
54
67
  exports.llmsTxt = llmsTxt;
68
+ exports.llmsTxtResponse = llmsTxtResponse;
55
69
  exports.parseLlmsTxt = parseLlmsTxt;
56
70
  //# sourceMappingURL=index.cjs.map
57
71
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\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\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\n/**\n * Render an `llms.txt` document.\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): string {\n const out: string[] = [`# ${doc.title}`];\n if (doc.summary) out.push(\"\", `> ${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 section.links) {\n out.push(`- [${l.title}](${l.url})${l.notes ? `: ${l.notes}` : \"\"}`);\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 if (doc.summary) out.push(\"\", `> ${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 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 doc.summary = (doc.summary ? doc.summary + \" \" : \"\") + line.slice(2).trim();\n } else if (line.startsWith(\"## \")) {\n current = { title: line.slice(3).trim(), links: [] };\n doc.sections.push(current);\n } else if (current && linkRe.test(line)) {\n const m = line.match(linkRe)!;\n current.links.push({ title: m[1]!, url: m[2]!, notes: m[3]?.trim() || undefined });\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"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\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\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\n/**\n * Render an `llms.txt` document.\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): string {\n const out: string[] = [`# ${doc.title}`];\n if (doc.summary) out.push(\"\", `> ${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 section.links) {\n out.push(`- [${l.title}](${l.url})${l.notes ? `: ${l.notes}` : \"\"}`);\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 if (doc.summary) out.push(\"\", `> ${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 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 doc.summary = (doc.summary ? doc.summary + \" \" : \"\") + line.slice(2).trim();\n } else if (line.startsWith(\"## \")) {\n current = { title: line.slice(3).trim(), links: [] };\n doc.sections.push(current);\n } else if (current && linkRe.test(line)) {\n const m = line.match(linkRe)!;\n current.links.push({ title: m[1]!, url: m[2]!, notes: m[3]?.trim() || undefined });\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/* ------------------------------ 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"]}
package/dist/index.d.cts CHANGED
@@ -53,5 +53,9 @@ interface LlmsFullDoc {
53
53
  declare function llmsFullTxt(doc: LlmsFullDoc): string;
54
54
  /** Parse an `llms.txt` string back into a structured document. */
55
55
  declare function parseLlmsTxt(txt: string): LlmsDoc;
56
+ /** `llms.txt` as a Fetch/edge `Response` (text/plain) for app/llms.txt/route.ts. */
57
+ declare function llmsTxtResponse(doc: LlmsDoc, init?: ResponseInit): Response;
58
+ /** `llms-full.txt` as a Fetch/edge `Response` (text/plain). */
59
+ declare function llmsFullTxtResponse(doc: LlmsFullDoc, init?: ResponseInit): Response;
56
60
 
57
- export { type LlmsDoc, type LlmsFullDoc, type LlmsFullSection, type LlmsLink, type LlmsSection, llmsFullTxt, llmsTxt, parseLlmsTxt };
61
+ export { type LlmsDoc, type LlmsFullDoc, type LlmsFullSection, type LlmsLink, type LlmsSection, llmsFullTxt, llmsFullTxtResponse, llmsTxt, llmsTxtResponse, parseLlmsTxt };
package/dist/index.d.ts CHANGED
@@ -53,5 +53,9 @@ interface LlmsFullDoc {
53
53
  declare function llmsFullTxt(doc: LlmsFullDoc): string;
54
54
  /** Parse an `llms.txt` string back into a structured document. */
55
55
  declare function parseLlmsTxt(txt: string): LlmsDoc;
56
+ /** `llms.txt` as a Fetch/edge `Response` (text/plain) for app/llms.txt/route.ts. */
57
+ declare function llmsTxtResponse(doc: LlmsDoc, init?: ResponseInit): Response;
58
+ /** `llms-full.txt` as a Fetch/edge `Response` (text/plain). */
59
+ declare function llmsFullTxtResponse(doc: LlmsFullDoc, init?: ResponseInit): Response;
56
60
 
57
- export { type LlmsDoc, type LlmsFullDoc, type LlmsFullSection, type LlmsLink, type LlmsSection, llmsFullTxt, llmsTxt, parseLlmsTxt };
61
+ export { type LlmsDoc, type LlmsFullDoc, type LlmsFullSection, type LlmsLink, type LlmsSection, llmsFullTxt, llmsFullTxtResponse, llmsTxt, llmsTxtResponse, parseLlmsTxt };
package/dist/index.js CHANGED
@@ -47,7 +47,19 @@ function parseLlmsTxt(txt) {
47
47
  if (details) doc.details = details;
48
48
  return doc;
49
49
  }
50
+ function llmsTxtResponse(doc, init = {}) {
51
+ return new Response(llmsTxt(doc), {
52
+ ...init,
53
+ headers: { "content-type": "text/plain; charset=utf-8", ...init.headers ?? {} }
54
+ });
55
+ }
56
+ function llmsFullTxtResponse(doc, init = {}) {
57
+ return new Response(llmsFullTxt(doc), {
58
+ ...init,
59
+ headers: { "content-type": "text/plain; charset=utf-8", ...init.headers ?? {} }
60
+ });
61
+ }
50
62
 
51
- export { llmsFullTxt, llmsTxt, parseLlmsTxt };
63
+ export { llmsFullTxt, llmsFullTxtResponse, llmsTxt, llmsTxtResponse, parseLlmsTxt };
52
64
  //# sourceMappingURL=index.js.map
53
65
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AA0CO,SAAS,QAAQ,GAAA,EAAsB;AAC5C,EAAA,MAAM,GAAA,GAAgB,CAAC,CAAA,EAAA,EAAK,GAAA,CAAI,KAAK,CAAA,CAAE,CAAA;AACvC,EAAA,IAAI,GAAA,CAAI,SAAS,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA;AAChD,EAAA,IAAI,GAAA,CAAI,SAAS,GAAA,CAAI,IAAA,CAAK,IAAI,GAAA,CAAI,OAAA,CAAQ,MAAM,CAAA;AAChD,EAAA,KAAA,MAAW,OAAA,IAAW,IAAI,QAAA,EAAU;AAClC,IAAA,GAAA,CAAI,KAAK,EAAA,EAAI,CAAA,GAAA,EAAM,OAAA,CAAQ,KAAK,IAAI,EAAE,CAAA;AACtC,IAAA,KAAA,MAAW,CAAA,IAAK,QAAQ,KAAA,EAAO;AAC7B,MAAA,GAAA,CAAI,IAAA,CAAK,CAAA,GAAA,EAAM,CAAA,CAAE,KAAK,KAAK,CAAA,CAAE,GAAG,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK,CAAA,CAAE,KAAK,CAAA,CAAA,GAAK,EAAE,CAAA,CAAE,CAAA;AAAA,IACrE;AAAA,EACF;AACA,EAAA,OAAO,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AAC1B;AAiBO,SAAS,YAAY,GAAA,EAA0B;AACpD,EAAA,MAAM,GAAA,GAAgB,CAAC,CAAA,EAAA,EAAK,GAAA,CAAI,KAAK,CAAA,CAAE,CAAA;AACvC,EAAA,IAAI,GAAA,CAAI,SAAS,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAA,EAAK,GAAA,CAAI,OAAO,CAAA,CAAE,CAAA;AAChD,EAAA,KAAA,MAAW,OAAA,IAAW,IAAI,QAAA,EAAU;AAClC,IAAA,GAAA,CAAI,KAAK,EAAA,EAAI,KAAA,EAAO,IAAI,CAAA,GAAA,EAAM,OAAA,CAAQ,KAAK,CAAA,CAAE,CAAA;AAC7C,IAAA,IAAI,OAAA,CAAQ,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,QAAA,EAAW,OAAA,CAAQ,GAAG,CAAA,CAAE,CAAA;AACtD,IAAA,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA;AAAA,EACrC;AACA,EAAA,OAAO,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AAC1B;AAGO,SAAS,aAAa,GAAA,EAAsB;AACjD,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,OAAO,CAAA;AAC/B,EAAA,MAAM,MAAe,EAAE,KAAA,EAAO,EAAA,EAAI,QAAA,EAAU,EAAC,EAAE;AAC/C,EAAA,IAAI,OAAA,GAA8B,IAAA;AAClC,EAAA,MAAM,YAAsB,EAAC;AAC7B,EAAA,MAAM,MAAA,GAAS,+CAAA;AAEf,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,MAAM,IAAA,GAAO,IAAI,OAAA,EAAQ;AACzB,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA,EAAG;AACzB,MAAA,GAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK;AAAA,IACjC,CAAA,MAAA,IAAW,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA,EAAG;AAChC,MAAA,GAAA,CAAI,OAAA,GAAA,CAAW,GAAA,CAAI,OAAA,GAAU,GAAA,CAAI,OAAA,GAAU,GAAA,GAAM,EAAA,IAAM,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,IAC5E,CAAA,MAAA,IAAW,IAAA,CAAK,UAAA,CAAW,KAAK,CAAA,EAAG;AACjC,MAAA,OAAA,GAAU,EAAE,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK,EAAG,KAAA,EAAO,EAAC,EAAE;AACnD,MAAA,GAAA,CAAI,QAAA,CAAS,KAAK,OAAO,CAAA;AAAA,IAC3B,CAAA,MAAA,IAAW,OAAA,IAAW,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG;AACvC,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAC3B,MAAA,OAAA,CAAQ,MAAM,IAAA,CAAK,EAAE,OAAO,CAAA,CAAE,CAAC,GAAI,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAI,OAAO,CAAA,CAAE,CAAC,GAAG,IAAA,EAAK,IAAK,QAAW,CAAA;AAAA,IACnF,CAAA,MAAA,IAAW,CAAC,OAAA,IAAW,IAAA,IAAQ,CAAC,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG;AACpD,MAAA,SAAA,CAAU,KAAK,IAAI,CAAA;AAAA,IACrB;AAAA,EACF;AACA,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,IAAA,CAAK,IAAI,EAAE,IAAA,EAAK;AAC1C,EAAA,IAAI,OAAA,MAAa,OAAA,GAAU,OAAA;AAC3B,EAAA,OAAO,GAAA;AACT","file":"index.js","sourcesContent":["/**\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\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\n/**\n * Render an `llms.txt` document.\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): string {\n const out: string[] = [`# ${doc.title}`];\n if (doc.summary) out.push(\"\", `> ${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 section.links) {\n out.push(`- [${l.title}](${l.url})${l.notes ? `: ${l.notes}` : \"\"}`);\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 if (doc.summary) out.push(\"\", `> ${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 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 doc.summary = (doc.summary ? doc.summary + \" \" : \"\") + line.slice(2).trim();\n } else if (line.startsWith(\"## \")) {\n current = { title: line.slice(3).trim(), links: [] };\n doc.sections.push(current);\n } else if (current && linkRe.test(line)) {\n const m = line.match(linkRe)!;\n current.links.push({ title: m[1]!, url: m[2]!, notes: m[3]?.trim() || undefined });\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"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\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\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\n/**\n * Render an `llms.txt` document.\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): string {\n const out: string[] = [`# ${doc.title}`];\n if (doc.summary) out.push(\"\", `> ${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 section.links) {\n out.push(`- [${l.title}](${l.url})${l.notes ? `: ${l.notes}` : \"\"}`);\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 if (doc.summary) out.push(\"\", `> ${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 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 doc.summary = (doc.summary ? doc.summary + \" \" : \"\") + line.slice(2).trim();\n } else if (line.startsWith(\"## \")) {\n current = { title: line.slice(3).trim(), links: [] };\n doc.sections.push(current);\n } else if (current && linkRe.test(line)) {\n const m = line.match(linkRe)!;\n current.links.push({ title: m[1]!, url: m[2]!, notes: m[3]?.trim() || undefined });\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/* ------------------------------ 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lacspace/llms-txt",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Generate and parse llms.txt and llms-full.txt (the llmstxt.org standard) — a Markdown map of your site for LLMs. Zero-dependency, isomorphic.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",