@actuate-media/cms-core 0.67.0 → 0.69.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/__tests__/api/llms-txt.test.js +287 -0
  3. package/dist/__tests__/api/llms-txt.test.js.map +1 -1
  4. package/dist/__tests__/api/route-contracts.test.js +1 -0
  5. package/dist/__tests__/api/route-contracts.test.js.map +1 -1
  6. package/dist/__tests__/seo/content-markdown.test.d.ts +2 -0
  7. package/dist/__tests__/seo/content-markdown.test.d.ts.map +1 -0
  8. package/dist/__tests__/seo/content-markdown.test.js +124 -0
  9. package/dist/__tests__/seo/content-markdown.test.js.map +1 -0
  10. package/dist/__tests__/seo/llms-sanitize.test.d.ts +2 -0
  11. package/dist/__tests__/seo/llms-sanitize.test.d.ts.map +1 -0
  12. package/dist/__tests__/seo/llms-sanitize.test.js +74 -0
  13. package/dist/__tests__/seo/llms-sanitize.test.js.map +1 -0
  14. package/dist/api/routes/seo.d.ts.map +1 -1
  15. package/dist/api/routes/seo.js +156 -24
  16. package/dist/api/routes/seo.js.map +1 -1
  17. package/dist/config/types.d.ts +34 -0
  18. package/dist/config/types.d.ts.map +1 -1
  19. package/dist/seo/content-markdown.d.ts +15 -0
  20. package/dist/seo/content-markdown.d.ts.map +1 -0
  21. package/dist/seo/content-markdown.js +193 -0
  22. package/dist/seo/content-markdown.js.map +1 -0
  23. package/dist/seo/index.d.ts +4 -1
  24. package/dist/seo/index.d.ts.map +1 -1
  25. package/dist/seo/index.js +3 -1
  26. package/dist/seo/index.js.map +1 -1
  27. package/dist/seo/llms-select.d.ts +34 -0
  28. package/dist/seo/llms-select.d.ts.map +1 -0
  29. package/dist/seo/llms-select.js +67 -0
  30. package/dist/seo/llms-select.js.map +1 -0
  31. package/dist/seo/llms-txt.d.ts +24 -0
  32. package/dist/seo/llms-txt.d.ts.map +1 -1
  33. package/dist/seo/llms-txt.js +104 -53
  34. package/dist/seo/llms-txt.js.map +1 -1
  35. package/package.json +3 -1
