@pas7/llm-seo 0.1.6
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/LICENSE +201 -0
- package/README.md +164 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.js +673 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/next/index.d.ts +292 -0
- package/dist/adapters/next/index.js +673 -0
- package/dist/adapters/next/index.js.map +1 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +2232 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/config.schema-DCnBx3Gm.d.ts +824 -0
- package/dist/core/index.d.ts +752 -0
- package/dist/core/index.js +1330 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1909 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.schema-B_z3rxRV.d.ts +384 -0
- package/dist/schema/index.d.ts +72 -0
- package/dist/schema/index.js +422 -0
- package/dist/schema/index.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/normalize/url.ts","../src/core/normalize/sort.ts","../src/core/normalize/text.ts","../src/core/canonical/locale.ts","../src/core/canonical/canonical-from-manifest.ts","../src/core/generate/llms-txt.ts","../src/core/generate/llms-full-txt.ts","../src/core/generate/citations.ts","../src/core/check/issues.ts","../src/core/check/rules-linter.ts","../src/core/check/checker.ts","../src/schema/config.schema.ts","../src/schema/manifest.schema.ts","../src/schema/validate.ts","../src/adapters/next/manifest.ts","../src/adapters/next/build-hooks.ts"],"names":["getHubLabel","formatHubLabel","z","readFile"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * URL normalization utilities for deterministic SEO processing.\n */\n\n/**\n * Options for URL normalization.\n */\nexport interface NormalizeUrlOptions {\n /** Base URL e.g., \"https://example.com\" */\n baseUrl: string;\n /** Path e.g., \"/blog/my-post\" */\n path: string;\n /** Trailing slash policy */\n trailingSlash: 'always' | 'never' | 'preserve';\n /** Strip query string (default: true) */\n stripQuery?: boolean;\n /** Strip hash/fragment (default: true) */\n stripHash?: boolean;\n}\n\n/**\n * Normalizes a path by removing double slashes and normalizing dots.\n * @param path - The path to normalize\n * @param preserveTrailingSlash - Whether to preserve trailing slash (default: false)\n * @returns The normalized path\n */\nexport function normalizePath(path: string, preserveTrailingSlash = false): string {\n // Handle empty path\n if (!path || path === '/') {\n return '/';\n }\n\n // Track if original path had trailing slash\n const hadTrailingSlash = path.endsWith('/') && path !== '/';\n\n // Ensure path starts with /\n let normalized = path.startsWith('/') ? path : `/${path}`;\n\n // Collapse multiple consecutive slashes into one\n normalized = normalized.replace(/\\/{2,}/g, '/');\n\n // Handle . and .. segments\n const segments: string[] = [];\n const parts = normalized.split('/');\n\n for (const part of parts) {\n if (part === '.' || part === '') {\n // Skip current directory references and empty parts\n continue;\n } else if (part === '..') {\n // Go up one directory\n if (segments.length > 0) {\n segments.pop();\n }\n } else {\n segments.push(part);\n }\n }\n\n // Reconstruct path\n let result = '/' + segments.join('/');\n \n // Restore trailing slash if needed\n if (preserveTrailingSlash && hadTrailingSlash && result !== '/') {\n result += '/';\n }\n \n return result;\n}\n\n/**\n * Joins URL parts safely, handling slashes between parts.\n * @param parts - URL parts to join\n * @returns Joined path string\n */\nexport function joinUrlParts(...parts: string[]): string {\n if (parts.length === 0) {\n return '/';\n }\n\n // Filter out empty parts\n const filteredParts = parts.filter((part) => part.length > 0);\n\n if (filteredParts.length === 0) {\n return '/';\n }\n\n // Join parts, ensuring single slashes between them\n const joined = filteredParts\n .map((part) => {\n // Remove leading slash from all parts\n let p = part.replace(/^\\/+/, '');\n // Remove trailing slash from all parts except we'll add at the end if needed\n p = p.replace(/\\/+$/, '');\n return p;\n })\n .filter((p) => p.length > 0)\n .join('/');\n\n return joined.length > 0 ? `/${joined}` : '/';\n}\n\n/**\n * Validates that a URL is absolute with http/https protocol.\n * @param url - The URL string to validate\n * @returns True if the URL is a valid absolute http/https URL\n */\nexport function isValidAbsoluteUrl(url: string): boolean {\n if (!url || typeof url !== 'string') {\n return false;\n }\n\n try {\n const parsed = new URL(url);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/**\n * Normalizes URL according to policy:\n * - No // in path (collapse to single /)\n * - Strip query and hash by default\n * - Apply trailing slash policy\n * - Lowercase hostname\n * - Remove default ports (80, 443)\n * @param options - Normalization options\n * @returns The normalized URL string\n */\nexport function normalizeUrl(options: NormalizeUrlOptions): string {\n const { baseUrl, path, trailingSlash, stripQuery = true, stripHash = true } = options;\n\n // Parse base URL\n let parsedBase: URL;\n try {\n parsedBase = new URL(baseUrl);\n } catch {\n throw new TypeError(`Invalid baseUrl: ${baseUrl}`);\n }\n\n // Normalize the path with trailing slash preservation flag\n const shouldPreserveTrailingSlash = trailingSlash === 'preserve';\n const normalizedPath = normalizePath(path, shouldPreserveTrailingSlash);\n\n // Apply trailing slash policy\n let finalPath = normalizedPath;\n if (trailingSlash === 'always') {\n // Always add trailing slash (except for root which already has it)\n if (!finalPath.endsWith('/')) {\n finalPath = `${finalPath}/`;\n }\n } else if (trailingSlash === 'never') {\n // Remove trailing slash (except for root)\n if (finalPath !== '/' && finalPath.endsWith('/')) {\n finalPath = finalPath.slice(0, -1);\n }\n }\n // 'preserve' - already handled by normalizePath\n\n // Build the full URL\n const protocol = parsedBase.protocol.toLowerCase();\n let hostname = parsedBase.hostname.toLowerCase();\n\n // Handle port - remove default ports\n let port = parsedBase.port;\n if (port) {\n const isDefaultPort =\n (protocol === 'http:' && port === '80') ||\n (protocol === 'https:' && port === '443');\n if (!isDefaultPort) {\n hostname = `${hostname}:${port}`;\n }\n }\n\n // Build the final URL\n let fullUrl = `${protocol}//${hostname}${finalPath}`;\n\n // Add query string if not stripped\n if (!stripQuery && parsedBase.search) {\n fullUrl += parsedBase.search;\n }\n\n // Add hash if not stripped\n if (!stripHash && parsedBase.hash) {\n fullUrl += parsedBase.hash;\n }\n\n return fullUrl;\n}\n\n/**\n * Sorts URLs deterministically for consistent output ordering.\n * @param urls - Array of URLs to sort\n * @returns Sorted array of URLs\n */\nexport function sortUrls(urls: readonly string[]): string[] {\n return [...urls].sort((a, b) => a.localeCompare(b));\n}\n","/**\n * Deterministic sorting utilities for SEO artifacts.\n */\n\n/**\n * Comparator function type for sorting operations.\n */\nexport type Comparator<T> = (a: T, b: T) => number;\n\n/**\n * Creates a deterministic string comparator for consistent ordering.\n * Uses localeCompare with specific locale for reproducibility.\n * @param a - First string to compare\n * @param b - Second string to compare\n * @returns Negative if a < b, positive if a > b, zero if equal\n */\nexport function compareStrings(a: string, b: string): number {\n return a.localeCompare(b, 'en', { sensitivity: 'case', numeric: true });\n}\n\n/**\n * Sorts an array of strings deterministically.\n * @param items - Array of strings to sort\n * @returns New sorted array\n */\nexport function sortStrings(items: readonly string[]): string[] {\n return [...items].sort(compareStrings);\n}\n\n/**\n * Sorts an array of objects by a string key deterministically.\n * @param items - Array of objects to sort\n * @param keyFn - Function to extract the comparison key\n * @returns New sorted array\n */\nexport function sortBy<T>(items: readonly T[], keyFn: (item: T) => string): T[] {\n return [...items].sort((a, b) => compareStrings(keyFn(a), keyFn(b)));\n}\n\n/**\n * Sorts strings in a deterministic way (localeCompare with numeric).\n * Alias for sortStrings for API consistency.\n * @param items - Array of strings to sort\n * @returns New sorted array\n */\nexport function stableSortStrings(items: string[]): string[] {\n return [...items].sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'case', numeric: true }));\n}\n\n/**\n * Sorts objects by key in a deterministic way.\n * @param items - Array of objects to sort\n * @param keyFn - Function to extract the comparison key\n * @returns New sorted array\n */\nexport function stableSortBy<T>(items: T[], keyFn: (item: T) => string): T[] {\n return [...items].sort((a, b) => {\n const keyA = keyFn(a);\n const keyB = keyFn(b);\n return keyA.localeCompare(keyB, 'en', { sensitivity: 'case', numeric: true });\n });\n}\n\n/**\n * Counts the number of path segments in a URL.\n * @param url - The URL to count segments for\n * @returns Number of path segments\n */\nfunction countPathSegments(url: string): number {\n try {\n const parsed = new URL(url);\n const path = parsed.pathname.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!path) return 0;\n return path.split('/').length;\n } catch {\n // If not a valid URL, count slashes in the string\n const cleaned = url.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!cleaned) return 0;\n return cleaned.split('/').length;\n }\n}\n\n/**\n * Sorts URLs by path segments (shorter first, then alphabetically).\n * This ensures deterministic ordering with root paths first.\n * @param urls - Array of URLs to sort\n * @returns New sorted array\n */\nexport function sortUrlsByPath(urls: string[]): string[] {\n return [...urls].sort((a, b) => {\n const segmentsA = countPathSegments(a);\n const segmentsB = countPathSegments(b);\n\n // First sort by number of segments (shorter paths first)\n if (segmentsA !== segmentsB) {\n return segmentsA - segmentsB;\n }\n\n // Then sort alphabetically\n return a.localeCompare(b, 'en', { sensitivity: 'case', numeric: true });\n });\n}\n","/**\n * Text normalization utilities for deterministic SEO processing.\n */\n\n/**\n * Normalizes whitespace in text by collapsing multiple spaces and trimming.\n * @param text - The text to normalize\n * @returns Normalized text with single spaces\n */\nexport function normalizeWhitespace(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Normalizes line endings to the specified format.\n * @param text - The text to normalize\n * @param lineEndings - Target line endings format ('lf' or 'crlf')\n * @returns Text with normalized line endings\n */\nexport function normalizeLineEndings(text: string, lineEndings: 'lf' | 'crlf'): string {\n // First normalize all line endings to \\n\n const normalized = text.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n // Then convert to target format\n return lineEndings === 'crlf' ? normalized.replace(/\\n/g, '\\r\\n') : normalized;\n}\n\n/**\n * Normalizes whitespace in lines - trims trailing whitespace and removes multiple consecutive spaces.\n * @param text - The text to normalize\n * @returns Text with normalized line whitespace\n */\nexport function normalizeLineWhitespace(text: string): string {\n const lines = text.split(/\\r?\\n/);\n return lines\n .map((line) => line.trimEnd().replace(/[ \\t]+/g, (match) => ' '.repeat(match.length === 0 ? 0 : match.length)))\n .map((line) => line.replace(/ +/g, ' '))\n .join('\\n');\n}\n\n/**\n * Normalizes text for use in SEO meta descriptions or titles.\n * Collapses whitespace and truncates to a maximum length.\n * @param text - The text to normalize\n * @param maxLength - Maximum allowed length\n * @returns Normalized text\n */\nexport function normalizeSeoText(text: string, maxLength: number): string {\n const normalized = normalizeWhitespace(text);\n if (normalized.length <= maxLength) {\n return normalized;\n }\n // Truncate at word boundary\n const truncated = normalized.slice(0, maxLength);\n const lastSpace = truncated.lastIndexOf(' ');\n return lastSpace > 0 ? `${truncated.slice(0, lastSpace)}…` : `${truncated.slice(0, -1)}…`;\n}\n","/**\n * Locale handling utilities for canonical URL generation.\n */\n\nimport type { ManifestItem } from '../../schema/manifest.schema.js';\nimport { stableSortStrings } from '../normalize/sort.js';\n\n/**\n * Represents a locale configuration for a site.\n */\nexport interface LocaleConfig {\n /** Default locale code (e.g., 'en') */\n default: string;\n /** Supported locale codes */\n supported: readonly string[];\n /** URL strategy for locales */\n strategy: 'subdirectory' | 'subdomain' | 'domain';\n}\n\n/**\n * Options for selecting canonical locale.\n */\nexport interface SelectCanonicalLocaleOptions {\n /** Default locale code (e.g., 'en') */\n defaultLocale: string;\n /** Available locale codes for the item */\n availableLocales: string[];\n}\n\n/**\n * Selects canonical locale using deterministic algorithm:\n * 1. If defaultLocale is in availableLocales → return defaultLocale\n * 2. Otherwise, sort availableLocales and return first\n * 3. If no locales available → return null\n * @param options - Selection options\n * @returns The canonical locale or null if none available\n */\nexport function selectCanonicalLocale(options: SelectCanonicalLocaleOptions): string | null {\n const { defaultLocale, availableLocales } = options;\n\n // Handle empty/null cases\n if (!availableLocales || availableLocales.length === 0) {\n return null;\n }\n\n // Filter out any null/undefined/empty values\n const validLocales = availableLocales.filter(\n (locale): locale is string => typeof locale === 'string' && locale.length > 0\n );\n\n if (validLocales.length === 0) {\n return null;\n }\n\n // If defaultLocale is available, use it\n if (defaultLocale && validLocales.includes(defaultLocale)) {\n return defaultLocale;\n }\n\n // Otherwise, sort and return first (deterministic)\n const sorted = stableSortStrings(validLocales);\n return sorted[0] ?? null;\n}\n\n/**\n * Determines if a locale is available for an item.\n * @param locale - The locale to check\n * @param availableLocales - Array of available locales\n * @returns True if the locale is available\n */\nexport function isLocaleAvailable(locale: string, availableLocales: string[]): boolean {\n if (!locale || !availableLocales || availableLocales.length === 0) {\n return false;\n }\n return availableLocales.includes(locale);\n}\n\n/**\n * Gets all unique locales from manifest items.\n * @param items - Array of manifest items\n * @returns Array of unique locale codes\n */\nexport function extractAllLocales(items: ManifestItem[]): string[] {\n const localeSet = new Set<string>();\n\n for (const item of items) {\n if (item.locales && Array.isArray(item.locales)) {\n for (const locale of item.locales) {\n if (typeof locale === 'string' && locale.length > 0) {\n localeSet.add(locale);\n }\n }\n }\n }\n\n return stableSortStrings([...localeSet]);\n}\n\n/**\n * Generates locale-prefixed path.\n * @param path - The base path\n * @param locale - The locale code\n * @param config - Locale configuration\n * @returns Path with locale prefix if applicable\n */\nexport function localizePath(\n path: string,\n locale: string,\n config: LocaleConfig\n): string {\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n \n // Default locale may not need prefix\n if (locale === config.default && config.strategy === 'subdirectory') {\n return normalizedPath;\n }\n \n if (config.strategy === 'subdirectory') {\n return `/${locale}${normalizedPath === '/' ? '' : normalizedPath}`;\n }\n \n return normalizedPath;\n}\n\n/**\n * Extracts locale from a path.\n * @param path - The path to extract locale from\n * @param config - Locale configuration\n * @returns Tuple of [locale, pathWithoutLocale]\n */\nexport function extractLocaleFromPath(\n path: string,\n config: LocaleConfig\n): readonly [string, string] {\n if (config.strategy !== 'subdirectory') {\n return [config.default, path];\n }\n \n const match = path.match(/^\\/([a-z]{2}(?:-[A-Z]{2})?)(\\/|$)/);\n \n if (match?.[1] && config.supported.includes(match[1])) {\n const locale = match[1];\n const remainingPath = path.slice(locale.length + 1) || '/';\n return [locale, remainingPath] as const;\n }\n \n return [config.default, path];\n}\n\n/**\n * Generates alternate locale URLs for a page.\n * @param baseUrl - Base URL of the site\n * @param path - Page path\n * @param config - Locale configuration\n * @returns Map of locale to full URL\n */\nexport function generateAlternateUrls(\n baseUrl: string,\n path: string,\n config: LocaleConfig\n): Map<string, string> {\n const urlMap = new Map<string, string>();\n \n for (const locale of config.supported) {\n const localePath = localizePath(path, locale, config);\n const fullUrl = `${baseUrl}${localePath}`;\n urlMap.set(locale, fullUrl);\n }\n \n return urlMap;\n}\n","/**\n * Canonical URL generation from site manifests.\n */\n\nimport type { SiteManifest, ManifestItem } from '../../schema/manifest.schema.js';\nimport { normalizeUrl, joinUrlParts } from '../normalize/url.js';\nimport { sortUrlsByPath } from '../normalize/sort.js';\nimport { selectCanonicalLocale } from './locale.js';\n\n/**\n * Options for canonical URL generation.\n */\nexport interface CanonicalOptions {\n /** Whether to include trailing slash (default: false) */\n trailingSlash?: boolean;\n /** Whether to use lowercase (default: true) */\n lowercase?: boolean;\n}\n\n/**\n * Locale strategy for URL generation.\n */\nexport type LocaleStrategy = 'prefix' | 'subdomain' | 'none';\n\n/**\n * Trailing slash policy.\n */\nexport type TrailingSlashPolicy = 'always' | 'never' | 'preserve';\n\n/**\n * Options for creating canonical URLs from manifest.\n */\nexport interface CreateCanonicalUrlsOptions {\n /** Array of manifest items */\n items: ManifestItem[];\n /** Base URL e.g., \"https://example.com\" */\n baseUrl: string;\n /** Route prefix e.g., \"/blog\" for blog posts */\n routePrefix?: string;\n /** Default locale code */\n defaultLocale: string;\n /** Trailing slash policy */\n trailingSlash: TrailingSlashPolicy;\n /** Locale URL strategy */\n localeStrategy: LocaleStrategy;\n}\n\n/**\n * Generates a canonical URL for a given path from the site manifest.\n * @param manifest - The site manifest containing base URL information\n * @param path - The path to generate canonical URL for\n * @param options - Canonical URL options\n * @returns The canonical URL\n */\nexport function generateCanonicalUrl(\n manifest: SiteManifest,\n path: string,\n options: CanonicalOptions = {}\n): string {\n const { trailingSlash = false, lowercase = true } = options;\n const basePath = path.startsWith('/') ? path : `/${path}`;\n const normalizedPath = trailingSlash\n ? `${basePath}${basePath.endsWith('/') ? '' : '/'}`\n : basePath.replace(/\\/+$/, '') || '/';\n const fullUrl = `${manifest.baseUrl}${normalizedPath}`;\n return lowercase ? fullUrl.toLowerCase() : fullUrl;\n}\n\n/**\n * Extracts all canonical URLs from a site manifest.\n * @param manifest - The site manifest\n * @param options - Canonical URL options\n * @returns Array of canonical URLs\n */\nexport function extractCanonicalUrls(\n manifest: SiteManifest,\n options: CanonicalOptions = {}\n): string[] {\n return manifest.pages.map((page) => generateCanonicalUrl(manifest, page.path, options));\n}\n\n/**\n * Deduplicates URLs by converting to Set and back.\n * @param urls - Array of URLs to deduplicate\n * @returns Array of unique URLs\n */\nexport function dedupeUrls(urls: string[]): string[] {\n return [...new Set(urls)];\n}\n\n/**\n * Builds locale prefix based on strategy.\n * @param locale - The locale code\n * @param strategy - The locale strategy\n * @param defaultLocale - The default locale code\n * @returns Locale prefix string or empty string\n */\nfunction buildLocalePrefix(\n locale: string,\n strategy: LocaleStrategy,\n defaultLocale: string\n): string {\n // No prefix for 'none' strategy\n if (strategy === 'none') {\n return '';\n }\n\n // Subdomain strategy doesn't add path prefix\n if (strategy === 'subdomain') {\n return '';\n }\n\n // For prefix strategy, don't prefix default locale\n if (strategy === 'prefix' && locale === defaultLocale) {\n return '';\n }\n\n return `/${locale}`;\n}\n\n/**\n * Builds base URL with subdomain if needed.\n * @param baseUrl - The base URL\n * @param locale - The locale code\n * @param strategy - The locale strategy\n * @param defaultLocale - The default locale code\n * @returns Base URL with subdomain if applicable\n */\nfunction buildBaseUrlWithSubdomain(\n baseUrl: string,\n locale: string,\n strategy: LocaleStrategy,\n defaultLocale: string\n): string {\n if (strategy !== 'subdomain' || locale === defaultLocale) {\n return baseUrl;\n }\n\n try {\n const parsed = new URL(baseUrl);\n return `${parsed.protocol}//${locale}.${parsed.host}`;\n } catch {\n return baseUrl;\n }\n}\n\n/**\n * Creates a single canonical URL for a manifest item.\n * @param item - The manifest item\n * @param options - Options for URL creation (without items array)\n * @returns The canonical URL string\n */\nexport function createCanonicalUrlForItem(\n item: ManifestItem,\n options: Omit<CreateCanonicalUrlsOptions, 'items'>\n): string {\n const { baseUrl, routePrefix, defaultLocale, trailingSlash, localeStrategy } = options;\n\n // If item has canonicalOverride, use it directly\n if (item.canonicalOverride && typeof item.canonicalOverride === 'string') {\n return item.canonicalOverride;\n }\n\n // Select canonical locale for this item\n const availableLocales = item.locales ?? [defaultLocale];\n const canonicalLocale = selectCanonicalLocale({\n defaultLocale,\n availableLocales,\n });\n\n // If no locale available, use default\n const locale = canonicalLocale ?? defaultLocale;\n\n // Build URL parts\n const localePrefix = buildLocalePrefix(locale, localeStrategy, defaultLocale);\n const effectiveBaseUrl = buildBaseUrlWithSubdomain(baseUrl, locale, localeStrategy, defaultLocale);\n\n // Build the path\n const parts: string[] = [];\n if (localePrefix) {\n parts.push(localePrefix);\n }\n if (routePrefix) {\n parts.push(routePrefix);\n }\n parts.push(item.slug);\n\n const fullPath = joinUrlParts(...parts);\n\n // Normalize the URL\n return normalizeUrl({\n baseUrl: effectiveBaseUrl,\n path: fullPath,\n trailingSlash,\n stripQuery: true,\n stripHash: true,\n });\n}\n\n/**\n * Creates canonical URLs from manifest items:\n * 1. For each item, select canonical locale\n * 2. Build URL: baseUrl + localePrefix (if strategy=prefix) + routePrefix + slug\n * 3. Apply trailing slash policy\n * 4. Normalize URL\n * 5. Dedupe (by URL string)\n * 6. Sort stably\n * @param options - Options for URL creation\n * @returns Sorted array of canonical URLs\n */\nexport function createCanonicalUrlsFromManifest(options: CreateCanonicalUrlsOptions): string[] {\n const { items } = options;\n\n // Handle empty items\n if (!items || items.length === 0) {\n return [];\n }\n\n // Create URLs for each item\n const urls = items.map((item) => createCanonicalUrlForItem(item, options));\n\n // Deduplicate\n const deduped = dedupeUrls(urls);\n\n // Sort stably by path\n return sortUrlsByPath(deduped);\n}\n","/**\n * llms.txt generator for LLM-optimized site documentation.\n * Generates a short brand profile with sections, URLs, policies, and contact info.\n */\n\nimport type { LlmsSeoConfig } from '../../schema/config.schema.js';\nimport { sortStrings } from '../normalize/sort.js';\nimport { normalizeLineEndings, normalizeLineWhitespace } from '../normalize/text.js';\n\n/**\n * Options for llms.txt generation.\n */\nexport interface CreateLlmsTxtOptions {\n /** Full LLM SEO configuration */\n config: LlmsSeoConfig;\n /** Pre-built canonical URLs from manifests */\n canonicalUrls: string[];\n}\n\n/**\n * Result of llms.txt generation.\n */\nexport interface CreateLlmsTxtResult {\n /** Generated llms.txt content */\n content: string;\n /** Size in bytes */\n byteSize: number;\n /** Number of lines */\n lineCount: number;\n}\n\n/**\n * Creates llms.txt content with deterministic output.\n * - Deterministic ordering of all sections\n * - Handles missing optional fields gracefully\n * - EOL controlled by config.format.lineEndings\n * @param options - Generation options\n * @returns Generated content with metadata\n */\nexport function createLlmsTxt(options: CreateLlmsTxtOptions): CreateLlmsTxtResult {\n const { config, canonicalUrls } = options;\n const lineEndings = config.format?.lineEndings ?? 'lf';\n const lines: string[] = [];\n\n // Header: Brand name and tagline\n lines.push(`# ${config.brand.name}`);\n lines.push('');\n\n if (config.brand.tagline) {\n lines.push(`> ${config.brand.tagline}`);\n lines.push('');\n }\n\n // Brand description\n if (config.brand.description) {\n lines.push(config.brand.description);\n lines.push('');\n }\n\n // Sections\n const hubs = config.sections?.hubs ?? [];\n if (hubs.length > 0) {\n lines.push('## Sections');\n lines.push('');\n const sortedHubs = sortStrings(hubs);\n for (const hub of sortedHubs) {\n const hubLabel = getHubLabel(hub);\n lines.push(`- [${hub}](${hub}) - ${hubLabel}`);\n }\n lines.push('');\n }\n\n // URLs\n if (canonicalUrls.length > 0) {\n lines.push('## URLs');\n lines.push('');\n const sortedUrls = sortStrings(canonicalUrls);\n for (const url of sortedUrls) {\n lines.push(`- ${url}`);\n }\n lines.push('');\n }\n\n // Policies\n const hasPolicies = config.policy?.geoPolicy || config.policy?.citationRules || config.policy?.restrictedClaims;\n if (hasPolicies) {\n lines.push('## Policies');\n lines.push('');\n\n if (config.policy?.geoPolicy) {\n lines.push(`- GEO: ${config.policy.geoPolicy}`);\n }\n\n if (config.policy?.citationRules) {\n lines.push(`- Citations: ${config.policy.citationRules}`);\n }\n\n if (config.policy?.restrictedClaims) {\n const status = config.policy.restrictedClaims.enable ? 'Enabled' : 'Disabled';\n lines.push(`- Restricted Claims: ${status}`);\n }\n\n lines.push('');\n }\n\n // Contact\n const hasContact = config.contact?.email || config.contact?.social || config.contact?.phone;\n const hasBooking = config.booking?.url;\n if (hasContact || hasBooking) {\n lines.push('## Contact');\n lines.push('');\n\n if (config.contact?.email) {\n lines.push(`- Email: ${config.contact.email}`);\n }\n\n if (config.contact?.phone) {\n lines.push(`- Phone: ${config.contact.phone}`);\n }\n\n if (config.contact?.social) {\n if (config.contact.social.twitter) {\n lines.push(`- Twitter: ${config.contact.social.twitter}`);\n }\n if (config.contact.social.linkedin) {\n lines.push(`- LinkedIn: ${config.contact.social.linkedin}`);\n }\n if (config.contact.social.github) {\n lines.push(`- GitHub: ${config.contact.social.github}`);\n }\n }\n\n if (config.booking?.url) {\n const label = config.booking.label ?? 'Book consultation';\n lines.push(`- Booking: ${config.booking.url} (${label})`);\n }\n\n lines.push('');\n }\n\n // Machine Hints\n const hasMachineHints = config.machineHints?.robots || \n config.machineHints?.sitemap || \n config.machineHints?.llmsTxt || \n config.machineHints?.llmsFullTxt;\n \n if (hasMachineHints) {\n lines.push('## Machine Hints');\n lines.push('');\n\n if (config.machineHints?.robots) {\n lines.push(`- robots.txt: ${config.machineHints.robots}`);\n }\n\n if (config.machineHints?.sitemap) {\n lines.push(`- sitemap.xml: ${config.machineHints.sitemap}`);\n }\n\n if (config.machineHints?.llmsTxt) {\n lines.push(`- llms.txt: ${config.machineHints.llmsTxt}`);\n }\n\n if (config.machineHints?.llmsFullTxt) {\n lines.push(`- llms-full.txt: ${config.machineHints.llmsFullTxt}`);\n }\n\n lines.push('');\n }\n\n // Build final content\n let content = lines.join('\\n');\n \n // Normalize whitespace\n content = normalizeLineWhitespace(content);\n \n // Apply line endings\n content = normalizeLineEndings(content, lineEndings);\n\n // Calculate metadata\n const finalLines = content.split(lineEndings === 'crlf' ? '\\r\\n' : '\\n');\n\n return {\n content,\n byteSize: Buffer.byteLength(content, 'utf-8'),\n lineCount: finalLines.length,\n };\n}\n\n/**\n * Gets a human-readable label for a hub path.\n */\nfunction getHubLabel(hub: string): string {\n const labels: Record<string, string> = {\n '/services': 'Services overview',\n '/blog': 'Blog posts',\n '/projects': 'Our projects',\n '/cases': 'Case studies',\n '/contact': 'Contact us',\n '/about': 'About us',\n '/products': 'Products',\n '/docs': 'Documentation',\n '/faq': 'Frequently asked questions',\n '/pricing': 'Pricing information',\n '/team': 'Our team',\n '/careers': 'Career opportunities',\n '/news': 'News and updates',\n '/resources': 'Resources',\n '/support': 'Support center',\n };\n\n return labels[hub] ?? formatHubLabel(hub);\n}\n\n/**\n * Formats a hub path into a human-readable label.\n */\nfunction formatHubLabel(hub: string): string {\n // Remove leading slash and format\n const clean = hub.replace(/^\\//, '');\n // Replace hyphens and underscores with spaces, capitalize words\n return clean\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n// Legacy exports for backwards compatibility\nexport interface LlmsTxtOptions {\n /** Whether to include optional sections */\n includeOptionalSections?: boolean;\n}\n\n/**\n * @deprecated Use createLlmsTxt instead\n */\nexport function generateLlmsTxt(\n manifest: { baseUrl: string; title: string; description?: string | undefined; pages: Array<{ path: string; title?: string | undefined; description?: string | undefined }> },\n _options?: LlmsTxtOptions\n): string {\n const canonicalUrls = manifest.pages.map((page) => `${manifest.baseUrl}${page.path}`);\n \n const config: LlmsSeoConfig = {\n site: { baseUrl: manifest.baseUrl },\n brand: {\n name: manifest.title,\n locales: ['en'],\n ...(manifest.description && { description: manifest.description }),\n },\n manifests: {},\n output: {\n paths: {\n llmsTxt: 'public/llms.txt',\n llmsFullTxt: 'public/llms-full.txt',\n },\n },\n };\n\n return createLlmsTxt({ config, canonicalUrls }).content;\n}\n","/**\n * llms-full.txt generator with complete context for LLMs.\n * Generates full brand context with all URLs, detailed policies, social/booking, and machine hints.\n */\n\nimport type { LlmsSeoConfig } from '../../schema/config.schema.js';\nimport type { ManifestItem } from '../../schema/manifest.schema.js';\nimport { sortStrings, sortBy } from '../normalize/sort.js';\nimport { normalizeLineEndings, normalizeLineWhitespace } from '../normalize/text.js';\n\n/**\n * Options for llms-full.txt generation.\n */\nexport interface CreateLlmsFullTxtOptions {\n /** Full LLM SEO configuration */\n config: LlmsSeoConfig;\n /** Pre-built canonical URLs from manifests */\n canonicalUrls: string[];\n /** Manifest items for detailed URL listing */\n manifestItems: ManifestItem[];\n}\n\n/**\n * Result of llms-full.txt generation.\n */\nexport interface CreateLlmsFullTxtResult {\n /** Generated llms-full.txt content */\n content: string;\n /** Size in bytes */\n byteSize: number;\n /** Number of lines */\n lineCount: number;\n}\n\n/**\n * Creates llms-full.txt content with deterministic output.\n * - Complete context with all URLs\n * - Detailed policy sections\n * - Social and booking info\n * - EOL controlled by config.format.lineEndings\n * @param options - Generation options\n * @returns Generated content with metadata\n */\nexport function createLlmsFullTxt(options: CreateLlmsFullTxtOptions): CreateLlmsFullTxtResult {\n const { config, canonicalUrls, manifestItems } = options;\n const lineEndings = config.format?.lineEndings ?? 'lf';\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${config.brand.name} - Full LLM Context`);\n lines.push('');\n\n if (config.brand.tagline) {\n lines.push(`> ${config.brand.tagline}`);\n lines.push('');\n }\n\n // Brand description\n if (config.brand.description) {\n lines.push(config.brand.description);\n lines.push('');\n }\n\n // Organization and locales\n if (config.brand.org) {\n lines.push(`Organization: ${config.brand.org}`);\n }\n lines.push(`Locales: ${config.brand.locales.join(', ')}`);\n lines.push('');\n\n // All Canonical URLs\n if (canonicalUrls.length > 0) {\n lines.push('## All Canonical URLs');\n lines.push('');\n const sortedUrls = sortStrings(canonicalUrls);\n for (const url of sortedUrls) {\n lines.push(`- ${url}`);\n }\n lines.push('');\n }\n\n // Policies\n const hasPolicies = config.policy?.geoPolicy || config.policy?.citationRules || config.policy?.restrictedClaims;\n if (hasPolicies) {\n lines.push('## Policies');\n lines.push('');\n\n // GEO Policy\n if (config.policy?.geoPolicy) {\n lines.push('### GEO Policy');\n lines.push(config.policy.geoPolicy);\n lines.push('');\n }\n\n // Citation Rules\n if (config.policy?.citationRules) {\n lines.push('### Citation Rules');\n lines.push(config.policy.citationRules);\n lines.push('');\n }\n\n // Restricted Claims\n if (config.policy?.restrictedClaims) {\n lines.push('### Restricted Claims');\n const status = config.policy.restrictedClaims.enable ? 'Enabled' : 'Disabled';\n lines.push(`Status: ${status}`);\n \n if (config.policy.restrictedClaims.forbidden && config.policy.restrictedClaims.forbidden.length > 0) {\n lines.push(`Forbidden terms: ${config.policy.restrictedClaims.forbidden.join(', ')}`);\n }\n \n if (config.policy.restrictedClaims.whitelist && config.policy.restrictedClaims.whitelist.length > 0) {\n lines.push(`Exceptions: ${config.policy.restrictedClaims.whitelist.join(', ')}`);\n }\n \n lines.push('');\n }\n }\n\n // Social & Booking\n const hasSocial = config.contact?.social?.twitter || \n config.contact?.social?.linkedin || \n config.contact?.social?.github;\n const hasBooking = config.booking?.url;\n \n if (hasSocial || hasBooking) {\n lines.push('## Social & Booking');\n lines.push('');\n\n if (config.contact?.social?.twitter) {\n lines.push(`- Twitter: ${config.contact.social.twitter}`);\n }\n\n if (config.contact?.social?.linkedin) {\n lines.push(`- LinkedIn: ${config.contact.social.linkedin}`);\n }\n\n if (config.contact?.social?.github) {\n lines.push(`- GitHub: ${config.contact.social.github}`);\n }\n\n if (config.booking?.url) {\n const label = config.booking.label ?? 'Book consultation';\n lines.push(`- Booking: ${config.booking.url} (${label})`);\n }\n\n lines.push('');\n }\n\n // Machine Hints\n const hasMachineHints = config.machineHints?.robots || \n config.machineHints?.sitemap || \n config.machineHints?.llmsTxt || \n config.machineHints?.llmsFullTxt;\n \n if (hasMachineHints) {\n lines.push('## Machine Hints');\n lines.push('');\n\n if (config.machineHints?.robots) {\n lines.push(`- robots.txt: ${config.machineHints.robots}`);\n }\n\n if (config.machineHints?.sitemap) {\n lines.push(`- sitemap.xml: ${config.machineHints.sitemap}`);\n }\n\n if (config.machineHints?.llmsTxt) {\n lines.push(`- llms.txt: ${config.machineHints.llmsTxt}`);\n }\n\n if (config.machineHints?.llmsFullTxt) {\n lines.push(`- llms-full.txt: ${config.machineHints.llmsFullTxt}`);\n }\n\n lines.push('');\n }\n\n // Sitemap\n const hubs = config.sections?.hubs ?? [];\n if (hubs.length > 0 || manifestItems.length > 0) {\n lines.push('## Sitemap');\n lines.push('');\n\n // Add section hubs first\n if (hubs.length > 0) {\n const sortedHubs = sortStrings(hubs);\n for (const hub of sortedHubs) {\n lines.push(`- [${hub}](${hub}) - ${getHubLabel(hub)}`);\n }\n }\n\n // Add all manifest URLs\n if (manifestItems.length > 0) {\n const sortedItems = sortBy(manifestItems, (item) => item.slug);\n for (const item of sortedItems) {\n const url = item.canonicalOverride ?? `${config.site.baseUrl}${item.slug}`;\n const title = item.title ?? item.slug;\n const locales = item.locales?.join(', ') ?? config.brand.locales[0] ?? 'en';\n lines.push(`- [${title}](${url}) (${locales})`);\n }\n }\n\n lines.push('');\n }\n\n // Build final content\n let content = lines.join('\\n');\n \n // Normalize whitespace\n content = normalizeLineWhitespace(content);\n \n // Apply line endings\n content = normalizeLineEndings(content, lineEndings);\n\n // Calculate metadata\n const finalLines = content.split(lineEndings === 'crlf' ? '\\r\\n' : '\\n');\n\n return {\n content,\n byteSize: Buffer.byteLength(content, 'utf-8'),\n lineCount: finalLines.length,\n };\n}\n\n/**\n * Gets a human-readable label for a hub path.\n */\nfunction getHubLabel(hub: string): string {\n const labels: Record<string, string> = {\n '/services': 'Services overview',\n '/blog': 'Blog posts',\n '/projects': 'Our projects',\n '/cases': 'Case studies',\n '/contact': 'Contact us',\n '/about': 'About us',\n '/products': 'Products',\n '/docs': 'Documentation',\n '/faq': 'Frequently asked questions',\n '/pricing': 'Pricing information',\n '/team': 'Our team',\n '/careers': 'Career opportunities',\n '/news': 'News and updates',\n '/resources': 'Resources',\n '/support': 'Support center',\n };\n\n return labels[hub] ?? formatHubLabel(hub);\n}\n\n/**\n * Formats a hub path into a human-readable label.\n */\nfunction formatHubLabel(hub: string): string {\n // Remove leading slash and format\n const clean = hub.replace(/^\\//, '');\n // Replace hyphens and underscores with spaces, capitalize words\n return clean\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n// Legacy exports for backwards compatibility\nexport interface LlmsFullTxtOptions {\n /** Maximum content length per page (0 = no limit) */\n maxContentLength?: number;\n}\n\n/**\n * Generates full page content for llms-full.txt.\n * @deprecated Use createLlmsFullTxt instead\n */\nexport function generatePageContent(\n page: { path: string; title?: string; description?: string; content?: string },\n manifest: { baseUrl: string },\n _options?: LlmsFullTxtOptions\n): string {\n const maxContentLength = _options?.maxContentLength ?? 0;\n const lines: string[] = [];\n const url = `${manifest.baseUrl}${page.path}`;\n lines.push(`## ${page.title ?? page.path}`);\n lines.push(`URL: ${url}`);\n lines.push('');\n \n if (page.description) {\n lines.push(page.description);\n lines.push('');\n }\n \n if (page.content) {\n let content = page.content;\n if (maxContentLength > 0 && content.length > maxContentLength) {\n content = `${content.slice(0, maxContentLength)}...`;\n }\n lines.push(content);\n lines.push('');\n }\n \n return lines.join('\\n');\n}\n\n/**\n /**\n * @deprecated Use createLlmsFullTxt instead\n */\n export function generateLlmsFullTxt(\n manifest: { baseUrl: string; title: string; description?: string | undefined; pages: Array<{ path: string; title?: string | undefined; description?: string | undefined; content?: string | undefined }> },\n _options?: LlmsFullTxtOptions\n ): string {\n const canonicalUrls = manifest.pages.map((page) => `${manifest.baseUrl}${page.path}`);\n const manifestItems: ManifestItem[] = manifest.pages.map((page) => ({\n slug: page.path,\n title: page.title,\n description: page.description,\n }));\n \n const config: LlmsSeoConfig = {\n site: { baseUrl: manifest.baseUrl },\n brand: {\n name: manifest.title,\n locales: ['en'],\n ...(manifest.description && { description: manifest.description }),\n },\n manifests: {},\n output: {\n paths: {\n llmsTxt: 'public/llms.txt',\n llmsFullTxt: 'public/llms-full.txt',\n },\n },\n };\n \n return createLlmsFullTxt({ config, canonicalUrls, manifestItems }).content;\n }","/**\n * Citation generation utilities for LLM-optimized content.\n * Creates machine-readable citations.json for CI validation.\n */\n\nimport type { LlmsSeoConfig } from '../../schema/config.schema.js';\nimport type { ManifestItem } from '../../schema/manifest.schema.js';\n\n/**\n * Citation source entry.\n */\nexport interface CitationSource {\n /** Canonical URL */\n url: string;\n /** Priority (0-100) */\n priority: number;\n /** Section name */\n section: string;\n /** Locale code */\n locale: string;\n /** Publication date (ISO 8601) */\n publishedAt?: string;\n /** Last update date (ISO 8601) */\n updatedAt?: string;\n /** Page title */\n title?: string;\n}\n\n/**\n * Site information in citations.json.\n */\nexport interface CitationsSite {\n /** Base URL */\n baseUrl: string;\n /** Site name */\n name: string;\n}\n\n/**\n * Policy information in citations.json.\n */\nexport interface CitationsPolicy {\n /** Geographic policy */\n geoPolicy?: string;\n /** Citation rules */\n citationRules?: string;\n /** Whether restricted claims are enabled */\n restrictedClaimsEnabled: boolean;\n}\n\n/**\n * Complete citations.json structure.\n */\nexport interface CitationsJson {\n /** Schema version */\n version: string;\n /** Generation timestamp (ISO 8601) */\n generated: string;\n /** Site information */\n site: CitationsSite;\n /** Sorted citation sources */\n sources: CitationSource[];\n /** Policy information */\n policy: CitationsPolicy;\n}\n\n/**\n * Options for citations.json generation.\n */\nexport interface CreateCitationsJsonOptions {\n /** Full LLM SEO configuration */\n config: LlmsSeoConfig;\n /** Manifest items to include */\n manifestItems: ManifestItem[];\n /** Section name for these items */\n sectionName: string;\n /** Optional fixed timestamp for deterministic output (tests) */\n fixedTimestamp?: string;\n}\n\n/**\n * Creates citations.json object with deterministic output.\n * - Sorted by priority (descending), then by URL\n * - Includes all manifest items with their metadata\n * @param options - Generation options\n * @returns Citations JSON object\n */\nexport function createCitationsJson(options: CreateCitationsJsonOptions): CitationsJson {\n const { config, manifestItems, sectionName, fixedTimestamp } = options;\n\n // Build sources from manifest items\n const sources: CitationSource[] = manifestItems.map((item) => {\n const url = item.canonicalOverride ?? `${config.site.baseUrl}${item.slug}`;\n const defaultLocale = config.site.defaultLocale ?? config.brand.locales[0] ?? 'en';\n \n return {\n url,\n priority: item.priority ?? 50,\n section: sectionName,\n locale: item.locales?.[0] ?? defaultLocale,\n ...(item.publishedAt && { publishedAt: item.publishedAt }),\n ...(item.updatedAt && { updatedAt: item.updatedAt }),\n ...(item.title && { title: item.title }),\n };\n });\n\n // Sort by priority (descending), then by URL (ascending)\n const sortedSources = sources.sort((a, b) => {\n // First by priority descending\n if (a.priority !== b.priority) {\n return b.priority - a.priority;\n }\n // Then by URL ascending\n return a.url.localeCompare(b.url, 'en', { sensitivity: 'case', numeric: true });\n });\n\n // Build policy\n const policy: CitationsPolicy = {\n restrictedClaimsEnabled: config.policy?.restrictedClaims?.enable ?? false,\n ...(config.policy?.geoPolicy && { geoPolicy: config.policy.geoPolicy }),\n ...(config.policy?.citationRules && { citationRules: config.policy.citationRules }),\n };\n\n return {\n version: '1.0',\n generated: fixedTimestamp ?? new Date().toISOString(),\n site: {\n baseUrl: config.site.baseUrl,\n name: config.brand.name,\n },\n sources: sortedSources,\n policy,\n };\n}\n\n/**\n * Creates citations.json as a formatted string.\n * @param options - Generation options\n * @returns JSON string with 2-space indentation\n */\nexport function createCitationsJsonString(options: CreateCitationsJsonOptions): string {\n const citations = createCitationsJson(options);\n return JSON.stringify(citations, null, 2);\n}\n\n// Legacy exports for backwards compatibility\n\n/**\n * Represents a citation for a page.\n * @deprecated Use CitationSource instead\n */\nexport interface Citation {\n /** The URL being cited */\n url: string;\n /** The title of the cited page */\n title: string;\n /** Optional description */\n description?: string;\n}\n\n/**\n * Generates a citation object for a page.\n * @deprecated Use createCitationsJson instead\n */\nexport function createCitation(\n page: { path: string; title?: string; description?: string },\n manifest: { baseUrl: string }\n): Citation {\n const citation: Citation = {\n url: `${manifest.baseUrl}${page.path}`,\n title: page.title ?? page.path,\n };\n \n if (page.description) {\n citation.description = page.description;\n }\n \n return citation;\n}\n\n/**\n * Generates a citation in markdown format.\n * @deprecated\n */\nexport function citationToMarkdown(citation: Citation): string {\n if (citation.description) {\n return `[${citation.title}](${citation.url}) - ${citation.description}`;\n }\n return `[${citation.title}](${citation.url})`;\n}\n\n/**\n * Generates a citation in JSON-LD format.\n * @deprecated\n */\nexport function citationToJsonLd(citation: Citation): Record<string, string> {\n const jsonLd: Record<string, string> = {\n '@type': 'WebPage',\n name: citation.title,\n url: citation.url,\n };\n \n if (citation.description) {\n jsonLd.description = citation.description;\n }\n \n return jsonLd;\n}\n\n/**\n * Generates a reference list from multiple citations.\n * @deprecated\n */\nexport function generateReferenceList(citations: readonly Citation[]): string {\n const lines: string[] = ['## References', ''];\n \n for (let i = 0; i < citations.length; i++) {\n const citation = citations[i];\n if (citation) {\n const num = i + 1;\n lines.push(`${num}. ${citationToMarkdown(citation)}`);\n }\n }\n \n lines.push('');\n return lines.join('\\n');\n}\n","/**\n * Issue types and utilities for SEO checking.\n */\n\n/**\n * Severity levels for issues.\n */\nexport type IssueSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Categories of SEO issues.\n */\nexport type IssueCategory = \n | 'content'\n | 'structure'\n | 'accessibility'\n | 'performance'\n | 'metadata';\n\n/**\n * Represents a check issue found during file verification.\n */\nexport interface CheckIssue {\n /** File path or config path */\n path: string;\n /** Issue code e.g., 'file_mismatch', 'missing_file' */\n code: CheckIssueCode;\n /** Human-readable message describing the issue */\n message: string;\n /** Severity of the issue */\n severity: IssueSeverity;\n /** Optional line number where the issue was found */\n line?: number;\n /** Context snippet (first N lines or relevant content) */\n context?: string;\n}\n\n/**\n * Issue codes for check issues.\n */\nexport type CheckIssueCode =\n // File issues\n | 'file_missing'\n | 'file_mismatch'\n | 'file_empty'\n // Content issues\n | 'forbidden_term'\n | 'empty_section'\n | 'duplicate_url'\n | 'invalid_url'\n // Config issues\n | 'config_invalid';\n\n/**\n * Legacy Issue interface for backwards compatibility.\n */\nexport interface Issue {\n /** Unique identifier for the issue type */\n id: string;\n /** The page or resource this issue applies to */\n pageId: string;\n /** Severity of the issue */\n severity: IssueSeverity;\n /** Human-readable message describing the issue */\n message: string;\n /** Optional category for grouping */\n category?: IssueCategory;\n /** Optional suggestion for fixing the issue */\n suggestion?: string;\n /** Optional line number where the issue was found */\n line?: number;\n /** Optional column number where the issue was found */\n column?: number;\n}\n\n/**\n * Creates a CheckIssue.\n * @param severity - Issue severity\n * @param code - Issue code\n * @param message - Human-readable message\n * @param path - File path (optional, defaults to empty string)\n * @param context - Context snippet (optional)\n * @returns A CheckIssue object\n */\nexport function createCheckIssue(\n severity: IssueSeverity,\n code: CheckIssueCode,\n message: string,\n path = '',\n context?: string\n): CheckIssue {\n const issue: CheckIssue = {\n path,\n code,\n message,\n severity,\n };\n \n if (context !== undefined) {\n issue.context = context;\n }\n \n return issue;\n}\n\n/**\n * Creates a legacy Issue with default values.\n * @param overrides - Partial issue to override defaults\n * @returns A complete issue object\n */\nexport function createIssue(overrides: Partial<Issue> & Pick<Issue, 'id' | 'pageId' | 'severity' | 'message'>): Issue {\n return {\n category: 'content',\n ...overrides,\n };\n}\n\n/**\n * Converts legacy Issue to CheckIssue.\n * @param issue - Legacy issue\n * @param path - File path\n * @returns CheckIssue object\n */\nexport function issueToCheckIssue(issue: Issue, path: string): CheckIssue {\n const checkIssue: CheckIssue = {\n path,\n code: issue.id as CheckIssueCode,\n message: issue.message,\n severity: issue.severity,\n };\n \n if (issue.line !== undefined) {\n checkIssue.line = issue.line;\n }\n \n if (issue.suggestion !== undefined) {\n checkIssue.context = issue.suggestion;\n }\n \n return checkIssue;\n}\n\n/**\n * Groups check issues by severity.\n * @param issues - List of issues\n * @returns Map of severity to issues\n */\nexport function groupCheckIssuesBySeverity(issues: readonly CheckIssue[]): Map<IssueSeverity, CheckIssue[]> {\n const grouped = new Map<IssueSeverity, CheckIssue[]>();\n \n for (const issue of issues) {\n const existing = grouped.get(issue.severity) ?? [];\n existing.push(issue);\n grouped.set(issue.severity, existing);\n }\n \n return grouped;\n}\n\n/**\n * Groups issues by severity (legacy).\n * @param issues - List of issues\n * @returns Map of severity to issues\n */\nexport function groupBySeverity(issues: readonly Issue[]): Map<IssueSeverity, Issue[]> {\n const grouped = new Map<IssueSeverity, Issue[]>();\n \n for (const issue of issues) {\n const existing = grouped.get(issue.severity) ?? [];\n existing.push(issue);\n grouped.set(issue.severity, existing);\n }\n \n return grouped;\n}\n\n/**\n * Groups issues by page.\n * @param issues - List of issues\n * @returns Map of pageId to issues\n */\nexport function groupByPage(issues: readonly Issue[]): Map<string, Issue[]> {\n const grouped = new Map<string, Issue[]>();\n \n for (const issue of issues) {\n const existing = grouped.get(issue.pageId) ?? [];\n existing.push(issue);\n grouped.set(issue.pageId, existing);\n }\n \n return grouped;\n}\n\n/**\n * Filters issues by minimum severity.\n * @param issues - List of issues\n * @param minSeverity - Minimum severity to include\n * @returns Filtered list of issues\n */\nexport function filterBySeverity(issues: readonly Issue[], minSeverity: IssueSeverity): Issue[] {\n const severityOrder: IssueSeverity[] = ['error', 'warning', 'info'];\n const minIndex = severityOrder.indexOf(minSeverity);\n \n return issues.filter((issue) => {\n const issueIndex = severityOrder.indexOf(issue.severity);\n return issueIndex <= minIndex;\n });\n}\n\n/**\n * Counts issues by severity.\n * @param issues - List of check issues\n * @returns Counts for each severity level\n */\nexport function countSeverities(issues: readonly CheckIssue[]): Record<IssueSeverity, number> {\n const counts: Record<IssueSeverity, number> = {\n error: 0,\n warning: 0,\n info: 0,\n };\n \n for (const issue of issues) {\n counts[issue.severity]++;\n }\n \n return counts;\n}\n\n/**\n * Formats a check issue for display.\n * @param issue - Check issue to format\n * @returns Formatted string\n */\nexport function formatCheckIssue(issue: CheckIssue): string {\n const severityLabel = issue.severity.charAt(0).toUpperCase() + issue.severity.slice(1);\n let output = `${severityLabel}: ${issue.code}\\n`;\n output += ` File: ${issue.path}\\n`;\n \n if (issue.line !== undefined) {\n output += ` Line: ${issue.line}\\n`;\n }\n \n output += ` Message: ${issue.message}`;\n \n if (issue.context) {\n output += `\\n Context: \"${issue.context}\"`;\n }\n \n return output;\n}\n\n/**\n * Formats multiple check issues for display.\n * @param issues - Check issues to format\n * @returns Formatted string\n */\nexport function formatCheckIssues(issues: CheckIssue[]): string {\n return issues.map(formatCheckIssue).join('\\n\\n');\n}\n","/**\n * Rules linter for llms.txt and related files.\n */\n\nimport type { Issue } from './issues.js';\nimport type { LlmsSeoConfig } from '../../schema/config.schema.js';\nimport { createIssue } from './issues.js';\nimport type { CheckIssue } from './issues.js';\n\n/**\n * Rule definition for linting.\n */\nexport interface LintRule {\n /** Unique rule identifier */\n id: string;\n /** Human-readable description */\n description: string;\n /** Whether the rule is enabled by default */\n enabled: boolean;\n /** The lint function */\n lint: (content: string, filePath: string) => Issue[];\n}\n\n/**\n * Options for linting content.\n */\nexport interface LintOptions {\n /** llms.txt or llms-full.txt content */\n content: string;\n /** LLM-SEO configuration */\n config: LlmsSeoConfig;\n}\n\n/**\n * Result of linting content.\n */\nexport interface LintResult {\n /** Issues found during linting */\n issues: CheckIssue[];\n}\n\n/**\n * Available lint rules.\n */\nexport const LINT_RULES: readonly LintRule[] = [\n {\n id: 'heading-structure',\n description: 'Ensures proper heading structure (h1 -> h2 -> h3)',\n enabled: true,\n lint: lintHeadingStructure,\n },\n {\n id: 'url-format',\n description: 'Validates URL format in links',\n enabled: true,\n lint: lintUrlFormat,\n },\n {\n id: 'trailing-whitespace',\n description: 'Checks for trailing whitespace on lines',\n enabled: true,\n lint: lintTrailingWhitespace,\n },\n {\n id: 'consistent-list-markers',\n description: 'Ensures consistent list marker usage',\n enabled: true,\n lint: lintListMarkers,\n },\n];\n\n/**\n * Lints content against provided rules.\n * @param content - The content to lint\n * @param filePath - Path to the file being linted\n * @param rules - Rules to apply (defaults to all enabled rules)\n * @returns Lint result with issues\n */\nexport function lintContent(\n content: string,\n filePath: string,\n rules: readonly LintRule[] = LINT_RULES.filter((r) => r.enabled)\n): LintResultLegacy {\n const issues: Issue[] = [];\n \n for (const rule of rules) {\n const ruleIssues = rule.lint(content, filePath);\n issues.push(...ruleIssues);\n }\n \n return {\n filePath,\n issues,\n passed: issues.filter((i) => i.severity === 'error').length === 0,\n };\n}\n\n/**\n * Legacy lint result interface.\n */\nexport interface LintResultLegacy {\n /** File path that was linted */\n filePath: string;\n /** Issues found during linting */\n issues: Issue[];\n /** Whether the file passed all rules */\n passed: boolean;\n}\n\n/**\n * Lints content against policy rules:\n * - Forbidden terms (if restrictedClaims.enable)\n * - Empty sections\n * - Duplicate URLs in priority lists\n * - Locale consistency between sections\n * \n * @param options - Lint options\n * @returns Lint result with issues\n */\nexport function lintContentWithConfig(options: LintOptions): LintResult {\n const { content, config } = options;\n const issues: CheckIssue[] = [];\n \n // Check forbidden terms if policy is configured\n if (config.policy?.restrictedClaims?.enable) {\n const forbidden = config.policy.restrictedClaims.forbidden ?? [];\n const whitelist = config.policy.restrictedClaims.whitelist ?? [];\n const forbiddenIssues = checkForbiddenTerms(content, forbidden, whitelist);\n issues.push(...forbiddenIssues);\n }\n \n // Check for empty sections\n const emptySectionIssues = checkEmptySections(content);\n issues.push(...emptySectionIssues);\n \n // Check for duplicate URLs\n const duplicateUrlIssues = checkDuplicateUrls(content);\n issues.push(...duplicateUrlIssues);\n \n return { issues };\n}\n\n/**\n * Checks for forbidden terms in content.\n * @param content - Content to check\n * @param forbidden - List of forbidden terms\n * @param whitelist - List of whitelisted terms (case-insensitive)\n * @returns Array of check issues\n */\nexport function checkForbiddenTerms(\n content: string,\n forbidden: string[],\n whitelist: string[] = []\n): CheckIssue[] {\n const issues: CheckIssue[] = [];\n const lines = content.split('\\n');\n const whitelistLower = whitelist.map((w) => w.toLowerCase());\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) continue;\n const trimmed = line.trim();\n const loweredTrimmed = trimmed.toLowerCase();\n\n // Do not lint policy definition lines that explicitly list forbidden/allowed terms.\n if (\n loweredTrimmed.startsWith('forbidden terms:') ||\n loweredTrimmed.startsWith('exceptions:')\n ) {\n continue;\n }\n \n for (const term of forbidden) {\n const termLower = term.toLowerCase();\n const lineLower = line.toLowerCase();\n \n // Check if term exists in line\n if (lineLower.includes(termLower)) {\n // Check if it's whitelisted\n const isWhitelisted = whitelistLower.some((w) => \n lineLower.includes(w) && w.includes(termLower)\n );\n \n if (!isWhitelisted) {\n issues.push({\n path: '',\n code: 'forbidden_term',\n message: `Term \"${term}\" is forbidden by policy`,\n severity: 'warning',\n line: i + 1,\n context: trimmed.substring(0, 100),\n });\n }\n }\n }\n }\n \n return issues;\n}\n\n/**\n * Checks for empty sections in content.\n * An empty section is a heading followed only by whitespace/blank lines\n * until the next heading or end of file.\n * Note: The first heading (typically h1 document title) is not checked\n * as it's common to have the title without immediate content.\n * @param content - Content to check\n * @returns Array of check issues\n */\nexport function checkEmptySections(content: string): CheckIssue[] {\n const issues: CheckIssue[] = [];\n const lines = content.split('\\n');\n \n let currentSection: string | null = null;\n let sectionStartLine = 0;\n let sectionHeadingLevel = 0;\n let sectionHasContent = false;\n let sectionWasFirst = false;\n let isFirstHeading = true;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) continue;\n \n // Check for markdown heading\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n \n if (headingMatch?.[2]) {\n const nextHeadingLevel = headingMatch[1]?.length ?? 0;\n\n // A subsection counts as content for its parent section.\n if (currentSection !== null && nextHeadingLevel > sectionHeadingLevel) {\n sectionHasContent = true;\n }\n\n // Check if previous section was empty (had heading but no content)\n // Skip check for the first heading (document title)\n if (currentSection !== null && !sectionHasContent && !sectionWasFirst) {\n issues.push({\n path: '',\n code: 'empty_section',\n message: `Section \"${currentSection}\" has no content`,\n severity: 'info',\n line: sectionStartLine,\n });\n }\n \n // Start new section\n currentSection = headingMatch[2].trim();\n sectionStartLine = i + 1;\n sectionHeadingLevel = nextHeadingLevel;\n sectionHasContent = false;\n sectionWasFirst = isFirstHeading;\n isFirstHeading = false;\n } else if (currentSection !== null) {\n // Non-heading line - check if it has actual content\n if (line.trim().length > 0) {\n sectionHasContent = true;\n }\n }\n }\n \n // Check last section (skip if it's the only/first heading)\n if (currentSection !== null && !sectionHasContent && !sectionWasFirst) {\n issues.push({\n path: '',\n code: 'empty_section',\n message: `Section \"${currentSection}\" has no content`,\n severity: 'info',\n line: sectionStartLine,\n });\n }\n \n return issues;\n}\n\n/**\n * Checks for duplicate URLs in content.\n * @param content - Content to check\n * @returns Array of check issues\n */\nexport function checkDuplicateUrls(content: string): CheckIssue[] {\n const issues: CheckIssue[] = [];\n const lines = content.split('\\n');\n const seenUrls = new Map<string, number>();\n \n // Pattern to match markdown links\n const urlPattern = /\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) continue;\n \n let match: RegExpExecArray | null = urlPattern.exec(line);\n while (match !== null) {\n const url = match[2];\n if (url !== undefined) {\n const firstOccurrence = seenUrls.get(url);\n if (firstOccurrence !== undefined) {\n issues.push({\n path: '',\n code: 'duplicate_url',\n message: `URL \"${url}\" appears multiple times (first at line ${firstOccurrence})`,\n severity: 'warning',\n line: i + 1,\n context: url,\n });\n } else {\n seenUrls.set(url, i + 1);\n }\n }\n match = urlPattern.exec(line);\n }\n \n // Reset regex state for next line\n urlPattern.lastIndex = 0;\n }\n \n return issues;\n}\n\n/**\n * Lints heading structure in markdown content.\n */\nfunction lintHeadingStructure(content: string, filePath: string): Issue[] {\n const issues: Issue[] = [];\n const lines = content.split('\\n');\n let prevLevel = 0;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) continue;\n const match = line.match(/^(#{1,6})\\s/);\n if (match?.[1]) {\n const level = match[1].length;\n if (level > prevLevel + 1 && prevLevel > 0) {\n issues.push(createIssue({\n id: 'heading-skip',\n pageId: filePath,\n severity: 'warning',\n message: `Heading level skipped: h${prevLevel} to h${level}`,\n line: i + 1,\n }));\n }\n prevLevel = level;\n }\n }\n \n return issues;\n}\n\n/**\n * Lints URL format in markdown content.\n */\nfunction lintUrlFormat(content: string, filePath: string): Issue[] {\n const issues: Issue[] = [];\n const lines = content.split('\\n');\n const urlPattern = /\\[([^\\]]*)\\]\\(([^)]+)\\)/g;\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line === undefined) continue;\n let match: RegExpExecArray | null = urlPattern.exec(line);\n while (match !== null) {\n const url = match[2];\n if (url && !url.startsWith('/') && !url.startsWith('http') && !url.startsWith('#')) {\n issues.push(createIssue({\n id: 'invalid-url',\n pageId: filePath,\n severity: 'warning',\n message: `Invalid URL format: ${url}`,\n line: i + 1,\n column: match.index + 1,\n }));\n }\n match = urlPattern.exec(line);\n }\n }\n \n return issues;\n}\n\n/**\n * Lints trailing whitespace in content.\n */\nfunction lintTrailingWhitespace(content: string, filePath: string): Issue[] {\n const issues: Issue[] = [];\n const lines = content.split('\\n');\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line !== undefined && line.endsWith(' ')) {\n issues.push(createIssue({\n id: 'trailing-whitespace',\n pageId: filePath,\n severity: 'info',\n message: 'Line has trailing whitespace',\n line: i + 1,\n }));\n }\n }\n \n return issues;\n}\n\n/**\n * Lints list marker consistency in content.\n */\nfunction lintListMarkers(content: string, filePath: string): Issue[] {\n const issues: Issue[] = [];\n const lines = content.split('\\n');\n const dashCount = lines.filter((l) => /^\\s*-\\s/.test(l)).length;\n const asteriskCount = lines.filter((l) => /^\\s*\\*\\s/.test(l)).length;\n \n if (dashCount > 0 && asteriskCount > 0) {\n issues.push(createIssue({\n id: 'inconsistent-list-markers',\n pageId: filePath,\n severity: 'info',\n message: 'Mix of - and * list markers detected',\n }));\n }\n \n return issues;\n}\n","/**\n * SEO checker for LLM-optimized content validation.\n */\n\nimport * as fs from 'node:fs/promises';\nimport type { LlmsSeoConfig } from '../../schema/config.schema.js';\nimport type { SiteManifest } from '../../schema/manifest.schema.js';\nimport type { Issue, IssueSeverity } from './issues.js';\nimport type { CheckIssue, CheckIssueCode } from './issues.js';\nimport { createCheckIssue, countSeverities } from './issues.js';\nimport { lintContent as lintWithRules, checkForbiddenTerms, checkEmptySections, checkDuplicateUrls } from './rules-linter.js';\nimport { ExitCode } from '../../cli/exit-codes.js';\n\n/**\n * Configuration for the SEO checker.\n */\nexport interface CheckerConfig {\n /** Enable strict mode for additional checks */\n strict?: boolean;\n /** Maximum allowed title length */\n maxTitleLength?: number;\n /** Maximum allowed description length */\n maxDescriptionLength?: number;\n}\n\n/**\n * Options for checking generated files.\n */\nexport interface CheckOptions {\n /** LLM-SEO configuration */\n config: LlmsSeoConfig;\n /** Path to llms.txt (default from config) */\n llmsTxtPath?: string;\n /** Path to llms-full.txt (default from config) */\n llmsFullTxtPath?: string;\n /** Path to citations.json (optional) */\n citationsPath?: string;\n /** Fail threshold */\n failOn: 'warn' | 'error';\n}\n\n/**\n * Result of running the SEO checker.\n */\nexport interface CheckerResult {\n /** Whether all checks passed */\n passed: boolean;\n /** List of issues found */\n issues: Issue[];\n /** Number of pages checked */\n pagesChecked: number;\n /** Summary of issues by severity */\n summary: Record<IssueSeverity, number>;\n}\n\n/**\n * Result of checking generated files.\n */\nexport interface CheckResult {\n /** List of issues found */\n issues: CheckIssue[];\n /** Summary counts */\n summary: {\n errors: number;\n warnings: number;\n info: number;\n filesChecked: number;\n filesMissing: number;\n filesMismatch: number;\n };\n /** Exit code for CI */\n exitCode: ExitCode;\n}\n\n/**\n * Result of content comparison.\n */\nexport interface CompareResult {\n /** Whether content matches */\n match: boolean;\n /** Context showing differences */\n context: string;\n}\n\n/**\n * Default checker configuration.\n */\nexport const DEFAULT_CHECKER_CONFIG: Required<CheckerConfig> = {\n strict: false,\n maxTitleLength: 60,\n maxDescriptionLength: 160,\n};\n\n/**\n * Runs SEO checks on a site manifest.\n * @param manifest - The site manifest to check\n * @param config - Checker configuration\n * @returns Checker result with issues and summary\n */\nexport function checkManifest(\n manifest: SiteManifest,\n config: CheckerConfig = {}\n): CheckerResult {\n const fullConfig = { ...DEFAULT_CHECKER_CONFIG, ...config };\n const issues: Issue[] = [];\n \n // Check each page\n for (const page of manifest.pages) {\n const pageIssues = checkPage(page, fullConfig);\n issues.push(...pageIssues);\n }\n \n // Calculate summary\n const summary: Record<IssueSeverity, number> = {\n error: 0,\n warning: 0,\n info: 0,\n };\n \n for (const issue of issues) {\n summary[issue.severity]++;\n }\n \n return {\n passed: summary.error === 0,\n issues,\n pagesChecked: manifest.pages.length,\n summary,\n };\n}\n\n/**\n * Checks a single page for SEO issues.\n * @param page - The page to check\n * @param config - Checker configuration\n * @returns List of issues found\n */\nfunction checkPage(\n page: { path: string; title?: string | undefined; description?: string | undefined },\n config: Required<CheckerConfig>\n): Issue[] {\n const issues: Issue[] = [];\n const pageId = page.path;\n \n // Check title\n if (!page.title) {\n issues.push({\n id: 'missing-title',\n pageId,\n severity: 'warning',\n message: 'Page is missing a title',\n });\n } else if (page.title.length > config.maxTitleLength) {\n issues.push({\n id: 'title-too-long',\n pageId,\n severity: 'warning',\n message: `Title exceeds ${config.maxTitleLength} characters (${page.title.length})`,\n });\n }\n \n // Check description\n if (!page.description) {\n issues.push({\n id: 'missing-description',\n pageId,\n severity: 'warning',\n message: 'Page is missing a description',\n });\n } else if (page.description.length > config.maxDescriptionLength) {\n issues.push({\n id: 'description-too-long',\n pageId,\n severity: 'info',\n message: `Description exceeds ${config.maxDescriptionLength} characters (${page.description.length})`,\n });\n }\n \n return issues;\n}\n\n/**\n * Main check function:\n * 1. Validates config\n * 2. Reads existing files from disk\n * 3. Compares expected vs actual (if expected content provided)\n * 4. Runs linting rules\n * 5. Returns issues with summary\n * \n * @param options - Check options\n * @returns Check result with issues and exit code\n */\nexport async function checkGeneratedFiles(options: CheckOptions): Promise<CheckResult> {\n const issues: CheckIssue[] = [];\n let filesChecked = 0;\n let filesMissing = 0;\n let filesMismatch = 0;\n \n const { config, failOn } = options;\n \n // Get file paths from config\n const llmsTxtPath = options.llmsTxtPath ?? config.output.paths.llmsTxt;\n const llmsFullTxtPath = options.llmsFullTxtPath ?? config.output.paths.llmsFullTxt;\n const citationsPath = options.citationsPath ?? config.output.paths.citations;\n \n // Check llms.txt\n const llmsTxtResult = await checkFile(llmsTxtPath);\n if (!llmsTxtResult.exists) {\n issues.push(createCheckIssue(\n 'error',\n 'file_missing',\n `Required file does not exist: ${llmsTxtPath}`,\n llmsTxtPath\n ));\n filesMissing++;\n } else if (llmsTxtResult.content === '') {\n issues.push(createCheckIssue(\n 'warning',\n 'file_empty',\n `File is empty: ${llmsTxtPath}`,\n llmsTxtPath\n ));\n filesChecked++;\n } else {\n filesChecked++;\n // Run content linter on llms.txt\n const lintIssues = await lintFile(llmsTxtPath, llmsTxtResult.content, config);\n issues.push(...lintIssues);\n }\n \n // Check llms-full.txt\n const llmsFullTxtResult = await checkFile(llmsFullTxtPath);\n if (!llmsFullTxtResult.exists) {\n issues.push(createCheckIssue(\n 'error',\n 'file_missing',\n `Required file does not exist: ${llmsFullTxtPath}`,\n llmsFullTxtPath\n ));\n filesMissing++;\n } else if (llmsFullTxtResult.content === '') {\n issues.push(createCheckIssue(\n 'warning',\n 'file_empty',\n `File is empty: ${llmsFullTxtPath}`,\n llmsFullTxtPath\n ));\n filesChecked++;\n } else {\n filesChecked++;\n // Run content linter on llms-full.txt\n const lintIssues = await lintFile(llmsFullTxtPath, llmsFullTxtResult.content, config);\n issues.push(...lintIssues);\n }\n \n // Check citations.json (optional)\n if (citationsPath) {\n const citationsResult = await checkFile(citationsPath);\n if (!citationsResult.exists) {\n issues.push(createCheckIssue(\n 'warning',\n 'file_missing',\n `Optional citations file does not exist: ${citationsPath}`,\n citationsPath\n ));\n filesMissing++;\n } else {\n filesChecked++;\n }\n }\n \n // Calculate summary\n const severityCounts = countSeverities(issues);\n \n // Determine exit code\n let exitCode: ExitCode;\n if (severityCounts.error > 0) {\n exitCode = 2; // ERROR\n } else if (failOn === 'warn' && severityCounts.warning > 0) {\n exitCode = 1; // WARN\n } else {\n exitCode = 0; // OK\n }\n \n return {\n issues,\n summary: {\n errors: severityCounts.error,\n warnings: severityCounts.warning,\n info: severityCounts.info,\n filesChecked,\n filesMissing,\n filesMismatch,\n },\n exitCode,\n };\n}\n\n/**\n * Checks if a file exists.\n * @param filePath - Path to the file\n * @returns Promise resolving to true if file exists\n */\nexport async function checkFileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Checks a file and returns its content.\n * @param filePath - Path to the file\n * @returns Object with exists flag and content\n */\nasync function checkFile(filePath: string): Promise<{ exists: boolean; content: string }> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return { exists: true, content };\n } catch {\n return { exists: false, content: '' };\n }\n}\n\n/**\n * Reads file content safely.\n * @param filePath - Path to the file\n * @returns File content or null if file doesn't exist\n */\nexport async function readFileContent(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Compares two strings and returns diff context.\n * @param expected - Expected content\n * @param actual - Actual content\n * @param maxContextLines - Maximum number of diff lines to show (default: 5)\n * @returns CompareResult with match status and context\n */\nexport function compareContent(\n expected: string,\n actual: string,\n maxContextLines = 5\n): CompareResult {\n if (expected === actual) {\n return { match: true, context: '' };\n }\n \n const expectedLines = expected.split('\\n');\n const actualLines = actual.split('\\n');\n const contextLines: string[] = [];\n let diffCount = 0;\n \n const maxLines = Math.max(expectedLines.length, actualLines.length);\n \n for (let i = 0; i < maxLines && diffCount < maxContextLines; i++) {\n const expectedLine = expectedLines[i];\n const actualLine = actualLines[i];\n \n if (expectedLine !== actualLine) {\n diffCount++;\n const lineNum = i + 1;\n \n if (expectedLine !== undefined) {\n contextLines.push(`Expected line ${lineNum}: \"${expectedLine}\"`);\n }\n if (actualLine !== undefined) {\n contextLines.push(`Actual line ${lineNum}: \"${actualLine}\"`);\n }\n }\n }\n \n return {\n match: false,\n context: contextLines.join('\\n'),\n };\n}\n\n/**\n * Lints a file content against policy rules.\n * @param filePath - Path to the file\n * @param content - File content\n * @param config - LLM-SEO configuration\n * @returns Array of check issues\n */\nasync function lintFile(\n filePath: string,\n content: string,\n config: LlmsSeoConfig\n): Promise<CheckIssue[]> {\n const issues: CheckIssue[] = [];\n \n // Run basic linting rules\n const lintResult = lintWithRules(content, filePath);\n for (const issue of lintResult.issues) {\n const checkIssue: CheckIssue = {\n path: filePath,\n code: issue.id as CheckIssueCode,\n message: issue.message,\n severity: issue.severity,\n };\n if (issue.line !== undefined) {\n checkIssue.line = issue.line;\n }\n if (issue.suggestion !== undefined) {\n checkIssue.context = issue.suggestion;\n }\n issues.push(checkIssue);\n }\n \n // Check forbidden terms if policy is configured\n if (config.policy?.restrictedClaims?.enable) {\n const forbidden = config.policy.restrictedClaims.forbidden ?? [];\n const whitelist = config.policy.restrictedClaims.whitelist ?? [];\n const forbiddenIssues = checkForbiddenTerms(content, forbidden, whitelist);\n \n for (const issue of forbiddenIssues) {\n const checkIssue: CheckIssue = {\n path: filePath,\n code: 'forbidden_term',\n message: issue.message,\n severity: issue.severity,\n };\n if (issue.line !== undefined) {\n checkIssue.line = issue.line;\n }\n if (issue.context !== undefined) {\n checkIssue.context = issue.context;\n }\n issues.push(checkIssue);\n }\n }\n \n // Check for empty sections\n const emptySectionIssues = checkEmptySections(content);\n for (const issue of emptySectionIssues) {\n const checkIssue: CheckIssue = {\n path: filePath,\n code: 'empty_section',\n message: issue.message,\n severity: issue.severity,\n };\n if (issue.line !== undefined) {\n checkIssue.line = issue.line;\n }\n if (issue.context !== undefined) {\n checkIssue.context = issue.context;\n }\n issues.push(checkIssue);\n }\n \n // Check for duplicate URLs\n const duplicateUrlIssues = checkDuplicateUrls(content);\n for (const issue of duplicateUrlIssues) {\n const checkIssue: CheckIssue = {\n path: filePath,\n code: 'duplicate_url',\n message: issue.message,\n severity: issue.severity,\n };\n if (issue.line !== undefined) {\n checkIssue.line = issue.line;\n }\n if (issue.context !== undefined) {\n checkIssue.context = issue.context;\n }\n issues.push(checkIssue);\n }\n \n return issues;\n}\n\n/**\n * Checks generated files against expected content.\n * @param llmsTxtPath - Path to llms.txt\n * @param expectedLlmsTxt - Expected llms.txt content\n * @param llmsFullTxtPath - Path to llms-full.txt\n * @param expectedLlmsFullTxt - Expected llms-full.txt content\n * @param maxContextLines - Maximum context lines for diff\n * @returns Array of check issues\n */\nexport async function checkFilesAgainstExpected(\n llmsTxtPath: string,\n expectedLlmsTxt: string,\n llmsFullTxtPath: string,\n expectedLlmsFullTxt: string,\n maxContextLines = 5\n): Promise<CheckIssue[]> {\n const issues: CheckIssue[] = [];\n \n // Check llms.txt\n const llmsTxtContent = await readFileContent(llmsTxtPath);\n if (llmsTxtContent === null) {\n issues.push(createCheckIssue(\n 'error',\n 'file_missing',\n `Required file does not exist: ${llmsTxtPath}`,\n llmsTxtPath\n ));\n } else if (llmsTxtContent === '') {\n issues.push(createCheckIssue(\n 'warning',\n 'file_empty',\n `File is empty: ${llmsTxtPath}`,\n llmsTxtPath\n ));\n } else {\n const compareResult = compareContent(expectedLlmsTxt, llmsTxtContent, maxContextLines);\n if (!compareResult.match) {\n issues.push(createCheckIssue(\n 'error',\n 'file_mismatch',\n `Content differs from expected output`,\n llmsTxtPath,\n compareResult.context\n ));\n }\n }\n \n // Check llms-full.txt\n const llmsFullTxtContent = await readFileContent(llmsFullTxtPath);\n if (llmsFullTxtContent === null) {\n issues.push(createCheckIssue(\n 'error',\n 'file_missing',\n `Required file does not exist: ${llmsFullTxtPath}`,\n llmsFullTxtPath\n ));\n } else if (llmsFullTxtContent === '') {\n issues.push(createCheckIssue(\n 'warning',\n 'file_empty',\n `File is empty: ${llmsFullTxtPath}`,\n llmsFullTxtPath\n ));\n } else {\n const compareResult = compareContent(expectedLlmsFullTxt, llmsFullTxtContent, maxContextLines);\n if (!compareResult.match) {\n issues.push(createCheckIssue(\n 'error',\n 'file_mismatch',\n `Content differs from expected output`,\n llmsFullTxtPath,\n compareResult.context\n ));\n }\n }\n \n return issues;\n}\n","/**\n * Configuration schema for llm-seo.\n * Full LlmsSeoConfig schema with all required fields and validation rules.\n */\n\nimport { z } from 'zod';\n\n/**\n * Schema for site configuration.\n */\nexport const SiteConfigSchema = z.object({\n /** Site base URL - must be valid URL with http/https, no trailing slash */\n baseUrl: z\n .string()\n .url({ message: 'Must be a valid URL with http or https protocol' })\n .refine(\n (url) => !url.endsWith('/'),\n { message: 'Base URL must not have a trailing slash' }\n ),\n /** Default locale - must be in locales if provided */\n defaultLocale: z.string().min(2).optional(),\n});\n\n/**\n * Type for site configuration.\n */\nexport type SiteConfig = z.infer<typeof SiteConfigSchema>;\n\n/**\n * Schema for brand configuration.\n */\nexport const BrandConfigSchema = z.object({\n /** Brand name - required */\n name: z.string().min(1, { message: 'Brand name is required' }),\n /** Optional tagline */\n tagline: z.string().optional(),\n /** Optional description */\n description: z.string().optional(),\n /** Optional organization name */\n org: z.string().optional(),\n /** Supported locales - e.g., [\"en\", \"uk\", \"de\"] */\n locales: z.array(z.string().min(2)).min(1, { message: 'At least one locale is required' }),\n});\n\n/**\n * Type for brand configuration.\n */\nexport type BrandConfig = z.infer<typeof BrandConfigSchema>;\n\n/**\n * Schema for sections configuration.\n */\nexport const SectionsConfigSchema = z.object({\n /** Hub paths - e.g., [\"/services\", \"/blog\", \"/projects\"] */\n hubs: z.array(z.string()).default([]),\n});\n\n/**\n * Type for sections configuration.\n */\nexport type SectionsConfig = z.infer<typeof SectionsConfigSchema>;\n\n/**\n * Schema for social links configuration.\n */\nexport const SocialConfigSchema = z.object({\n /** Twitter handle or URL */\n twitter: z.string().optional(),\n /** LinkedIn URL */\n linkedin: z.string().optional(),\n /** GitHub URL */\n github: z.string().optional(),\n});\n\n/**\n * Type for social links configuration.\n */\nexport type SocialConfig = z.infer<typeof SocialConfigSchema>;\n\n/**\n * Schema for contact configuration.\n * At least email or one social field required.\n */\nexport const ContactConfigSchema = z.object({\n /** Contact email */\n email: z.string().email().optional(),\n /** Social links */\n social: SocialConfigSchema.optional(),\n /** Phone number */\n phone: z.string().optional(),\n});\n\n/**\n * Type for contact configuration.\n */\nexport type ContactConfig = z.infer<typeof ContactConfigSchema>;\n\n/**\n * Schema for restricted claims configuration.\n */\nexport const RestrictedClaimsConfigSchema = z.object({\n /** Enable restricted claims checking */\n enable: z.boolean(),\n /** Forbidden words/phrases - e.g., [\"best\", \"#1\", \"guaranteed\"] */\n forbidden: z.array(z.string()).optional(),\n /** Allowlisted phrases */\n whitelist: z.array(z.string()).optional(),\n});\n\n/**\n * Type for restricted claims configuration.\n */\nexport type RestrictedClaimsConfig = z.infer<typeof RestrictedClaimsConfigSchema>;\n\n/**\n * Schema for policy configuration.\n */\nexport const PolicyConfigSchema = z.object({\n /** Geographic policy statement */\n geoPolicy: z.string().optional(),\n /** Citation rules */\n citationRules: z.string().optional(),\n /** Restricted claims configuration */\n restrictedClaims: RestrictedClaimsConfigSchema.optional(),\n});\n\n/**\n * Type for policy configuration.\n */\nexport type PolicyConfig = z.infer<typeof PolicyConfigSchema>;\n\n/**\n * Schema for booking configuration.\n */\nexport const BookingConfigSchema = z.object({\n /** Booking URL - e.g., Cal.com link */\n url: z.string().url().optional(),\n /** Booking label - e.g., \"Book a consultation\" */\n label: z.string().optional(),\n});\n\n/**\n * Type for booking configuration.\n */\nexport type BookingConfig = z.infer<typeof BookingConfigSchema>;\n\n/**\n * Schema for machine hints configuration.\n */\nexport const MachineHintsConfigSchema = z.object({\n /** URL to robots.txt */\n robots: z.string().url().optional(),\n /** URL to sitemap.xml */\n sitemap: z.string().url().optional(),\n /** URL to llms.txt */\n llmsTxt: z.string().url().optional(),\n /** URL to llms-full.txt */\n llmsFullTxt: z.string().url().optional(),\n});\n\n/**\n * Type for machine hints configuration.\n */\nexport type MachineHintsConfig = z.infer<typeof MachineHintsConfigSchema>;\n\n/**\n * Schema for output paths configuration.\n */\nexport const OutputPathsConfigSchema = z.object({\n /** Path to llms.txt output - e.g., \"public/llms.txt\" */\n llmsTxt: z.string().min(1, { message: 'llmsTxt output path is required' }),\n /** Path to llms-full.txt output - e.g., \"public/llms-full.txt\" */\n llmsFullTxt: z.string().min(1, { message: 'llmsFullTxt output path is required' }),\n /** Path to citations.json output - e.g., \"public/citations.json\" */\n citations: z.string().optional(),\n});\n\n/**\n * Type for output paths configuration.\n */\nexport type OutputPathsConfig = z.infer<typeof OutputPathsConfigSchema>;\n\n/**\n * Schema for output configuration.\n */\nexport const OutputConfigSchema = z.object({\n /** Output paths */\n paths: OutputPathsConfigSchema,\n});\n\n/**\n * Type for output configuration.\n */\nexport type OutputConfig = z.infer<typeof OutputConfigSchema>;\n\n/**\n * Schema for format configuration.\n */\nexport const FormatConfigSchema = z.object({\n /** Trailing slash handling */\n trailingSlash: z.enum(['always', 'never', 'preserve']).default('never'),\n /** Line endings format */\n lineEndings: z.enum(['lf', 'crlf']).default('lf'),\n /** Locale URL strategy */\n localeStrategy: z.enum(['prefix', 'subdomain', 'none']).optional(),\n});\n\n/**\n * Type for format configuration.\n */\nexport type FormatConfig = z.infer<typeof FormatConfigSchema>;\n\n/**\n * Full LlmsSeoConfig schema with all required fields.\n */\nexport const LlmsSeoConfigSchema = z.object({\n /** Site configuration */\n site: SiteConfigSchema,\n /** Brand configuration */\n brand: BrandConfigSchema,\n /** Sections configuration */\n sections: SectionsConfigSchema.optional(),\n /** Manifests configuration */\n manifests: z.record(z.unknown()).default({}),\n /** Contact configuration */\n contact: ContactConfigSchema.optional(),\n /** Policy configuration */\n policy: PolicyConfigSchema.optional(),\n /** Booking configuration */\n booking: BookingConfigSchema.optional(),\n /** Machine hints configuration */\n machineHints: MachineHintsConfigSchema.optional(),\n /** Output configuration */\n output: OutputConfigSchema,\n /** Format configuration */\n format: FormatConfigSchema.optional(),\n});\n\n/**\n * Type for full LlmsSeoConfig.\n */\nexport type LlmsSeoConfig = z.infer<typeof LlmsSeoConfigSchema>;\n\n// Legacy exports for backwards compatibility\nexport const ConfigSchema = z.object({\n baseUrl: z.string().url(),\n title: z.string().min(1),\n description: z.string().optional(),\n outputDir: z.string().default('./public'),\n includeOptionalSections: z.boolean().default(false),\n maxContentLength: z.number().int().nonnegative().default(0),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport const LocaleConfigSchema = z.object({\n default: z.string().min(2),\n supported: z.array(z.string().min(2)).min(1),\n strategy: z.enum(['subdirectory', 'subdomain', 'domain']),\n});\n\nexport type LocaleConfigSchemaType = z.infer<typeof LocaleConfigSchema>;\n\nexport const CheckConfigSchema = z.object({\n strict: z.boolean().default(false),\n maxTitleLength: z.number().int().positive().default(60),\n maxDescriptionLength: z.number().int().positive().default(160),\n enableLint: z.boolean().default(true),\n});\n\nexport type CheckConfig = z.infer<typeof CheckConfigSchema>;\n\nexport const FullConfigSchema = z.object({\n site: ConfigSchema,\n locale: LocaleConfigSchema.optional(),\n check: CheckConfigSchema.optional(),\n});\n\nexport type FullConfig = z.infer<typeof FullConfigSchema>;\n","/**\n * Manifest schema for site pages.\n */\n\nimport { z } from 'zod';\n\n/**\n * Schema for ManifestItem - a single page entry in a manifest.\n */\nexport const ManifestItemSchema = z.object({\n /** URL path slug - required */\n slug: z.string().min(1, { message: 'Slug is required and cannot be empty' }),\n /** Available locales for this page */\n locales: z.array(z.string().min(2)).optional(),\n /** Publication date (ISO 8601) */\n publishedAt: z.string().datetime({ message: 'publishedAt must be a valid ISO 8601 date' }).optional(),\n /** Last update date (ISO 8601) */\n updatedAt: z.string().datetime({ message: 'updatedAt must be a valid ISO 8601 date' }).optional(),\n /** Override canonical URL */\n canonicalOverride: z.string().url().optional(),\n /** Priority for citations (0-100) */\n priority: z.number().int().min(0).max(100).optional(),\n /** Title for display */\n title: z.string().optional(),\n /** Description for display */\n description: z.string().optional(),\n});\n\n/**\n * Type for ManifestItem.\n */\nexport type ManifestItem = z.infer<typeof ManifestItemSchema>;\n\n/**\n * Schema for ManifestSource - external manifest reference.\n */\nexport const ManifestSourceSchema = z.object({\n /** Source type */\n type: z.enum(['file', 'url', 'module']),\n /** Source location */\n source: z.string(),\n /** Optional transform function */\n transform: z.string().optional(),\n});\n\n/**\n * Type for ManifestSource.\n */\nexport type ManifestSource = z.infer<typeof ManifestSourceSchema>;\n\n/**\n * Schema for manifest value - can be array of items or source reference.\n */\nexport const ManifestValueSchema = z.union([\n z.array(ManifestItemSchema),\n ManifestSourceSchema,\n]);\n\n/**\n * Type for manifest value.\n */\nexport type ManifestValue = z.infer<typeof ManifestValueSchema>;\n\n/**\n * Schema for manifests configuration.\n */\nexport const ManifestsConfigSchema = z.record(z.string(), ManifestValueSchema);\n\n/**\n * Type for manifests configuration.\n */\nexport type ManifestsConfig = z.infer<typeof ManifestsConfigSchema>;\n\n// Legacy schemas for backwards compatibility\n\n/**\n * Schema for optional section in llms.txt.\n */\nexport const OptionalSectionSchema = z.object({\n /** Section title */\n title: z.string().min(1),\n /** Section content */\n content: z.string().optional(),\n});\n\n/**\n * Type for optional section.\n */\nexport type OptionalSection = z.infer<typeof OptionalSectionSchema>;\n\n/**\n * Schema for a page manifest entry (legacy).\n */\nexport const PageManifestSchema = z.object({\n /** Page path (e.g., /about) */\n path: z.string().startsWith('/'),\n /** Page title */\n title: z.string().optional(),\n /** Page description */\n description: z.string().optional(),\n /** Page content for llms-full.txt */\n content: z.string().optional(),\n /** Whether page is optional (included only in full) */\n optional: z.boolean().default(false),\n /** Last modified timestamp (ISO 8601) */\n lastModified: z.string().datetime().optional(),\n});\n\n/**\n * Type for page manifest.\n */\nexport type PageManifest = z.infer<typeof PageManifestSchema>;\n\n/**\n * Schema for site manifest.\n */\nexport const SiteManifestSchema = z.object({\n /** Site base URL */\n baseUrl: z.string().url(),\n /** Site title */\n title: z.string().min(1),\n /** Site description */\n description: z.string().optional(),\n /** List of pages */\n pages: z.array(PageManifestSchema).min(1),\n /** Optional sections for llms.txt */\n optionalSections: z.array(OptionalSectionSchema).optional(),\n /** Site version */\n version: z.string().optional(),\n /** Generation timestamp (ISO 8601) */\n generatedAt: z.string().datetime().optional(),\n});\n\n/**\n * Type for site manifest.\n */\nexport type SiteManifest = z.infer<typeof SiteManifestSchema>;\n\n/**\n * Schema for build manifest (Next.js compatible).\n */\nexport const BuildManifestSchema = z.object({\n /** Build ID */\n buildId: z.string(),\n /** List of static pages */\n pages: z.record(z.string(), z.array(z.string())),\n /** Dynamic routes */\n dynamicRoutes: z.record(z.string(), z.object({\n routeRegex: z.string(),\n dataRoute: z.string(),\n dataRouteRegex: z.string(),\n })).optional(),\n});\n\n/**\n * Type for build manifest.\n */\nexport type BuildManifest = z.infer<typeof BuildManifestSchema>;\n","/**\n * Validation utilities using Zod schemas.\n */\n\nimport { ZodType, ZodError } from 'zod';\nimport { LlmsSeoConfigSchema, type LlmsSeoConfig, type ContactConfig } from './config.schema.js';\nimport type { ManifestItem } from './manifest.schema.js';\n\n/**\n * Result of a validation operation.\n */\nexport interface ValidationResult<T> {\n /** Whether validation passed */\n success: boolean;\n /** Validated data (only present if success is true) */\n data?: T;\n /** Validation issues (errors and warnings) */\n issues?: ValidationIssue[];\n}\n\n/**\n * Represents a single validation issue (error or warning).\n */\nexport interface ValidationIssue {\n /** Path to the invalid field */\n path: string;\n /** Error code */\n code: string;\n /** Human-readable error message */\n message: string;\n /** Issue severity */\n severity: 'error' | 'warning';\n}\n\n/**\n * Legacy ValidationError type for backwards compatibility.\n */\nexport type ValidationError = Omit<ValidationIssue, 'severity'>;\n\n/**\n * Validates data against a Zod schema.\n * @param schema - The Zod schema to validate against\n * @param data - The data to validate\n * @returns Validation result\n */\nexport function validate<T>(\n schema: ZodType<T>,\n data: unknown\n): ValidationResult<T> {\n const result = schema.safeParse(data);\n \n if (result.success) {\n return {\n success: true,\n data: result.data,\n issues: [],\n };\n }\n \n return {\n success: false,\n issues: formatZodErrors(result.error),\n };\n}\n\n/**\n * Formats Zod errors into ValidationIssues.\n * @param error - The Zod error\n * @returns Array of validation issues\n */\nfunction formatZodErrors(error: ZodError): ValidationIssue[] {\n return error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n code: issue.code,\n severity: 'error' as const,\n }));\n}\n\n/**\n * Validates and throws on error.\n * @param schema - The Zod schema to validate against\n * @param data - The data to validate\n * @returns Validated data\n * @throws Error if validation fails\n */\nexport function validateOrThrow<T>(schema: ZodType<T>, data: unknown): T {\n const result = validate(schema, data);\n \n if (!result.success || !result.data) {\n const messages = result.issues?.map((e) => `${e.path}: ${e.message}`).join('; ') ?? 'Unknown validation error';\n throw new Error(`Validation failed: ${messages}`);\n }\n \n return result.data;\n}\n\n/**\n * Creates a human-readable error message from validation issues.\n * @param issues - Array of validation issues\n * @returns Formatted error message\n */\nexport function formatValidationErrors(issues: readonly ValidationIssue[]): string {\n const lines: string[] = ['Validation failed:', ''];\n \n for (const issue of issues) {\n lines.push(` - ${issue.path || '(root)'}: ${issue.message}`);\n }\n \n return lines.join('\\n');\n}\n\n/**\n * Normalizes a hub path by removing double slashes, query strings, and hashes.\n * @param path - The path to normalize\n * @returns Normalized path\n */\nfunction normalizeHubPath(path: string): string {\n let normalized = path.trim();\n \n // Remove query strings\n const queryIndex = normalized.indexOf('?');\n if (queryIndex !== -1) {\n normalized = normalized.substring(0, queryIndex);\n }\n \n // Remove hashes\n const hashIndex = normalized.indexOf('#');\n if (hashIndex !== -1) {\n normalized = normalized.substring(0, hashIndex);\n }\n \n // Remove double slashes (but keep leading slash)\n normalized = normalized.replace(/\\/+/g, '/');\n \n return normalized;\n}\n\n/**\n * Validates hub paths according to the rules.\n * @param hubs - Array of hub paths\n * @returns Array of validation issues\n */\nfunction validateHubPaths(hubs: string[]): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n \n for (let i = 0; i < hubs.length; i++) {\n const hub = hubs[i];\n if (!hub) continue;\n \n const path = `sections.hubs.${i}`;\n \n // Check for leading slash\n if (!hub.startsWith('/')) {\n issues.push({\n path,\n code: 'invalid_hub_path',\n message: `Hub path \"${hub}\" must start with a leading slash (/)`,\n severity: 'error',\n });\n }\n \n // Check for double slashes\n if (hub.includes('//')) {\n issues.push({\n path,\n code: 'invalid_hub_path',\n message: `Hub path \"${hub}\" contains double slashes (//)`,\n severity: 'error',\n });\n }\n \n // Check for query strings\n if (hub.includes('?')) {\n issues.push({\n path,\n code: 'invalid_hub_path',\n message: `Hub path \"${hub}\" must not contain query strings (?)`,\n severity: 'error',\n });\n }\n \n // Check for hashes\n if (hub.includes('#')) {\n issues.push({\n path,\n code: 'invalid_hub_path',\n message: `Hub path \"${hub}\" must not contain hashes (#)`,\n severity: 'error',\n });\n }\n }\n \n return issues;\n}\n\n/**\n * Validates manifest items for uniqueness by slug + locale.\n * @param manifests - The manifests record\n * @returns Array of validation issues\n */\nfunction validateManifestItems(manifests: Record<string, unknown>): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n \n for (const [manifestName, manifestValue] of Object.entries(manifests)) {\n // Skip if not an array (could be ManifestSource)\n if (!Array.isArray(manifestValue)) {\n continue;\n }\n \n const seen = new Map<string, number>();\n const items = manifestValue as ManifestItem[];\n \n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (!item) continue;\n \n const locales = item.locales || [''];\n \n for (const locale of locales) {\n const key = `${item.slug}:${locale}`;\n const path = `manifests.${manifestName}.${i}`;\n \n if (item.slug === undefined || item.slug === '') {\n issues.push({\n path,\n code: 'empty_slug',\n message: 'Manifest item slug cannot be empty',\n severity: 'error',\n });\n continue;\n }\n \n if (seen.has(key)) {\n const firstIndex = seen.get(key);\n issues.push({\n path,\n code: 'duplicate_manifest_item',\n message: `Duplicate manifest item with slug \"${item.slug}\" and locale \"${locale || 'default'}\" (first occurrence at index ${firstIndex})`,\n severity: 'error',\n });\n } else {\n seen.set(key, i);\n }\n }\n }\n }\n \n return issues;\n}\n\n/**\n * Validates contact configuration.\n * At least email or one social field required.\n * @param contact - The contact configuration\n * @returns Array of validation issues\n */\nfunction validateContact(contact: ContactConfig | undefined): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n \n if (!contact) {\n return issues;\n }\n \n const hasEmail = Boolean(contact.email);\n const hasSocial = Boolean(\n contact.social?.twitter ||\n contact.social?.linkedin ||\n contact.social?.github\n );\n \n if (!hasEmail && !hasSocial) {\n issues.push({\n path: 'contact',\n code: 'missing_contact',\n message: 'At least email or one social field (twitter, linkedin, github) is required',\n severity: 'error',\n });\n }\n \n return issues;\n}\n\n/**\n * Validates that defaultLocale exists in brand.locales.\n * @param defaultLocale - The default locale\n * @param locales - Available locales\n * @returns Array of validation issues\n */\nfunction validateDefaultLocale(defaultLocale: string | undefined, locales: string[]): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n \n if (defaultLocale && !locales.includes(defaultLocale)) {\n issues.push({\n path: 'site.defaultLocale',\n code: 'invalid_default_locale',\n message: `Default locale \"${defaultLocale}\" must exist in brand.locales [${locales.join(', ')}]`,\n severity: 'error',\n });\n }\n \n return issues;\n}\n\n/**\n * Validates the full LlmsSeoConfig with custom validation rules.\n * @param data - The configuration data to validate\n * @returns Validation result with all issues\n */\nexport function validateLlmsSeoConfig(data: unknown): ValidationResult<LlmsSeoConfig> {\n // First, validate with Zod schema\n const schemaResult = validate<LlmsSeoConfig>(LlmsSeoConfigSchema as ZodType<LlmsSeoConfig>, data);\n \n if (!schemaResult.success) {\n return schemaResult;\n }\n \n const config = schemaResult.data!;\n const issues: ValidationIssue[] = [];\n \n // Validate defaultLocale exists in locales\n if (config.site?.defaultLocale && config.brand?.locales) {\n issues.push(...validateDefaultLocale(config.site.defaultLocale, config.brand.locales));\n }\n \n // Validate hub paths\n if (config.sections?.hubs) {\n issues.push(...validateHubPaths(config.sections.hubs));\n }\n \n // Validate manifest items\n if (config.manifests && typeof config.manifests === 'object') {\n issues.push(...validateManifestItems(config.manifests as Record<string, unknown>));\n }\n \n // Validate contact\n issues.push(...validateContact(config.contact));\n \n // Return result with all issues\n if (issues.length > 0) {\n return {\n success: false,\n data: config,\n issues: [...(schemaResult.issues || []), ...issues],\n };\n }\n \n return {\n success: true,\n data: config,\n issues: [],\n };\n}\n\n/**\n * Normalizes hub paths in the configuration.\n * @param hubs - Array of hub paths\n * @returns Normalized hub paths\n */\nexport function normalizeHubPaths(hubs: string[]): string[] {\n return hubs.map(normalizeHubPath).filter((h) => h.length > 0);\n}\n","/**\n * Manifest generation for Next.js static exports.\n */\n\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { ManifestItem, SiteManifest, PageManifest, BuildManifest } from '../../schema/manifest.schema.js';\n\n/**\n * Next.js content manifest structure for fromNextContentManifest.\n */\nexport interface NextContentManifest {\n items: Array<{\n slug: string;\n locales?: string[];\n publishedAt?: string;\n updatedAt?: string;\n title?: string;\n description?: string;\n priority?: number;\n canonicalOverride?: string;\n [key: string]: unknown;\n }>;\n}\n\n/**\n * Options for fromNextContentManifest.\n */\nexport interface FromNextContentManifestOptions {\n /** Prefix to add to all slugs */\n slugPrefix?: string;\n /** Default locale if not specified */\n defaultLocale?: string;\n}\n\n/**\n * Converts Next.js content manifest to llm-seo ManifestItem[].\n *\n * @param manifest - Next.js content manifest\n * @param options - Conversion options\n * @returns Normalized ManifestItem[] for use in config\n */\nexport function fromNextContentManifest(\n manifest: NextContentManifest,\n options: FromNextContentManifestOptions = {}\n): ManifestItem[] {\n const { slugPrefix = '', defaultLocale } = options;\n\n return manifest.items.map((item): ManifestItem => {\n const result: ManifestItem = {\n slug: slugPrefix + item.slug,\n };\n\n if (item.locales !== undefined) {\n result.locales = item.locales;\n } else if (defaultLocale !== undefined) {\n result.locales = [defaultLocale];\n }\n\n if (item.publishedAt !== undefined) {\n result.publishedAt = item.publishedAt;\n }\n\n if (item.updatedAt !== undefined) {\n result.updatedAt = item.updatedAt;\n }\n\n if (item.title !== undefined) {\n result.title = item.title;\n }\n\n if (item.description !== undefined) {\n result.description = item.description;\n }\n\n if (item.priority !== undefined) {\n result.priority = item.priority;\n }\n\n if (item.canonicalOverride !== undefined) {\n result.canonicalOverride = item.canonicalOverride;\n }\n\n return result;\n });\n}\n\n/**\n * Options for createManifestFromPagesDir.\n */\nexport interface CreateManifestFromPagesDirOptions {\n /** Path to pages directory */\n pagesDir: string;\n /** Prefix to add to all routes */\n routePrefix?: string;\n /** Default locale for items */\n defaultLocale?: string;\n /** File extensions to include */\n extensions?: string[];\n}\n\n/**\n * Parsed frontmatter from a file.\n */\ninterface ParsedFrontmatter {\n title?: string;\n description?: string;\n date?: string;\n updated?: string;\n locale?: string;\n locales?: string[];\n priority?: number;\n [key: string]: unknown;\n}\n\n/**\n * Parses YAML-like frontmatter from content.\n * Simple implementation for basic frontmatter extraction.\n *\n * @param content - File content with potential frontmatter\n * @returns Parsed frontmatter and body content\n */\nfunction parseFrontmatter(content: string): { frontmatter: ParsedFrontmatter; body: string } {\n const frontmatterRegex = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/;\n const match = content.match(frontmatterRegex);\n\n if (!match) {\n return { frontmatter: {}, body: content };\n }\n\n const frontmatterText = match[1] ?? '';\n const body = match[2] ?? content;\n const frontmatter: ParsedFrontmatter = {};\n\n // Simple YAML-like parsing\n const lines = frontmatterText.split('\\n');\n for (const line of lines) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) continue;\n\n const key = line.slice(0, colonIndex).trim();\n let value: string | string[] = line.slice(colonIndex + 1).trim();\n\n // Handle arrays in format [item1, item2]\n if (value.startsWith('[') && value.endsWith(']')) {\n value = value\n .slice(1, -1)\n .split(',')\n .map((item) => item.trim().replace(/^['\"]|['\"]$/g, ''))\n .filter((item) => item.length > 0);\n } else {\n // Remove quotes\n value = value.replace(/^['\"]|['\"]$/g, '');\n }\n\n // Map to frontmatter fields\n if (key === 'title') frontmatter.title = value as string;\n else if (key === 'description') frontmatter.description = value as string;\n else if (key === 'date' || key === 'publishedAt') frontmatter.date = value as string;\n else if (key === 'updated' || key === 'updatedAt') frontmatter.updated = value as string;\n else if (key === 'locale') frontmatter.locale = value as string;\n else if (key === 'locales') frontmatter.locales = value as string[];\n else if (key === 'priority') frontmatter.priority = parseInt(value as string, 10);\n else frontmatter[key] = value;\n }\n\n return { frontmatter, body };\n}\n\n/**\n * Converts file path to URL slug.\n *\n * @param filePath - File path relative to pages dir\n * @param extensions - File extensions to strip\n * @returns URL slug\n */\nfunction filePathToSlug(filePath: string, extensions: string[]): string {\n let slug = filePath;\n\n // Remove extension\n for (const ext of extensions) {\n if (slug.endsWith(ext)) {\n slug = slug.slice(0, -ext.length);\n break;\n }\n }\n\n // Handle index files\n if (slug.endsWith('/index')) {\n slug = slug.slice(0, -6);\n }\n if (slug === 'index') {\n slug = '';\n }\n\n // Ensure leading slash\n if (!slug.startsWith('/')) {\n slug = '/' + slug;\n }\n\n return slug || '/';\n}\n\n/**\n * Recursively scans directory for content files.\n *\n * @param dir - Directory to scan\n * @param extensions - File extensions to include\n * @param basePath - Base path for relative paths\n * @returns Array of relative file paths\n */\nasync function scanDirectory(\n dir: string,\n extensions: string[],\n basePath: string = ''\n): Promise<string[]> {\n const files: string[] = [];\n\n if (!existsSync(dir)) {\n return files;\n }\n\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n const relativePath = basePath ? join(basePath, entry.name) : entry.name;\n\n if (entry.isDirectory()) {\n const subFiles = await scanDirectory(fullPath, extensions, relativePath);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n const hasValidExtension = extensions.some((ext) => entry.name.endsWith(ext));\n if (hasValidExtension) {\n files.push(relativePath);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Creates manifest from Next.js pages directory.\n * Scans for .mdx, .md files and extracts frontmatter.\n *\n * @param options - Options for manifest creation\n * @returns Promise resolving to ManifestItem[]\n */\nexport async function createManifestFromPagesDir(\n options: CreateManifestFromPagesDirOptions\n): Promise<ManifestItem[]> {\n const {\n pagesDir,\n routePrefix = '',\n defaultLocale,\n extensions = ['.mdx', '.md'],\n } = options;\n\n const files = await scanDirectory(pagesDir, extensions);\n const items: ManifestItem[] = [];\n\n for (const file of files) {\n const fullPath = join(pagesDir, file);\n const content = await readFile(fullPath, 'utf-8');\n const { frontmatter } = parseFrontmatter(content);\n\n const slug = routePrefix + filePathToSlug(file, extensions);\n\n const item: ManifestItem = {\n slug,\n };\n\n if (frontmatter.locales !== undefined) {\n item.locales = frontmatter.locales;\n } else if (frontmatter.locale !== undefined) {\n item.locales = [frontmatter.locale];\n } else if (defaultLocale !== undefined) {\n item.locales = [defaultLocale];\n }\n\n if (frontmatter.date !== undefined) {\n item.publishedAt = frontmatter.date;\n }\n\n if (frontmatter.updated !== undefined) {\n item.updatedAt = frontmatter.updated;\n }\n\n if (frontmatter.title !== undefined) {\n item.title = frontmatter.title;\n }\n\n if (frontmatter.description !== undefined) {\n item.description = frontmatter.description;\n }\n\n if (frontmatter.priority !== undefined) {\n item.priority = frontmatter.priority;\n }\n\n items.push(item);\n }\n\n // Sort by slug for deterministic output\n return items.sort((a, b) => a.slug.localeCompare(b.slug));\n}\n\n/**\n * Options for createManifestFromData.\n */\nexport interface CreateManifestFromDataOptions {\n /** Prefix to add to all slugs */\n slugPrefix?: string;\n /** Default locale if not specified */\n defaultLocale?: string;\n}\n\n/**\n * Creates manifest from Next.js data (getStaticProps data).\n *\n * @param items - Array of items from getStaticProps\n * @param options - Options for manifest creation\n * @returns ManifestItem[]\n */\nexport function createManifestFromData(\n items: Array<{\n params: { slug: string | string[] };\n locale?: string;\n publishedAt?: string;\n updatedAt?: string;\n title?: string;\n description?: string;\n priority?: number;\n [key: string]: unknown;\n }>,\n options: CreateManifestFromDataOptions = {}\n): ManifestItem[] {\n const { slugPrefix = '', defaultLocale } = options;\n\n return items.map((item): ManifestItem => {\n // Convert slug array or string to path\n const slugPath = Array.isArray(item.params.slug)\n ? '/' + item.params.slug.join('/')\n : item.params.slug.startsWith('/')\n ? item.params.slug\n : '/' + item.params.slug;\n\n const result: ManifestItem = {\n slug: slugPrefix + slugPath,\n };\n\n if (item.locale !== undefined) {\n result.locales = [item.locale];\n } else if (defaultLocale !== undefined) {\n result.locales = [defaultLocale];\n }\n\n if (item.publishedAt !== undefined) {\n result.publishedAt = item.publishedAt;\n }\n\n if (item.updatedAt !== undefined) {\n result.updatedAt = item.updatedAt;\n }\n\n if (item.title !== undefined) {\n result.title = item.title;\n }\n\n if (item.description !== undefined) {\n result.description = item.description;\n }\n\n if (item.priority !== undefined) {\n result.priority = item.priority;\n }\n\n return result;\n });\n}\n\n// ============================================================================\n// Legacy functions - kept for backwards compatibility\n// ============================================================================\n\n/**\n * Options for Next.js manifest generation.\n */\nexport interface NextManifestOptions {\n /** Base URL for the site */\n baseUrl: string;\n /** Site title */\n title: string;\n /** Site description */\n description?: string;\n /** Path to the Next.js build manifest */\n buildManifestPath?: string;\n}\n\n/**\n * Extracts page paths from Next.js build manifest.\n * @param buildManifest - The Next.js build manifest\n * @returns Array of page paths\n */\nexport function extractPagePaths(buildManifest: BuildManifest): string[] {\n const pages: string[] = [];\n\n // Extract from static pages\n for (const pagePath of Object.keys(buildManifest.pages)) {\n // Skip Next.js internal routes\n if (pagePath.startsWith('/_')) {\n continue;\n }\n\n // Normalize the path\n const normalizedPath = normalizeNextPath(pagePath);\n pages.push(normalizedPath);\n }\n\n // Sort for deterministic output\n return pages.sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * Normalizes a Next.js page path.\n * @param path - The page path\n * @returns Normalized path\n */\nfunction normalizeNextPath(path: string): string {\n // Remove file extension if present\n let normalized = path.replace(/\\.(html|json)$/, '');\n\n // Handle index pages\n if (normalized === '/index' || normalized === '') {\n normalized = '/';\n }\n\n // Ensure leading slash\n if (!normalized.startsWith('/')) {\n normalized = `/${normalized}`;\n }\n\n return normalized;\n}\n\n/**\n * Generates a site manifest from Next.js build output.\n * @param options - Manifest generation options\n * @param buildManifest - Optional build manifest\n * @returns Generated site manifest\n */\nexport function generateNextManifest(\n options: NextManifestOptions,\n buildManifest?: BuildManifest\n): SiteManifest {\n const pages: PageManifest[] = [];\n\n if (buildManifest) {\n const pagePaths = extractPagePaths(buildManifest);\n\n for (const path of pagePaths) {\n pages.push({\n path,\n title: undefined, // Will be filled by crawler or manually\n description: undefined,\n optional: false,\n });\n }\n }\n\n return {\n baseUrl: options.baseUrl,\n title: options.title,\n description: options.description,\n pages,\n };\n}\n","/**\n * Build hooks for Next.js integration.\n */\n\nimport type { SiteManifest } from '../../schema/manifest.schema.js';\nimport { generateLlmsTxt } from '../../core/generate/llms-txt.js';\nimport { generateLlmsFullTxt } from '../../core/generate/llms-full-txt.js';\n\n// ============================================================================\n// Build Scripts Generation\n// ============================================================================\n\n/**\n * Options for generateBuildScripts.\n */\nexport interface GenerateBuildScriptsOptions {\n /** Path to config file */\n configPath?: string;\n /** Output directory for generated files */\n outputPath?: string;\n /** Whether to emit citations.json */\n emitCitations?: boolean;\n /** Package manager to use */\n packageManager?: 'npm' | 'yarn' | 'pnpm';\n}\n\n/**\n * Result of generateBuildScripts.\n */\nexport interface BuildScriptsResult {\n /** Script for building SEO artifacts */\n 'build:seo': string;\n /** Post-build hook script */\n postbuild: string;\n /** Script for checking SEO artifacts */\n 'check:seo': string;\n}\n\n/**\n * Generates package.json scripts for llm-seo integration.\n *\n * @param options - Options for script generation\n * @returns Object with script names as keys and commands as values\n *\n * @example\n * ```typescript\n * const scripts = generateBuildScripts({\n * configPath: 'llm-seo.config.ts',\n * emitCitations: true,\n * });\n * // Returns:\n * // {\n * // \"build:seo\": \"llm-seo generate --config llm-seo.config.ts\",\n * // \"postbuild\": \"pnpm build:seo && llm-seo check --fail-on error\",\n * // \"check:seo\": \"llm-seo check --fail-on warn\"\n * // }\n * ```\n */\nexport function generateBuildScripts(\n options: GenerateBuildScriptsOptions = {}\n): BuildScriptsResult {\n const {\n configPath = 'llm-seo.config.ts',\n emitCitations = false,\n packageManager = 'pnpm',\n } = options;\n\n const configFlag = `--config ${configPath}`;\n const citationsFlag = emitCitations ? ' --emit-citations' : '';\n\n const runCommand = packageManager === 'npm' ? 'npm run' : packageManager;\n\n return {\n 'build:seo': `llm-seo generate ${configFlag}${citationsFlag}`,\n postbuild: `${runCommand} build:seo && llm-seo check --fail-on error`,\n 'check:seo': 'llm-seo check --fail-on warn',\n };\n}\n\n// ============================================================================\n// Robots.txt LLM Policy\n// ============================================================================\n\n/**\n * Options for createRobotsLlmsPolicySnippet.\n */\nexport interface CreateRobotsLlmsPolicySnippetOptions {\n /** Base URL of the site */\n baseUrl: string;\n /** Whether to allow llms.txt */\n allowLlmsTxt?: boolean;\n /** Whether to allow llms-full.txt */\n allowLlmsFullTxt?: boolean;\n /** Whether to allow sitemap.xml */\n allowSitemap?: boolean;\n /** Additional paths to allow */\n additionalPaths?: string[];\n /** User agent to target (default: *) */\n userAgent?: string;\n}\n\n/**\n * Creates robots.txt LLM policy snippet.\n *\n * @param options - Options for snippet generation\n * @returns robots.txt snippet string\n *\n * @example\n * ```typescript\n * const snippet = createRobotsLlmsPolicySnippet({\n * baseUrl: 'https://example.com',\n * allowLlmsTxt: true,\n * allowLlmsFullTxt: true,\n * });\n * // Returns:\n * // # LLM SEO\n * // User-agent: *\n * // Allow: /llms.txt\n * // Allow: /llms-full.txt\n * // Allow: /sitemap.xml\n * ```\n */\nexport function createRobotsLlmsPolicySnippet(\n options: CreateRobotsLlmsPolicySnippetOptions\n): string {\n const {\n baseUrl,\n allowLlmsTxt = true,\n allowLlmsFullTxt = true,\n allowSitemap = true,\n additionalPaths = [],\n userAgent = '*',\n } = options;\n\n const lines: string[] = ['# LLM SEO'];\n\n // Extract host from baseUrl\n try {\n const url = new URL(baseUrl);\n lines.push(`Host: ${url.host}`);\n } catch {\n // Invalid URL, skip host\n }\n\n lines.push(`User-agent: ${userAgent}`);\n\n if (allowLlmsTxt) {\n lines.push('Allow: /llms.txt');\n }\n\n if (allowLlmsFullTxt) {\n lines.push('Allow: /llms-full.txt');\n }\n\n if (allowSitemap) {\n lines.push('Allow: /sitemap.xml');\n }\n\n for (const path of additionalPaths) {\n lines.push(`Allow: ${path}`);\n }\n\n return lines.join('\\n');\n}\n\n// ============================================================================\n// Next.js Config Helper\n// ============================================================================\n\n/**\n * Options for createNextConfig.\n */\nexport interface CreateNextConfigOptions {\n /** Supported locales */\n locales?: string[];\n /** Default locale */\n defaultLocale?: string;\n /** Whether to use trailing slash */\n trailingSlash?: boolean;\n /** Whether to disable images optimization (for static export) */\n unoptimizedImages?: boolean;\n}\n\n/**\n * Next.js config object returned by createNextConfig.\n */\nexport interface NextConfigResult {\n /** Output mode */\n output: 'export';\n /** Trailing slash configuration */\n trailingSlash: boolean;\n /** Images configuration */\n images: { unoptimized: boolean };\n /** i18n configuration (only if locales provided) */\n i18n?: {\n locales: string[];\n defaultLocale: string;\n };\n}\n\n/**\n * Creates Next.js config object for static export with locales.\n *\n * @param options - Options for config generation\n * @returns Next.js config object\n *\n * @example\n * ```typescript\n * const nextConfig = createNextConfig({\n * locales: ['en', 'uk'],\n * defaultLocale: 'en',\n * trailingSlash: false,\n * });\n *\n * module.exports = nextConfig;\n * ```\n */\nexport function createNextConfig(\n options: CreateNextConfigOptions\n): NextConfigResult {\n const {\n locales = [],\n defaultLocale = 'en',\n trailingSlash = false,\n unoptimizedImages = true,\n } = options;\n\n const config: NextConfigResult = {\n output: 'export',\n trailingSlash,\n images: {\n unoptimized: unoptimizedImages,\n },\n };\n\n // Add i18n config only if locales are provided\n // Note: i18n is not supported with static export in Next.js 13+\n // This is kept for documentation/reference purposes\n if (locales.length > 0) {\n config.i18n = {\n locales,\n defaultLocale,\n };\n }\n\n return config;\n}\n\n// ============================================================================\n// Legacy Build Hooks\n// ============================================================================\n\n/**\n * Options for build hooks.\n */\nexport interface BuildHookOptions {\n /** Output directory for generated files */\n outputDir: string;\n /** Site manifest */\n manifest: SiteManifest;\n /** Whether to generate llms-full.txt */\n generateFull?: boolean;\n}\n\n/**\n * Result of running build hooks.\n */\nexport interface BuildHookResult {\n /** Generated files */\n files: string[];\n /** Whether the hook succeeded */\n success: boolean;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * Post-build hook that generates llms.txt files.\n * Call this after Next.js static export completes.\n * @param options - Hook options\n * @returns Hook result\n */\nexport async function postBuildHook(\n options: BuildHookOptions\n): Promise<BuildHookResult> {\n const { outputDir, manifest, generateFull = false } = options;\n const files: string[] = [];\n\n try {\n // Generate llms.txt\n generateLlmsTxt(manifest);\n const llmsTxtPath = `${outputDir}/llms.txt`;\n files.push(llmsTxtPath);\n\n // In a real implementation, we would write the file\n // await writeTextFile(llmsTxtPath, llmsTxt);\n\n // Generate llms-full.txt if requested\n if (generateFull) {\n generateLlmsFullTxt(manifest);\n const llmsFullTxtPath = `${outputDir}/llms-full.txt`;\n files.push(llmsFullTxtPath);\n\n // In a real implementation, we would write the file\n // await writeTextFile(llmsFullTxtPath, llmsFullTxt);\n }\n\n return {\n files,\n success: true,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n return {\n files,\n success: false,\n error: message,\n };\n }\n}\n\n/**\n * Creates a plugin function for Next.js integration.\n * @returns Plugin object with hooks\n */\nexport function createNextPlugin(): {\n name: string;\n postBuild: (options: BuildHookOptions) => Promise<BuildHookResult>;\n} {\n return {\n name: 'llm-seo',\n postBuild: postBuildHook,\n };\n}\n"]}
|