@@ -0,0 +1,15 @@
1
+ /** Convert an HTML/rich-text fragment to Markdown. Plain text passes through. */
2
+ export declare function htmlToMarkdown(html: string | null | undefined): string;
3
+ export interface DocumentMarkdownInput {
4
+ title?: string | null;
5
+ /** The document's `data` JSON column. */
6
+ data?: Record<string, unknown> | null;
7
+ /** Pre-extracted plain text fallback (the `plainText` column). */
8
+ plainText?: string | null;
9
+ }
10
+ /**
11
+ * Render a published document to clean Markdown:
12
+ * `# Title`, an optional one-line takeaway, then the body.
13
+ */
14
+ export declare function documentToMarkdown(doc: DocumentMarkdownInput): string;
15
+ //# sourceMappingURL=content-markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-markdown.d.ts","sourceRoot":"","sources":["../../src/seo/content-markdown.ts"],"names":[],"mappings":"AAiCA,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAatE;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACrC,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AA2BD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAoBrE"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Document → clean Markdown serialization for the AI/agent layer.
3
+ *
4
+ * Powers per-page `.md` output and `/llms-full.txt`. The goal is a faithful,
5
+ * readable rendering of the *content* (so an agent can fetch the page body, not
6
+ * just the link) — never the chrome, settings, ids, or URLs that live alongside
7
+ * it in the document model.
8
+ *
9
+ * HTML/rich-text slots are converted with Turndown; structured section content
10
+ * is walked generically (allow-listed prose/heading keys only) so new section
11
+ * types render acceptably without per-type code. Output is always `noindex`-only
12
+ * — callers must serve it with `X-Robots-Tag: noindex` and keep it out of the
13
+ * sitemap (the HTML page stays canonical).
14
+ */
15
+ import TurndownService from 'turndown';
16
+ import { getSectionType } from '../sections/registry.js';
17
+ let _td = null;
18
+ function turndown() {
19
+ if (!_td) {
20
+ _td = new TurndownService({
21
+ headingStyle: 'atx',
22
+ codeBlockStyle: 'fenced',
23
+ bulletListMarker: '-',
24
+ emDelimiter: '_',
25
+ });
26
+ }
27
+ return _td;
28
+ }
29
+ const HTML_LIKE = /<[a-z!/][\s\S]*>/i;
30
+ /** Convert an HTML/rich-text fragment to Markdown. Plain text passes through. */
31
+ export function htmlToMarkdown(html) {
32
+ if (!html)
33
+ return '';
34
+ const s = String(html);
35
+ if (!HTML_LIKE.test(s))
36
+ return s.replace(/\s+/g, ' ').trim();
37
+ try {
38
+ return turndown().turndown(s).trim();
39
+ }
40
+ catch {
41
+ // Defensive: never throw from a public serializer — degrade to stripped text.
42
+ return s
43
+ .replace(/<[^>]+>/g, ' ')
44
+ .replace(/\s+/g, ' ')
45
+ .trim();
46
+ }
47
+ }
48
+ // Keys whose string values are prose paragraphs.
49
+ const PROSE_KEYS = new Set([
50
+ 'body',
51
+ 'content',
52
+ 'html',
53
+ 'text',
54
+ 'copy',
55
+ 'description',
56
+ 'answer',
57
+ 'quote',
58
+ 'excerpt',
59
+ ]);
60
+ // Keys whose string values are headings/sub-headings within a section.
61
+ const HEADING_KEYS = new Set([
62
+ 'heading',
63
+ 'title',
64
+ 'subtitle',
65
+ 'subheading',
66
+ 'eyebrow',
67
+ 'question',
68
+ 'label',
69
+ ]);
70
+ const MAX_DEPTH = 8;
71
+ /**
72
+ * Render a published document to clean Markdown:
73
+ * `# Title`, an optional one-line takeaway, then the body.
74
+ */
75
+ export function documentToMarkdown(doc) {
76
+ const data = (doc.data ?? {});
77
+ const out = [];
78
+ const title = firstString(data.metaTitle, doc.title, data.title) ?? 'Untitled';
79
+ out.push(`# ${oneLine(title)}`, '');
80
+ const intro = firstString(data.keyTakeaway, data.metaDescription, data.seoDescription);
81
+ if (intro) {
82
+ out.push(oneLine(intro), '');
83
+ }
84
+ const body = buildBody(data);
85
+ if (body) {
86
+ out.push(body);
87
+ }
88
+ else if (doc.plainText) {
89
+ out.push(String(doc.plainText).trim());
90
+ }
91
+ return collapseBlankLines(out.join('\n')).trim() + '\n';
92
+ }
93
+ function buildBody(data) {
94
+ const parts = [];
95
+ const sections = Array.isArray(data.sections) ? data.sections : null;
96
+ if (sections) {
97
+ for (const s of sections) {
98
+ collectFromSection(s, parts);
99
+ }
100
+ }
101
+ if (parts.length === 0 && data._layout && typeof data._layout === 'object') {
102
+ collectFromTree(data._layout, parts, 0);
103
+ }
104
+ if (parts.length === 0) {
105
+ const html = firstString(data.body, data.content, data.html);
106
+ if (html)
107
+ parts.push(htmlToMarkdown(html));
108
+ }
109
+ return parts
110
+ .map((p) => p.trim())
111
+ .filter(Boolean)
112
+ .join('\n\n')
113
+ .trim();
114
+ }
115
+ function collectFromSection(section, parts) {
116
+ if (!isRecord(section))
117
+ return;
118
+ if (section.visible === false)
119
+ return;
120
+ const content = section.content;
121
+ if (!isRecord(content))
122
+ return;
123
+ // Resolve which slots hold rich text (HTML) from the section-type registry,
124
+ // so we convert those with Turndown rather than treating them as plain text.
125
+ const richKeys = new Set();
126
+ const typeId = typeof section.sectionType === 'string' ? section.sectionType : '';
127
+ const def = typeId ? getSectionType(typeId) : undefined;
128
+ for (const field of def?.fields ?? []) {
129
+ if (field?.type === 'richText' && typeof field.key === 'string')
130
+ richKeys.add(field.key);
131
+ }
132
+ walkContent(content, richKeys, parts, 0);
133
+ }
134
+ function collectFromTree(node, parts, depth) {
135
+ if (depth > MAX_DEPTH || !isRecord(node))
136
+ return;
137
+ if (isRecord(node.data)) {
138
+ // Block data carries author content (richText body, headings, etc.).
139
+ walkContent(node.data, new Set(), parts, 0);
140
+ }
141
+ if (Array.isArray(node.children)) {
142
+ for (const child of node.children)
143
+ collectFromTree(child, parts, depth + 1);
144
+ }
145
+ }
146
+ function walkContent(obj, richKeys, parts, depth) {
147
+ if (depth > MAX_DEPTH)
148
+ return;
149
+ for (const [key, value] of Object.entries(obj)) {
150
+ if (typeof value === 'string') {
151
+ const trimmed = value.trim();
152
+ if (!trimmed)
153
+ continue;
154
+ if (richKeys.has(key) || HTML_LIKE.test(trimmed)) {
155
+ const md = htmlToMarkdown(trimmed);
156
+ if (md)
157
+ parts.push(md);
158
+ }
159
+ else if (HEADING_KEYS.has(key)) {
160
+ parts.push(`## ${oneLine(trimmed)}`);
161
+ }
162
+ else if (PROSE_KEYS.has(key)) {
163
+ parts.push(oneLine(trimmed));
164
+ }
165
+ }
166
+ else if (Array.isArray(value)) {
167
+ for (const item of value) {
168
+ if (isRecord(item))
169
+ walkContent(item, richKeys, parts, depth + 1);
170
+ }
171
+ }
172
+ else if (isRecord(value)) {
173
+ walkContent(value, richKeys, parts, depth + 1);
174
+ }
175
+ }
176
+ }
177
+ function isRecord(v) {
178
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
179
+ }
180
+ function firstString(...candidates) {
181
+ for (const c of candidates) {
182
+ if (typeof c === 'string' && c.trim())
183
+ return c;
184
+ }
185
+ return undefined;
186
+ }
187
+ function oneLine(s) {
188
+ return s.replace(/\s+/g, ' ').trim();
189
+ }
190
+ function collapseBlankLines(s) {
191
+ return s.replace(/\n{3,}/g, '\n\n');
192
+ }
193
+ //# sourceMappingURL=content-markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-markdown.js","sourceRoot":"","sources":["../../src/seo/content-markdown.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,10 @@ export { resolveRobotsDirectives, resolveSeoEnvironment } from './robots.js';
6
6
  export type { RobotsDirectives, RobotsResolutionInput, RobotsSettings } from './robots.js';
7
7
  export { resolveTitle, getDocumentTitle, validateTitleTemplate, applySiteTitleTemplate, SITE_TITLE_TOKENS, DEFAULT_SITE_TITLE_TEMPLATE, } from './title-templates.js';
8
8
  export type { TitleTemplateConfig, TitleVariable, SiteTitleToken, TitleTemplateValidation, } from './title-templates.js';
9
- export { generateLlmsTxt } from './llms-txt.js';
9
+ export { generateLlmsTxt, sanitizeLlmsText } from './llms-txt.js';
10
+ export { documentToMarkdown, htmlToMarkdown } from './content-markdown.js';
11
+ export type { DocumentMarkdownInput } from './content-markdown.js';
12
+ export { selectLlmsDocs, toLlmsPage, readLlmsInclude, isLlmsNoindex } from './llms-select.js';
10
13
  export type { LlmsTxtConfig, LlmsTxtPage } from './llms-txt.js';
11
14
  export { composePageMeta, detectSchemaType, resolveContentDates } from './page-meta.js';
12
15
  export type { ComposePageMetaInput, ComposedPageMeta, ComposeDocumentInput } from './page-meta.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"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"}
package/dist/seo/index.js CHANGED
@@ -2,7 +2,9 @@ export { analyzeContent, calculateReadability, stripHtmlTags, countSyllables, de
2
2
  export { generateMetaTags, renderMetaTagsHtml, generateNextMetadata, buildVerificationMetaEntries, renderVerificationMetaHtml, buildNextVerification, } from './meta-tags.js';
3
3
  export { resolveRobotsDirectives, resolveSeoEnvironment } from './robots.js';
4
4
  export { resolveTitle, getDocumentTitle, validateTitleTemplate, applySiteTitleTemplate, SITE_TITLE_TOKENS, DEFAULT_SITE_TITLE_TEMPLATE, } from './title-templates.js';
5
- export { generateLlmsTxt } from './llms-txt.js';
5
+ export { generateLlmsTxt, sanitizeLlmsText } from './llms-txt.js';
6
+ export { documentToMarkdown, htmlToMarkdown } from './content-markdown.js';
7
+ export { selectLlmsDocs, toLlmsPage, readLlmsInclude, isLlmsNoindex } from './llms-select.js';
6
8
  export { composePageMeta, detectSchemaType, resolveContentDates } from './page-meta.js';
7
9
  export { analyzeImageAlts, countMissingAltImages, isDecorativeImgTag } from './alt-text.js';
8
10
  export { buildRssFeed, buildJsonFeed } from './feeds.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAItB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAI5E,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAS7B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAI/C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAIvF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAI3F,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAIxD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAIzF,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAA;AAS5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAA;AAanB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAWpF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,8BAA8B,EAC9B,oBAAoB,GACrB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/seo/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAA;AAItB,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AAIvB,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAI5E,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,sBAAsB,CAAA;AAS7B,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AACjE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE1E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAI7F,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAIvF,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAI3F,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAIxD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAIzF,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,2BAA2B,GAC5B,MAAM,qBAAqB,CAAA;AAS5B,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAA;AAanB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAWpF,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,8BAA8B,EAC9B,oBAAoB,GACrB,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,mBAAmB,CAAA"}
@@ -0,0 +1,34 @@
1
+ import type { LlmsTxtPage } from './llms-txt.js';
2
+ export type LlmsInclude = 'AUTO' | 'ALWAYS' | 'NEVER';
3
+ /** Tri-state per-doc include flag; defaults to AUTO for unrecognized values. */
4
+ export declare function readLlmsInclude(data: unknown): LlmsInclude;
5
+ /** A doc is excluded from every llms surface when it is noindexed. */
6
+ export declare function isLlmsNoindex(data: unknown): boolean;
7
+ export interface LlmsSelectableDoc {
8
+ collection: string;
9
+ data: unknown;
10
+ }
11
+ /**
12
+ * Apply the curation + privacy rules:
13
+ * - internal/system collections excluded
14
+ * - noindexed docs excluded (privacy boundary)
15
+ * - `llmsInclude` NEVER excluded, ALWAYS included (overrides eligibility),
16
+ * AUTO included only when the collection is eligible
17
+ */
18
+ export declare function selectLlmsDocs<T extends LlmsSelectableDoc>(docs: T[], opts: {
19
+ isInternalCollection: (c: string) => boolean;
20
+ eligible: Set<string> | null;
21
+ }): T[];
22
+ export interface LlmsDocForPage {
23
+ title?: string | null;
24
+ slug?: string | null;
25
+ collection: string;
26
+ updatedAt?: Date | null;
27
+ data: unknown;
28
+ }
29
+ /** Map a selected document to the generator's page shape (curation-aware). */
30
+ export declare function toLlmsPage(d: LlmsDocForPage, opts: {
31
+ base: string;
32
+ urlPrefix?: string;
33
+ }): LlmsTxtPage;
34
+ //# sourceMappingURL=llms-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llms-select.d.ts","sourceRoot":"","sources":["../../src/seo/llms-select.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;AAErD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,CAG1D;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,OAAO,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,iBAAiB,EACxD,IAAI,EAAE,CAAC,EAAE,EACT,IAAI,EAAE;IAAE,oBAAoB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;CAAE,GACnF,CAAC,EAAE,CAWL;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IACvB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,8EAA8E;AAC9E,wBAAgB,UAAU,CACxB,CAAC,EAAE,cAAc,EACjB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,CA6Bb"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Shared selection + mapping for the llms.txt family of routes (`/llms.txt`,
3
+ * `/llms-full.txt`). Keeping this in one place means the curation rules and the
4
+ * privacy boundary (noindex exclusion) can never drift between the two surfaces.
5
+ */
6
+ import { resolveDocumentUrl } from './page-meta.js';
7
+ /** Tri-state per-doc include flag; defaults to AUTO for unrecognized values. */
8
+ export function readLlmsInclude(data) {
9
+ const v = String(data?.llmsInclude ?? '').toUpperCase();
10
+ return v === 'ALWAYS' || v === 'NEVER' ? v : 'AUTO';
11
+ }
12
+ /** A doc is excluded from every llms surface when it is noindexed. */
13
+ export function isLlmsNoindex(data) {
14
+ const d = data;
15
+ return d?.noindex === true || d?.robotsNoindex === true || d?.noindex === 'true';
16
+ }
17
+ /**
18
+ * Apply the curation + privacy rules:
19
+ * - internal/system collections excluded
20
+ * - noindexed docs excluded (privacy boundary)
21
+ * - `llmsInclude` NEVER excluded, ALWAYS included (overrides eligibility),
22
+ * AUTO included only when the collection is eligible
23
+ */
24
+ export function selectLlmsDocs(docs, opts) {
25
+ return docs
26
+ .filter((d) => !opts.isInternalCollection(d.collection))
27
+ .filter((d) => {
28
+ const data = d.data || {};
29
+ if (isLlmsNoindex(data))
30
+ return false;
31
+ const include = readLlmsInclude(data);
32
+ if (include === 'NEVER')
33
+ return false;
34
+ if (include === 'ALWAYS')
35
+ return true;
36
+ return opts.eligible ? opts.eligible.has(d.collection) : true;
37
+ });
38
+ }
39
+ /** Map a selected document to the generator's page shape (curation-aware). */
40
+ export function toLlmsPage(d, opts) {
41
+ const data = d.data || {};
42
+ const section = typeof data.llmsSection === 'string' && data.llmsSection.trim()
43
+ ? data.llmsSection.trim()
44
+ : undefined;
45
+ const str = (v) => typeof v === 'string' && v.trim() ? v : undefined;
46
+ return {
47
+ title: str(data.metaTitle) ?? d.title ?? str(data.title) ?? 'Untitled',
48
+ url: resolveDocumentUrl({
49
+ siteUrl: opts.base,
50
+ urlPrefix: opts.urlPrefix,
51
+ slug: d.slug ?? undefined,
52
+ data,
53
+ }),
54
+ description: str(data.llmsDescription) ??
55
+ str(data.keyTakeaway) ??
56
+ str(data.metaDescription) ??
57
+ str(data.seoDescription) ??
58
+ '',
59
+ collection: d.collection,
60
+ section,
61
+ optional: data.llmsOptional === true,
62
+ priority: typeof data.llmsPriority === 'number' ? data.llmsPriority : undefined,
63
+ updatedAt: d.updatedAt?.toISOString(),
64
+ isCornerstone: data.isCornerstone === true,
65
+ };
66
+ }
67
+ //# sourceMappingURL=llms-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llms-select.js","sourceRoot":"","sources":["../../src/seo/llms-select.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,38 @@
1
1
  export interface LlmsTxtConfig {
2
2
  siteName: string;
3
3
  siteUrl: string;
4
+ /** The reviewed one-to-three sentence blockquote summary. */
4
5
  siteDescription?: string;
6
+ /** Optional free-text context block (no headings) emitted after the summary. */
7
+ intro?: string;
8
+ /** Overall cap across all sections (default 50). */
5
9
  maxPages?: number;
10
+ /** Cap per section/collection (default 25) so one large group can't flood. */
11
+ maxPerSection?: number;
6
12
  }
13
+ /**
14
+ * Coerce CMS-authored text into a safe single-line list-item fragment.
15
+ *
16
+ * These strings flow from editor fields into a file that AI agents read, so we
17
+ * defend against two things: (1) markdown-breaking characters that would corrupt
18
+ * the `- [title](url): desc` syntax, and (2) multi-line / control-character
19
+ * content that a careless or hostile editor could use to smuggle instruction-like
20
+ * text. This is not a complete prompt-injection defense (no text filter is) — it
21
+ * forces single-line, length-capped, link-safe plain text, which removes the
22
+ * most common corruption and obfuscation vectors.
23
+ */
24
+ export declare function sanitizeLlmsText(raw: string | null | undefined, maxLen: number): string;
7
25
  export interface LlmsTxtPage {
8
26
  title: string;
9
27
  url: string;
10
28
  description?: string;
11
29
  collection?: string;
30
+ /** Explicit section/grouping override; falls back to `collection`. */
31
+ section?: string;
32
+ /** Routes the entry into the reserved `## Optional` section. */
33
+ optional?: boolean;
34
+ /** Sort order within a section — higher first. Defaults to 0. */
35
+ priority?: number;
12
36
  updatedAt?: string;
13
37
  isCornerstone?: boolean;
14
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"llms-txt.d.ts","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAsEnF"}
1
+ {"version":3,"file":"llms-txt.d.ts","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAiBvF;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAgDnF"}
@@ -1,27 +1,97 @@
1
+ const DESCRIPTION_MAX = 200;
2
+ const TITLE_MAX = 160;
3
+ /**
4
+ * Coerce CMS-authored text into a safe single-line list-item fragment.
5
+ *
6
+ * These strings flow from editor fields into a file that AI agents read, so we
7
+ * defend against two things: (1) markdown-breaking characters that would corrupt
8
+ * the `- [title](url): desc` syntax, and (2) multi-line / control-character
9
+ * content that a careless or hostile editor could use to smuggle instruction-like
10
+ * text. This is not a complete prompt-injection defense (no text filter is) — it
11
+ * forces single-line, length-capped, link-safe plain text, which removes the
12
+ * most common corruption and obfuscation vectors.
13
+ */
14
+ export function sanitizeLlmsText(raw, maxLen) {
15
+ if (!raw)
16
+ return '';
17
+ let s = raw
18
+ // Strip control characters (incl. newlines, tabs, zero-width) → space.
19
+ .replace(/[\u0000-\u001F\u007F\u200B-\u200D\uFEFF]/g, ' ')
20
+ // Remove characters that break markdown link syntax in the list item.
21
+ .replace(/[[\]()]/g, '')
22
+ // Collapse any remaining whitespace runs.
23
+ .replace(/\s+/g, ' ')
24
+ .trim();
25
+ if (s.length > maxLen)
26
+ s =
27
+ s
28
+ .slice(0, maxLen)
29
+ .replace(/\s+\S*$/, '')
30
+ .trim() || s.slice(0, maxLen);
31
+ return s;
32
+ }
1
33
  export function generateLlmsTxt(config, pages) {
2
34
  const maxPages = config.maxPages ?? 50;
35
+ const maxPerSection = config.maxPerSection ?? 25;
3
36
  const lines = [];
4
- lines.push(`# ${config.siteName}`);
37
+ lines.push(`# ${sanitizeLlmsText(config.siteName, TITLE_MAX) || 'Site'}`);
5
38
  lines.push('');
6
- if (config.siteDescription) {
7
- lines.push(`> ${config.siteDescription}`);
39
+ const summary = sanitizeLlmsText(config.siteDescription, DESCRIPTION_MAX);
40
+ if (summary) {
41
+ lines.push(`> ${summary}`);
42
+ lines.push('');
43
+ }
44
+ // Free-text context block. It is a reviewed config field (not editor-freeform),
45
+ // so multi-line markdown is allowed; we only trim and drop accidental headings
46
+ // (which would corrupt the section structure the spec relies on).
47
+ const intro = (config.intro ?? '')
48
+ .split(/\r?\n/)
49
+ .filter((l) => !/^\s{0,3}#/.test(l))
50
+ .join('\n')
51
+ .trim();
52
+ if (intro) {
53
+ lines.push(intro);
8
54
  lines.push('');
9
55
  }
10
- const sorted = [...pages].sort((a, b) => {
11
- if (a.isCornerstone !== b.isCornerstone)
12
- return a.isCornerstone ? -1 : 1;
13
- if (a.updatedAt && b.updatedAt)
14
- return b.updatedAt.localeCompare(a.updatedAt);
15
- if (a.updatedAt)
16
- return -1;
17
- if (b.updatedAt)
18
- return 1;
19
- return 0;
20
- });
21
- const limited = sorted.slice(0, maxPages);
56
+ const limited = [...pages].sort(comparePages).slice(0, maxPages);
57
+ const main = limited.filter((p) => !p.optional);
58
+ const optional = limited.filter((p) => p.optional);
59
+ for (const [section, group] of groupBySection(main)) {
60
+ emitSection(lines, formatHeading(section), group, maxPerSection);
61
+ }
62
+ // The reserved `## Optional` section tells context-limited agents what to skip
63
+ // first. Optional entries are flat (not sub-grouped) per common convention.
64
+ if (optional.length > 0) {
65
+ emitSection(lines, 'Optional', optional, maxPerSection);
66
+ }
67
+ lines.push('## Resources');
68
+ lines.push('');
69
+ lines.push(`- [Sitemap](${config.siteUrl}/sitemap.xml)`);
70
+ lines.push(`- [API Documentation](${config.siteUrl}/api/cms/docs)`);
71
+ lines.push('');
72
+ return lines.join('\n');
73
+ }
74
+ /** Cornerstone first, then higher `priority`, then most-recently updated. */
75
+ function comparePages(a, b) {
76
+ if (a.isCornerstone !== b.isCornerstone)
77
+ return a.isCornerstone ? -1 : 1;
78
+ const pa = a.priority ?? 0;
79
+ const pb = b.priority ?? 0;
80
+ if (pa !== pb)
81
+ return pb - pa;
82
+ if (a.updatedAt && b.updatedAt)
83
+ return b.updatedAt.localeCompare(a.updatedAt);
84
+ if (a.updatedAt)
85
+ return -1;
86
+ if (b.updatedAt)
87
+ return 1;
88
+ return 0;
89
+ }
90
+ /** Group entries by their resolved section, preserving first-seen order. */
91
+ function groupBySection(pages) {
22
92
  const groups = new Map();
23
- for (const page of limited) {
24
- const key = page.collection ?? 'Important Pages';
93
+ for (const page of pages) {
94
+ const key = page.section ?? page.collection ?? 'Important Pages';
25
95
  let group = groups.get(key);
26
96
  if (!group) {
27
97
  group = [];
@@ -29,44 +99,25 @@ export function generateLlmsTxt(config, pages) {
29
99
  }
30
100
  group.push(page);
31
101
  }
32
- // Sort within each group: cornerstone first, then by updatedAt desc
33
- for (const group of groups.values()) {
34
- group.sort((a, b) => {
35
- if (a.isCornerstone !== b.isCornerstone)
36
- return a.isCornerstone ? -1 : 1;
37
- if (a.updatedAt && b.updatedAt)
38
- return b.updatedAt.localeCompare(a.updatedAt);
39
- if (a.updatedAt)
40
- return -1;
41
- if (b.updatedAt)
42
- return 1;
43
- return 0;
44
- });
45
- }
46
- for (const [collection, group] of groups) {
47
- const heading = formatHeading(collection);
48
- lines.push(`## ${heading}`);
49
- lines.push('');
50
- for (const page of group) {
51
- // Append a freshness marker so AI answer engines can prefer recent
52
- // content. `updatedAt` is an ISO string; emit the date portion only.
53
- const updated = page.updatedAt ? formatLlmsDate(page.updatedAt) : undefined;
54
- const suffix = [page.description, updated ? `Updated: ${updated}` : undefined]
55
- .filter(Boolean)
56
- .join(' — ');
57
- const entry = suffix
58
- ? `- [${page.title}](${page.url}): ${suffix}`
59
- : `- [${page.title}](${page.url})`;
60
- lines.push(entry);
61
- }
62
- lines.push('');
63
- }
64
- lines.push('## Resources');
102
+ return groups;
103
+ }
104
+ function emitSection(lines, heading, group, maxPerSection) {
105
+ lines.push(`## ${heading}`);
65
106
  lines.push('');
66
- lines.push(`- [Sitemap](${config.siteUrl}/sitemap.xml)`);
67
- lines.push(`- [API Documentation](${config.siteUrl}/api/cms/docs)`);
107
+ // Cap per section so a single large collection can't crowd out the rest.
108
+ for (const page of group.slice(0, maxPerSection)) {
109
+ const title = sanitizeLlmsText(page.title, TITLE_MAX) || 'Untitled';
110
+ const description = sanitizeLlmsText(page.description, DESCRIPTION_MAX);
111
+ // Append a freshness marker so AI answer engines can prefer recent content.
112
+ // `updatedAt` is an ISO string; emit the date portion only.
113
+ const updated = page.updatedAt ? formatLlmsDate(page.updatedAt) : undefined;
114
+ const suffix = [description, updated ? `Updated: ${updated}` : undefined]
115
+ .filter(Boolean)
116
+ .join(' — ');
117
+ const entry = suffix ? `- [${title}](${page.url}): ${suffix}` : `- [${title}](${page.url})`;
118
+ lines.push(entry);
119
+ }
68
120
  lines.push('');
69
- return lines.join('\n');
70
121
  }
71
122
  function formatHeading(collection) {
72
123
  return collection.replace(/[-_]/g, ' ').replace(/\b\w/g, (ch) => ch.toUpperCase());
@@ -1 +1 @@
1
- {"version":3,"file":"llms-txt.js","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"llms-txt.js","sourceRoot":"","sources":["../../src/seo/llms-txt.ts"],"names":[],"mappings":"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"}