@djangocfg/seo 2.1.50 â 2.1.51
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/dist/cli.mjs +82 -5
- package/dist/cli.mjs.map +1 -1
- package/dist/crawler/index.mjs +16 -0
- package/dist/crawler/index.mjs.map +1 -1
- package/dist/index.mjs +75 -0
- package/dist/index.mjs.map +1 -1
- package/dist/reports/index.mjs +59 -0
- package/dist/reports/index.mjs.map +1 -1
- package/dist/routes/index.mjs +7 -5
- package/dist/routes/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/crawler/robots-parser.ts +26 -0
- package/src/reports/claude-context.ts +61 -0
- package/src/routes/analyzer.ts +17 -10
package/dist/reports/index.mjs
CHANGED
|
@@ -621,6 +621,65 @@ function generateClaudeContext(report) {
|
|
|
621
621
|
lines.push("- Parallel `@folder` - skipped");
|
|
622
622
|
lines.push("- Private `_folder` - skipped");
|
|
623
623
|
lines.push("");
|
|
624
|
+
lines.push("## SEO Files (Next.js App Router)");
|
|
625
|
+
lines.push("");
|
|
626
|
+
lines.push("**Required files in `app/`:**");
|
|
627
|
+
lines.push("");
|
|
628
|
+
lines.push("### sitemap.xml/route.ts");
|
|
629
|
+
lines.push("```typescript");
|
|
630
|
+
lines.push("import { createSitemapHandler } from '@djangocfg/nextjs/sitemap';");
|
|
631
|
+
lines.push("");
|
|
632
|
+
lines.push('export const dynamic = "force-static";');
|
|
633
|
+
lines.push("export const { GET } = createSitemapHandler({");
|
|
634
|
+
lines.push(" siteUrl,");
|
|
635
|
+
lines.push(" staticPages: [");
|
|
636
|
+
lines.push(' { loc: "/", priority: 1.0, changefreq: "daily" },');
|
|
637
|
+
lines.push(' { loc: "/about", priority: 0.8 },');
|
|
638
|
+
lines.push(" ],");
|
|
639
|
+
lines.push(" dynamicPages: async () => fetchPagesFromAPI(),");
|
|
640
|
+
lines.push("});");
|
|
641
|
+
lines.push("```");
|
|
642
|
+
lines.push("");
|
|
643
|
+
lines.push("### robots.ts");
|
|
644
|
+
lines.push("```typescript");
|
|
645
|
+
lines.push("import type { MetadataRoute } from 'next';");
|
|
646
|
+
lines.push("");
|
|
647
|
+
lines.push("export default function robots(): MetadataRoute.Robots {");
|
|
648
|
+
lines.push(" return {");
|
|
649
|
+
lines.push(' rules: { userAgent: "*", allow: "/" },');
|
|
650
|
+
lines.push(" sitemap: `${siteUrl}/sitemap.xml`,");
|
|
651
|
+
lines.push(" };");
|
|
652
|
+
lines.push("}");
|
|
653
|
+
lines.push("```");
|
|
654
|
+
lines.push("");
|
|
655
|
+
lines.push("### Cloudflare Override");
|
|
656
|
+
lines.push("");
|
|
657
|
+
lines.push('If robots.txt shows "Content-Signal" or "ai-train" \u2014 Cloudflare is overriding your file.');
|
|
658
|
+
lines.push('**Fix:** Dashboard \u2192 Security \u2192 Settings \u2192 "Manage your robots.txt" \u2192 Set to "Off"');
|
|
659
|
+
lines.push("");
|
|
660
|
+
lines.push("### Declarative Routes with SEO");
|
|
661
|
+
lines.push("");
|
|
662
|
+
lines.push("Create `app/_routes/` with SEO metadata for sitemap:");
|
|
663
|
+
lines.push("```typescript");
|
|
664
|
+
lines.push("import { defineRoute } from '@djangocfg/nextjs/navigation';");
|
|
665
|
+
lines.push("");
|
|
666
|
+
lines.push("export const home = defineRoute('/', {");
|
|
667
|
+
lines.push(" label: 'Home',");
|
|
668
|
+
lines.push(" protected: false,");
|
|
669
|
+
lines.push(" priority: 1.0, // Sitemap priority 0.0-1.0");
|
|
670
|
+
lines.push(" changefreq: 'daily', // always|hourly|daily|weekly|monthly|yearly|never");
|
|
671
|
+
lines.push(" noindex: false, // Exclude from sitemap");
|
|
672
|
+
lines.push("});");
|
|
673
|
+
lines.push("");
|
|
674
|
+
lines.push("export const staticRoutes = [home, about, contact];");
|
|
675
|
+
lines.push("```");
|
|
676
|
+
lines.push("");
|
|
677
|
+
lines.push("Then in `sitemap.xml/route.ts`:");
|
|
678
|
+
lines.push("```typescript");
|
|
679
|
+
lines.push("import { routes } from '@/app/_routes';");
|
|
680
|
+
lines.push("routes.getAllStaticRoutes().filter(r => !r.metadata.noindex)");
|
|
681
|
+
lines.push("```");
|
|
682
|
+
lines.push("");
|
|
624
683
|
lines.push("## Link Guidelines");
|
|
625
684
|
lines.push("");
|
|
626
685
|
lines.push("### Nextra/MDX Projects (content/)");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/reports/json-report.ts","../../src/reports/markdown-report.ts","../../src/reports/split-report.ts","../../src/reports/claude-context.ts","../../src/reports/generator.ts"],"names":["formatCategory","existsSync","readdirSync","rmSync","join","mkdirSync","writeFileSync"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @djangocfg/seo - JSON Report Generator\n * Generate AI-friendly JSON reports\n */\n\nimport type {\n SeoReport,\n SeoIssue,\n UrlInspectionResult,\n CrawlResult,\n ReportSummary,\n Recommendation,\n IssueCategory,\n IssueSeverity,\n} from '../types/index.js';\n\nexport interface JsonReportOptions {\n includeRawData?: boolean;\n prettyPrint?: boolean;\n /** Maximum URLs to include per issue group (default: 10) */\n maxUrlsPerIssue?: number;\n}\n\n/**\n * Generate a comprehensive JSON report\n */\nexport function generateJsonReport(\n siteUrl: string,\n data: {\n issues: SeoIssue[];\n urlInspections?: UrlInspectionResult[];\n crawlResults?: CrawlResult[];\n },\n options: JsonReportOptions = {}\n): SeoReport {\n const { issues, urlInspections = [], crawlResults = [] } = data;\n const maxUrlsPerIssue = options.maxUrlsPerIssue ?? 10;\n\n // Limit issues to maxUrlsPerIssue per title group\n const limitedIssues = limitIssuesByTitle(issues, maxUrlsPerIssue);\n\n const report: SeoReport = {\n id: generateReportId(),\n siteUrl,\n generatedAt: new Date().toISOString(),\n summary: generateSummary(issues, urlInspections, crawlResults), // Use original for accurate counts\n issues: sortIssues(limitedIssues),\n urlInspections: options.includeRawData ? urlInspections.slice(0, 100) : [],\n crawlResults: options.includeRawData ? crawlResults.slice(0, 100) : [],\n recommendations: generateRecommendations(issues, maxUrlsPerIssue),\n };\n\n return report;\n}\n\n/**\n * Limit issues to maxUrls per issue title group\n */\nfunction limitIssuesByTitle(issues: SeoIssue[], maxUrls: number): SeoIssue[] {\n const byTitle = new Map<string, SeoIssue[]>();\n\n for (const issue of issues) {\n const existing = byTitle.get(issue.title) || [];\n existing.push(issue);\n byTitle.set(issue.title, existing);\n }\n\n const limited: SeoIssue[] = [];\n for (const [, group] of byTitle) {\n const sorted = group.sort((a, b) => {\n const severityOrder = { critical: 0, error: 1, warning: 2, info: 3 };\n return severityOrder[a.severity] - severityOrder[b.severity];\n });\n limited.push(...sorted.slice(0, maxUrls));\n }\n\n return limited;\n}\n\n/**\n * Generate report summary\n */\nfunction generateSummary(\n issues: SeoIssue[],\n urlInspections: UrlInspectionResult[],\n crawlResults: CrawlResult[]\n): ReportSummary {\n const totalUrls = Math.max(\n urlInspections.length,\n crawlResults.length,\n new Set(issues.map((i) => i.url)).size\n );\n\n const indexedUrls = urlInspections.filter(\n (r) => r.indexStatusResult.coverageState === 'SUBMITTED_AND_INDEXED'\n ).length;\n\n const notIndexedUrls = urlInspections.filter(\n (r) =>\n r.indexStatusResult.coverageState === 'NOT_INDEXED' ||\n r.indexStatusResult.coverageState === 'CRAWLED_CURRENTLY_NOT_INDEXED' ||\n r.indexStatusResult.coverageState === 'DISCOVERED_CURRENTLY_NOT_INDEXED'\n ).length;\n\n const issuesByCategory = issues.reduce(\n (acc, issue) => {\n acc[issue.category] = (acc[issue.category] || 0) + 1;\n return acc;\n },\n {} as Record<IssueCategory, number>\n );\n\n const issuesBySeverity = issues.reduce(\n (acc, issue) => {\n acc[issue.severity] = (acc[issue.severity] || 0) + 1;\n return acc;\n },\n {} as Record<IssueSeverity, number>\n );\n\n // Calculate health score (0-100)\n const healthScore = calculateHealthScore(issues, totalUrls);\n\n return {\n totalUrls,\n indexedUrls,\n notIndexedUrls,\n issuesByCategory,\n issuesBySeverity,\n healthScore,\n };\n}\n\n/**\n * Calculate overall SEO health score\n */\nfunction calculateHealthScore(issues: SeoIssue[], totalUrls: number): number {\n if (totalUrls === 0) return 100;\n\n const severityWeights: Record<IssueSeverity, number> = {\n critical: 10,\n error: 5,\n warning: 2,\n info: 0.5,\n };\n\n const totalPenalty = issues.reduce(\n (sum, issue) => sum + severityWeights[issue.severity],\n 0\n );\n\n // Max penalty per URL is 20 points\n const maxPenalty = totalUrls * 20;\n const penaltyRatio = Math.min(totalPenalty / maxPenalty, 1);\n\n return Math.round((1 - penaltyRatio) * 100);\n}\n\n/**\n * Generate prioritized recommendations\n */\nfunction generateRecommendations(issues: SeoIssue[], maxUrls: number = 10): Recommendation[] {\n const recommendations: Recommendation[] = [];\n const issueGroups = new Map<string, SeoIssue[]>();\n\n // Group issues by title (similar issues)\n for (const issue of issues) {\n const key = `${issue.category}:${issue.title}`;\n if (!issueGroups.has(key)) {\n issueGroups.set(key, []);\n }\n issueGroups.get(key)!.push(issue);\n }\n\n // Create recommendations for each group\n for (const [, groupedIssues] of issueGroups) {\n const firstIssue = groupedIssues[0];\n if (!firstIssue) continue;\n const severity = firstIssue.severity;\n\n const priority: 1 | 2 | 3 | 4 | 5 =\n severity === 'critical'\n ? 1\n : severity === 'error'\n ? 2\n : severity === 'warning'\n ? 3\n : 4;\n\n const impact: 'high' | 'medium' | 'low' =\n priority <= 2 ? 'high' : priority === 3 ? 'medium' : 'low';\n\n const allUrls = groupedIssues.map((i) => i.url);\n const totalCount = allUrls.length;\n const limitedUrls = allUrls.slice(0, maxUrls);\n\n recommendations.push({\n priority,\n category: firstIssue.category,\n title: firstIssue.title,\n description: totalCount > maxUrls\n ? `${firstIssue.description} (showing ${maxUrls} of ${totalCount} URLs)`\n : firstIssue.description,\n affectedUrls: limitedUrls,\n estimatedImpact: impact,\n actionItems: [firstIssue.recommendation],\n });\n }\n\n // Sort by priority\n return recommendations.sort((a, b) => a.priority - b.priority);\n}\n\n/**\n * Sort issues by severity and category\n */\nfunction sortIssues(issues: SeoIssue[]): SeoIssue[] {\n const severityOrder: Record<IssueSeverity, number> = {\n critical: 0,\n error: 1,\n warning: 2,\n info: 3,\n };\n\n return [...issues].sort((a, b) => {\n const severityDiff = severityOrder[a.severity] - severityOrder[b.severity];\n if (severityDiff !== 0) return severityDiff;\n return a.category.localeCompare(b.category);\n });\n}\n\n/**\n * Generate unique report ID\n */\nfunction generateReportId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `seo-report-${timestamp}-${random}`;\n}\n\n/**\n * Export report as JSON string\n */\nexport function exportJsonReport(report: SeoReport, pretty = true): string {\n return JSON.stringify(report, null, pretty ? 2 : 0);\n}\n\n/**\n * Generate AI-optimized schema for the report\n * This schema helps AI understand the report structure\n */\nexport const AI_REPORT_SCHEMA = {\n $schema: 'http://json-schema.org/draft-07/schema#',\n title: 'SEO Report',\n description: 'AI-friendly SEO analysis report with issues and recommendations',\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Unique report identifier' },\n siteUrl: { type: 'string', description: 'Analyzed site URL' },\n generatedAt: { type: 'string', format: 'date-time' },\n summary: {\n type: 'object',\n description: 'Quick overview of SEO health',\n properties: {\n totalUrls: { type: 'number' },\n indexedUrls: { type: 'number' },\n notIndexedUrls: { type: 'number' },\n healthScore: {\n type: 'number',\n minimum: 0,\n maximum: 100,\n description: '0-100 score, higher is better',\n },\n },\n },\n issues: {\n type: 'array',\n description: 'List of detected SEO issues sorted by severity',\n items: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['critical', 'error', 'warning', 'info'],\n },\n category: {\n type: 'string',\n enum: [\n 'indexing',\n 'crawling',\n 'content',\n 'technical',\n 'mobile',\n 'performance',\n 'structured-data',\n 'security',\n ],\n },\n title: { type: 'string' },\n description: { type: 'string' },\n recommendation: { type: 'string' },\n url: { type: 'string' },\n },\n },\n },\n recommendations: {\n type: 'array',\n description: 'Prioritized action items',\n items: {\n type: 'object',\n properties: {\n priority: { type: 'number', minimum: 1, maximum: 5 },\n title: { type: 'string' },\n affectedUrls: { type: 'array', items: { type: 'string' } },\n actionItems: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n },\n};\n","/**\n * @djangocfg/seo - Markdown Report Generator\n * Generate human-readable Markdown reports\n */\n\nimport type { SeoReport, SeoIssue, IssueSeverity, IssueCategory } from '../types/index.js';\n\nexport interface MarkdownReportOptions {\n includeRawIssues?: boolean;\n includeUrls?: boolean;\n maxUrlsPerIssue?: number;\n}\n\n/**\n * Generate a Markdown report from SEO data\n */\nexport function generateMarkdownReport(\n report: SeoReport,\n options: MarkdownReportOptions = {}\n): string {\n const { includeRawIssues = true, includeUrls = true, maxUrlsPerIssue = 10 } = options;\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# SEO Analysis Report`);\n lines.push('');\n lines.push(`**Site:** ${report.siteUrl}`);\n lines.push(`**Generated:** ${new Date(report.generatedAt).toLocaleString()}`);\n lines.push(`**Report ID:** ${report.id}`);\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| Health Score | ${getHealthScoreEmoji(report.summary.healthScore)} **${report.summary.healthScore}/100** |`);\n lines.push(`| Total URLs | ${report.summary.totalUrls} |`);\n lines.push(`| Indexed URLs | ${report.summary.indexedUrls} |`);\n lines.push(`| Not Indexed | ${report.summary.notIndexedUrls} |`);\n lines.push('');\n\n // Issues by Severity\n lines.push('### Issues by Severity');\n lines.push('');\n const severities: IssueSeverity[] = ['critical', 'error', 'warning', 'info'];\n for (const severity of severities) {\n const count = report.summary.issuesBySeverity[severity] || 0;\n lines.push(`- ${getSeverityEmoji(severity)} **${capitalize(severity)}:** ${count}`);\n }\n lines.push('');\n\n // Issues by Category\n lines.push('### Issues by Category');\n lines.push('');\n const categories = Object.entries(report.summary.issuesByCategory).sort(\n ([, a], [, b]) => b - a\n );\n for (const [category, count] of categories) {\n lines.push(`- ${getCategoryEmoji(category as IssueCategory)} **${formatCategory(category)}:** ${count}`);\n }\n lines.push('');\n\n // Recommendations\n lines.push('## Prioritized Recommendations');\n lines.push('');\n\n for (const rec of report.recommendations) {\n lines.push(`### ${getPriorityEmoji(rec.priority)} Priority ${rec.priority}: ${rec.title}`);\n lines.push('');\n lines.push(`**Category:** ${formatCategory(rec.category)}`);\n lines.push(`**Impact:** ${capitalize(rec.estimatedImpact)}`);\n lines.push(`**Affected URLs:** ${rec.affectedUrls.length}`);\n lines.push('');\n lines.push(`${rec.description}`);\n lines.push('');\n lines.push('**Action Items:**');\n for (const action of rec.actionItems) {\n lines.push(`- ${action}`);\n }\n lines.push('');\n\n if (includeUrls && rec.affectedUrls.length > 0) {\n const urlsToShow = rec.affectedUrls.slice(0, maxUrlsPerIssue);\n lines.push('<details>');\n lines.push(`<summary>Affected URLs (${rec.affectedUrls.length})</summary>`);\n lines.push('');\n for (const url of urlsToShow) {\n lines.push(`- ${url}`);\n }\n if (rec.affectedUrls.length > maxUrlsPerIssue) {\n lines.push(`- ... and ${rec.affectedUrls.length - maxUrlsPerIssue} more`);\n }\n lines.push('</details>');\n lines.push('');\n }\n\n lines.push('---');\n lines.push('');\n }\n\n // Detailed Issues\n if (includeRawIssues) {\n lines.push('## All Issues');\n lines.push('');\n\n const issuesByCategory = groupBy(report.issues, 'category');\n\n for (const [category, issues] of Object.entries(issuesByCategory)) {\n lines.push(`### ${getCategoryEmoji(category as IssueCategory)} ${formatCategory(category)}`);\n lines.push('');\n\n for (const issue of issues) {\n lines.push(\n `#### ${getSeverityEmoji(issue.severity)} ${issue.title}`\n );\n lines.push('');\n lines.push(`**URL:** \\`${issue.url}\\``);\n lines.push(`**Severity:** ${capitalize(issue.severity)}`);\n lines.push('');\n lines.push(issue.description);\n lines.push('');\n lines.push(`**Recommendation:** ${issue.recommendation}`);\n lines.push('');\n }\n }\n }\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push('*Report generated by [@djangocfg/seo](https://djangocfg.com)*');\n lines.push('');\n lines.push('> This report is designed to be processed by AI assistants for automated SEO improvements.');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate a concise summary for AI consumption\n */\nexport function generateAiSummary(report: SeoReport): string {\n const lines: string[] = [];\n\n lines.push('# SEO Report Summary for AI Processing');\n lines.push('');\n lines.push('## Context');\n lines.push(`Site: ${report.siteUrl}`);\n lines.push(`Health Score: ${report.summary.healthScore}/100`);\n lines.push(`Critical Issues: ${report.summary.issuesBySeverity.critical || 0}`);\n lines.push(`Errors: ${report.summary.issuesBySeverity.error || 0}`);\n lines.push(`Warnings: ${report.summary.issuesBySeverity.warning || 0}`);\n lines.push('');\n lines.push('## Top Priority Actions');\n lines.push('');\n\n const topRecommendations = report.recommendations.slice(0, 5);\n for (let i = 0; i < topRecommendations.length; i++) {\n const rec = topRecommendations[i];\n if (!rec) continue;\n lines.push(`${i + 1}. **${rec.title}** (${rec.affectedUrls.length} URLs)`);\n lines.push(` - ${rec.actionItems[0]}`);\n }\n\n lines.push('');\n lines.push('## Issue Categories');\n lines.push('');\n\n const sortedCategories = Object.entries(report.summary.issuesByCategory)\n .sort(([, a], [, b]) => b - a);\n\n for (const [category, count] of sortedCategories) {\n lines.push(`- ${formatCategory(category)}: ${count} issues`);\n }\n\n return lines.join('\\n');\n}\n\n// Helper functions\nfunction getSeverityEmoji(severity: IssueSeverity): string {\n const emojis: Record<IssueSeverity, string> = {\n critical: 'đ´',\n error: 'đ ',\n warning: 'đĄ',\n info: 'đĩ',\n };\n return emojis[severity];\n}\n\nfunction getCategoryEmoji(category: IssueCategory): string {\n const emojis: Record<IssueCategory, string> = {\n indexing: 'đ',\n crawling: 'đˇī¸',\n content: 'đ',\n technical: 'âī¸',\n mobile: 'đą',\n performance: 'âĄ',\n 'structured-data': 'đˇī¸',\n security: 'đ',\n };\n return emojis[category] || 'đ';\n}\n\nfunction getPriorityEmoji(priority: number): string {\n const emojis: Record<number, string> = {\n 1: 'đ¨',\n 2: 'â ī¸',\n 3: 'đ',\n 4: 'đĄ',\n 5: 'âšī¸',\n };\n return emojis[priority] || 'đ';\n}\n\nfunction getHealthScoreEmoji(score: number): string {\n if (score >= 90) return 'đĸ';\n if (score >= 70) return 'đĄ';\n if (score >= 50) return 'đ ';\n return 'đ´';\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction formatCategory(category: string): string {\n return category\n .split('-')\n .map(capitalize)\n .join(' ');\n}\n\nfunction groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {\n return array.reduce(\n (acc, item) => {\n const groupKey = String(item[key]);\n if (!acc[groupKey]) {\n acc[groupKey] = [];\n }\n acc[groupKey].push(item);\n return acc;\n },\n {} as Record<string, T[]>\n );\n}\n","/**\n * @djangocfg/seo - Split Report Generator\n * Generates AI-friendly split reports (max 1000 lines each)\n */\n\nimport { writeFileSync, mkdirSync, existsSync, rmSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { SeoReport, SeoIssue, IssueCategory, IssueSeverity } from '../types/index.js';\n\nconst MAX_LINES = 1000;\n\nexport interface SplitReportOptions {\n outputDir: string;\n /** Clear output directory before generating */\n clearOutputDir?: boolean;\n}\n\nexport interface SplitReportResult {\n indexFile: string;\n categoryFiles: string[];\n totalFiles: number;\n}\n\n/**\n * Generate split reports for AI processing\n */\nexport function generateSplitReports(\n report: SeoReport,\n options: SplitReportOptions\n): SplitReportResult {\n const { outputDir, clearOutputDir = true } = options;\n\n // Clear output directory\n if (clearOutputDir && existsSync(outputDir)) {\n const files = readdirSync(outputDir);\n for (const file of files) {\n if (file.startsWith('seo-') && file.endsWith('.md')) {\n rmSync(join(outputDir, file), { force: true });\n }\n }\n }\n\n // Ensure output directory exists\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n const siteName = new URL(report.siteUrl).hostname.replace(/\\./g, '-');\n const prefix = `seo-${siteName}-${timestamp}`;\n\n const categoryFiles: string[] = [];\n\n // Group issues by category\n const issuesByCategory = groupIssuesByCategory(report.issues);\n const categories = Object.keys(issuesByCategory) as IssueCategory[];\n\n // Generate category files\n for (const category of categories) {\n const issues = issuesByCategory[category] || [];\n if (issues.length === 0) continue;\n\n const chunks = splitIntoChunks(issues, category);\n\n for (let i = 0; i < chunks.length; i++) {\n const suffix = chunks.length > 1 ? `-${i + 1}` : '';\n const filename = `${prefix}-${category}${suffix}.md`;\n const filepath = join(outputDir, filename);\n\n const chunk = chunks[i];\n if (!chunk) continue;\n const content = generateCategoryFile(report.siteUrl, category, chunk, {\n part: chunks.length > 1 ? i + 1 : undefined,\n totalParts: chunks.length > 1 ? chunks.length : undefined,\n });\n\n writeFileSync(filepath, content, 'utf-8');\n categoryFiles.push(filename);\n }\n }\n\n // Generate index file\n const indexFilename = `${prefix}-index.md`;\n const indexFilepath = join(outputDir, indexFilename);\n const indexContent = generateIndexFile(report, categoryFiles);\n writeFileSync(indexFilepath, indexContent, 'utf-8');\n\n return {\n indexFile: indexFilename,\n categoryFiles,\n totalFiles: categoryFiles.length + 1,\n };\n}\n\n/**\n * Generate compact index file\n */\nfunction generateIndexFile(report: SeoReport, categoryFiles: string[]): string {\n const lines: string[] = [];\n\n lines.push('# SEO Report Index');\n lines.push('');\n lines.push(`Site: ${report.siteUrl}`);\n lines.push(`Score: ${report.summary.healthScore}/100`);\n lines.push(`Date: ${report.generatedAt.slice(0, 10)}`);\n lines.push('');\n\n // Severity counts\n lines.push('## Issues');\n lines.push('');\n lines.push('| Severity | Count |');\n lines.push('|----------|-------|');\n const severities: IssueSeverity[] = ['critical', 'error', 'warning', 'info'];\n for (const sev of severities) {\n const count = report.summary.issuesBySeverity[sev] || 0;\n if (count > 0) {\n lines.push(`| ${sev} | ${count} |`);\n }\n }\n lines.push('');\n\n // Top 10 recommendations (compact)\n lines.push('## Actions');\n lines.push('');\n const topRecs = report.recommendations.slice(0, 10);\n for (let i = 0; i < topRecs.length; i++) {\n const rec = topRecs[i];\n if (!rec) continue;\n lines.push(`${i + 1}. **${rec.title}** (${rec.affectedUrls.length})`);\n lines.push(` ${rec.actionItems[0]}`);\n }\n lines.push('');\n\n // File index\n lines.push('## Files');\n lines.push('');\n for (const file of categoryFiles) {\n lines.push(`- [${file}](./${file})`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate compact category file\n */\nfunction generateCategoryFile(\n siteUrl: string,\n category: IssueCategory,\n issues: SeoIssue[],\n opts: { part?: number; totalParts?: number }\n): string {\n const lines: string[] = [];\n const partStr = opts.part ? ` (Part ${opts.part}/${opts.totalParts})` : '';\n\n lines.push(`# ${formatCategory(category)}${partStr}`);\n lines.push('');\n lines.push(`Site: ${siteUrl}`);\n lines.push(`Issues: ${issues.length}`);\n lines.push('');\n\n // Group by title for compact display\n const byTitle = new Map<string, SeoIssue[]>();\n for (const issue of issues) {\n const group = byTitle.get(issue.title) || [];\n group.push(issue);\n byTitle.set(issue.title, group);\n }\n\n for (const [title, groupIssues] of byTitle) {\n const first = groupIssues[0];\n if (!first) continue;\n\n lines.push(`## ${title}`);\n lines.push('');\n lines.push(`Severity: ${first.severity}`);\n lines.push(`Count: ${groupIssues.length}`);\n lines.push('');\n lines.push(`> ${first.recommendation}`);\n lines.push('');\n\n // Compact URL list\n lines.push('URLs:');\n for (const issue of groupIssues.slice(0, 20)) {\n lines.push(`- ${issue.url}`);\n }\n if (groupIssues.length > 20) {\n lines.push(`- ... +${groupIssues.length - 20} more`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Split issues into chunks that fit within MAX_LINES\n */\nfunction splitIntoChunks(issues: SeoIssue[], category: IssueCategory): SeoIssue[][] {\n // Estimate lines per issue group (title + severity + recommendation + URLs)\n const byTitle = new Map<string, SeoIssue[]>();\n for (const issue of issues) {\n const group = byTitle.get(issue.title) || [];\n group.push(issue);\n byTitle.set(issue.title, group);\n }\n\n const chunks: SeoIssue[][] = [];\n let currentChunk: SeoIssue[] = [];\n let currentLines = 10; // Header overhead\n\n for (const [, groupIssues] of byTitle) {\n // Estimate: 6 lines header + min(20, count) URLs + 2 spacing\n const urlCount = Math.min(20, groupIssues.length);\n const groupLines = 8 + urlCount;\n\n if (currentLines + groupLines > MAX_LINES && currentChunk.length > 0) {\n chunks.push(currentChunk);\n currentChunk = [];\n currentLines = 10;\n }\n\n currentChunk.push(...groupIssues);\n currentLines += groupLines;\n }\n\n if (currentChunk.length > 0) {\n chunks.push(currentChunk);\n }\n\n return chunks.length > 0 ? chunks : [[]];\n}\n\nfunction groupIssuesByCategory(issues: SeoIssue[]): Record<IssueCategory, SeoIssue[]> {\n const result: Partial<Record<IssueCategory, SeoIssue[]>> = {};\n\n for (const issue of issues) {\n if (!result[issue.category]) {\n result[issue.category] = [];\n }\n result[issue.category]!.push(issue);\n }\n\n return result as Record<IssueCategory, SeoIssue[]>;\n}\n\nfunction formatCategory(category: string): string {\n return category\n .split('-')\n .map(s => s.charAt(0).toUpperCase() + s.slice(1))\n .join(' ');\n}\n","/**\n * @djangocfg/seo - CLAUDE.md Generator\n * Generates AI context file with package docs and current audit state\n */\n\nimport type { SeoReport } from '../types/index.js';\n\n/**\n * Generate CLAUDE.md content for AI context\n */\nexport function generateClaudeContext(report: SeoReport): string {\n const lines: string[] = [];\n\n // Package docs (static)\n lines.push('# @djangocfg/seo');\n lines.push('');\n lines.push('SEO audit toolkit. Generates AI-optimized split reports (max 1000 lines each).');\n lines.push('');\n lines.push('## Commands');\n lines.push('');\n lines.push('```bash');\n lines.push('# Audit (HTTP-based, crawls live site)');\n lines.push('pnpm seo:audit # Full audit (split reports)');\n lines.push('pnpm seo:audit --env dev # Audit local dev');\n lines.push('pnpm seo:audit --format all # All formats');\n lines.push('');\n lines.push('# Content (file-based, scans MDX/content/)');\n lines.push('pnpm exec djangocfg-seo content check # Check MDX links');\n lines.push('pnpm exec djangocfg-seo content fix # Show fixable links');\n lines.push('pnpm exec djangocfg-seo content fix --fix # Apply fixes');\n lines.push('pnpm exec djangocfg-seo content sitemap # Generate sitemap.ts');\n lines.push('```');\n lines.push('');\n lines.push('## Options');\n lines.push('');\n lines.push('- `--env, -e` - prod (default) or dev');\n lines.push('- `--site, -s` - Site URL (overrides env)');\n lines.push('- `--output, -o` - Output directory');\n lines.push('- `--format, -f` - split (default), json, markdown, ai-summary, all');\n lines.push('- `--max-pages` - Max pages (default: 100)');\n lines.push('- `--service-account` - Google service account JSON path');\n lines.push('- `--content-dir` - Content directory (default: content/)');\n lines.push('- `--base-path` - Base URL path for docs (default: /docs)');\n lines.push('');\n lines.push('## Reports');\n lines.push('');\n lines.push('- `seo-*-index.md` - Summary + links to categories');\n lines.push('- `seo-*-technical.md` - Broken links, sitemap issues');\n lines.push('- `seo-*-content.md` - H1, meta, title issues');\n lines.push('- `seo-*-performance.md` - Load time, TTFB issues');\n lines.push('- `seo-ai-summary-*.md` - Quick overview');\n lines.push('');\n\n // Issue types - important for AI to understand priorities\n lines.push('## Issue Severity');\n lines.push('');\n lines.push('- **critical** - Blocks indexing (fix immediately)');\n lines.push('- **error** - SEO problems (high priority)');\n lines.push('- **warning** - Recommendations (medium priority)');\n lines.push('- **info** - Best practices (low priority)');\n lines.push('');\n lines.push('## Issue Categories');\n lines.push('');\n lines.push('- **technical** - Broken links, sitemap, robots.txt');\n lines.push('- **content** - Missing H1, meta description, title');\n lines.push('- **indexing** - Not indexed, crawl errors from GSC');\n lines.push('- **performance** - Slow load time (>3s), high TTFB (>800ms)');\n lines.push('');\n\n // Routes info\n lines.push('## Routes Scanner');\n lines.push('');\n lines.push('Scans Next.js App Router `app/` directory. Handles:');\n lines.push('- Route groups `(group)` - ignored in URL');\n lines.push('- Dynamic `[slug]` - shown as `:slug`');\n lines.push('- Catch-all `[...slug]` - shown as `:...slug`');\n lines.push('- Parallel `@folder` - skipped');\n lines.push('- Private `_folder` - skipped');\n lines.push('');\n\n // Link guidelines\n lines.push('## Link Guidelines');\n lines.push('');\n lines.push('### Nextra/MDX Projects (content/)');\n lines.push('');\n lines.push('For non-index files (e.g., `overview.mdx`):');\n lines.push('- **Sibling file**: `../sibling` (one level up)');\n lines.push('- **Other section**: `/docs/full/path` (absolute)');\n lines.push('- **AVOID**: `./sibling` (browser adds filename to path!)');\n lines.push('- **AVOID**: `../../deep/path` (hard to maintain)');\n lines.push('');\n lines.push('For index files (e.g., `index.mdx`):');\n lines.push('- **Child file**: `./child` works correctly');\n lines.push('- **Sibling folder**: `../sibling/` or absolute');\n lines.push('');\n lines.push('### Next.js App Router Projects');\n lines.push('');\n lines.push('Use declarative routes from `_routes/`:');\n lines.push('```typescript');\n lines.push('import { routes } from \"@/app/_routes\";');\n lines.push('<Link href={routes.dashboard.machines}>Machines</Link>');\n lines.push('```');\n lines.push('');\n lines.push('Benefits: type-safe, refactor-friendly, centralized.');\n lines.push('');\n\n // Current audit state (dynamic)\n lines.push('---');\n lines.push('');\n lines.push('## Current Audit');\n lines.push('');\n lines.push(`Site: ${report.siteUrl}`);\n lines.push(`Score: ${report.summary.healthScore}/100`);\n lines.push(`Date: ${report.generatedAt.slice(0, 10)}`);\n lines.push('');\n\n // Issue summary\n lines.push('### Issues');\n lines.push('');\n const { critical = 0, error = 0, warning = 0, info = 0 } = report.summary.issuesBySeverity;\n if (critical > 0) lines.push(`- Critical: ${critical}`);\n if (error > 0) lines.push(`- Error: ${error}`);\n if (warning > 0) lines.push(`- Warning: ${warning}`);\n if (info > 0) lines.push(`- Info: ${info}`);\n lines.push('');\n\n // Top 5 actions\n lines.push('### Top Actions');\n lines.push('');\n const topRecs = report.recommendations.slice(0, 5);\n for (let i = 0; i < topRecs.length; i++) {\n const rec = topRecs[i];\n if (!rec) continue;\n lines.push(`${i + 1}. **${rec.title}** (${rec.affectedUrls.length} URLs)`);\n }\n lines.push('');\n\n // Report files in this directory\n lines.push('### Report Files');\n lines.push('');\n lines.push('See split reports in this directory:');\n lines.push('- `seo-*-index.md` - Start here');\n lines.push('- `seo-*-technical.md` - Technical issues');\n lines.push('- `seo-*-content.md` - Content issues');\n lines.push('- `seo-*-performance.md` - Performance issues');\n lines.push('');\n\n return lines.join('\\n');\n}\n","/**\n * @djangocfg/seo - Report Generator\n * Main report generation orchestrator\n */\n\nimport { writeFileSync, mkdirSync, existsSync, rmSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport consola from 'consola';\nimport { generateJsonReport, exportJsonReport } from './json-report.js';\nimport { generateMarkdownReport, generateAiSummary } from './markdown-report.js';\nimport { generateSplitReports } from './split-report.js';\nimport { generateClaudeContext } from './claude-context.js';\nimport type {\n SeoReport,\n SeoIssue,\n UrlInspectionResult,\n CrawlResult,\n IssueCategory,\n IssueSeverity,\n} from '../types/index.js';\n\nexport interface ReportGeneratorOptions {\n outputDir: string;\n formats: ('json' | 'markdown' | 'ai-summary' | 'split')[];\n includeRawData?: boolean;\n timestamp?: boolean;\n /** Clear output directory before generating reports */\n clearOutputDir?: boolean;\n /** Maximum URLs to show per issue group (default: 10) */\n maxUrlsPerIssue?: number;\n}\n\nexport interface GeneratedReports {\n report: SeoReport;\n files: {\n json?: string;\n markdown?: string;\n aiSummary?: string;\n split?: {\n index: string;\n categories: string[];\n };\n };\n}\n\n/**\n * Generate and save SEO reports\n */\nexport async function generateAndSaveReports(\n siteUrl: string,\n data: {\n issues: SeoIssue[];\n urlInspections?: UrlInspectionResult[];\n crawlResults?: CrawlResult[];\n },\n options: ReportGeneratorOptions\n): Promise<GeneratedReports> {\n const {\n outputDir,\n formats,\n includeRawData = false,\n timestamp = true,\n clearOutputDir = true,\n maxUrlsPerIssue = 10,\n } = options;\n\n // Clear output directory if requested\n if (clearOutputDir && existsSync(outputDir)) {\n try {\n const files = readdirSync(outputDir);\n for (const file of files) {\n if (file.startsWith('seo-')) {\n rmSync(join(outputDir, file), { force: true });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Ensure output directory exists\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n // Generate the report\n const report = generateJsonReport(siteUrl, data, { includeRawData, maxUrlsPerIssue });\n\n const result: GeneratedReports = {\n report,\n files: {},\n };\n\n // Generate timestamp for filenames\n const ts = timestamp\n ? `-${new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)}`\n : '';\n const siteName = new URL(siteUrl).hostname.replace(/\\./g, '-');\n\n // Generate JSON report\n if (formats.includes('json')) {\n const filename = `seo-report-${siteName}${ts}.json`;\n const filepath = join(outputDir, filename);\n const content = exportJsonReport(report, true);\n writeFileSync(filepath, content, 'utf-8');\n result.files.json = filepath;\n consola.success(`JSON report saved: ${filepath}`);\n }\n\n // Generate Markdown report\n if (formats.includes('markdown')) {\n const filename = `seo-report-${siteName}${ts}.md`;\n const filepath = join(outputDir, filename);\n const content = generateMarkdownReport(report, {\n includeRawIssues: true,\n includeUrls: true,\n });\n writeFileSync(filepath, content, 'utf-8');\n result.files.markdown = filepath;\n consola.success(`Markdown report saved: ${filepath}`);\n }\n\n // Generate AI summary\n if (formats.includes('ai-summary')) {\n const filename = `seo-ai-summary-${siteName}${ts}.md`;\n const filepath = join(outputDir, filename);\n const content = generateAiSummary(report);\n writeFileSync(filepath, content, 'utf-8');\n result.files.aiSummary = filepath;\n consola.success(`AI summary saved: ${filepath}`);\n }\n\n // Generate split reports (AI-optimized, max 1000 lines each)\n if (formats.includes('split')) {\n const splitResult = generateSplitReports(report, {\n outputDir,\n clearOutputDir: false, // Already cleared above\n });\n result.files.split = {\n index: join(outputDir, splitResult.indexFile),\n categories: splitResult.categoryFiles.map(f => join(outputDir, f)),\n };\n consola.success(`Split reports saved: ${splitResult.totalFiles} files (index + ${splitResult.categoryFiles.length} categories)`);\n }\n\n // Always generate CLAUDE.md for AI context\n const claudeContent = generateClaudeContext(report);\n const claudeFilepath = join(outputDir, 'CLAUDE.md');\n writeFileSync(claudeFilepath, claudeContent, 'utf-8');\n consola.success(`AI context saved: ${claudeFilepath}`);\n\n return result;\n}\n\n/**\n * Print report summary to console\n */\nexport function printReportSummary(report: SeoReport): void {\n consola.box(\n `SEO Report: ${report.siteUrl}\\n` +\n `Health Score: ${report.summary.healthScore}/100\\n` +\n `Total URLs: ${report.summary.totalUrls}\\n` +\n `Indexed: ${report.summary.indexedUrls} | Not Indexed: ${report.summary.notIndexedUrls}\\n` +\n `Issues: ${report.issues.length}`\n );\n\n if (report.summary.issuesBySeverity.critical) {\n consola.error(`Critical issues: ${report.summary.issuesBySeverity.critical}`);\n }\n if (report.summary.issuesBySeverity.error) {\n consola.warn(`Errors: ${report.summary.issuesBySeverity.error}`);\n }\n if (report.summary.issuesBySeverity.warning) {\n consola.info(`Warnings: ${report.summary.issuesBySeverity.warning}`);\n }\n\n consola.log('');\n consola.info('Top recommendations:');\n for (const rec of report.recommendations.slice(0, 3)) {\n consola.log(` ${rec.priority}. ${rec.title} (${rec.affectedUrls.length} URLs)`);\n }\n}\n\n/**\n * Merge multiple reports into one\n */\nexport function mergeReports(reports: SeoReport[]): SeoReport {\n if (reports.length === 0) {\n throw new Error('Cannot merge empty reports array');\n }\n\n const merged: SeoReport = {\n id: `merged-${Date.now().toString(36)}`,\n siteUrl: reports.map((r) => r.siteUrl).join(', '),\n generatedAt: new Date().toISOString(),\n summary: {\n totalUrls: reports.reduce((sum, r) => sum + r.summary.totalUrls, 0),\n indexedUrls: reports.reduce((sum, r) => sum + r.summary.indexedUrls, 0),\n notIndexedUrls: reports.reduce((sum, r) => sum + r.summary.notIndexedUrls, 0),\n issuesByCategory: {} as any,\n issuesBySeverity: {} as any,\n healthScore: Math.round(\n reports.reduce((sum, r) => sum + r.summary.healthScore, 0) / reports.length\n ),\n },\n issues: reports.flatMap((r) => r.issues),\n urlInspections: reports.flatMap((r) => r.urlInspections),\n crawlResults: reports.flatMap((r) => r.crawlResults),\n recommendations: [],\n };\n\n // Merge issue counts\n for (const report of reports) {\n for (const [category, count] of Object.entries(report.summary.issuesByCategory)) {\n const cat = category as IssueCategory;\n merged.summary.issuesByCategory[cat] =\n (merged.summary.issuesByCategory[cat] || 0) + count;\n }\n for (const [severity, count] of Object.entries(report.summary.issuesBySeverity)) {\n const sev = severity as IssueSeverity;\n merged.summary.issuesBySeverity[sev] =\n (merged.summary.issuesBySeverity[sev] || 0) + count;\n }\n }\n\n // Merge and deduplicate recommendations\n const recMap = new Map<string, typeof merged.recommendations[0]>();\n for (const report of reports) {\n for (const rec of report.recommendations) {\n const key = `${rec.category}:${rec.title}`;\n if (recMap.has(key)) {\n const existing = recMap.get(key)!;\n existing.affectedUrls.push(...rec.affectedUrls);\n } else {\n recMap.set(key, { ...rec, affectedUrls: [...rec.affectedUrls] });\n }\n }\n }\n merged.recommendations = Array.from(recMap.values()).sort(\n (a, b) => a.priority - b.priority\n );\n\n return merged;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/reports/json-report.ts","../../src/reports/markdown-report.ts","../../src/reports/split-report.ts","../../src/reports/claude-context.ts","../../src/reports/generator.ts"],"names":["formatCategory","existsSync","readdirSync","rmSync","join","mkdirSync","writeFileSync"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @djangocfg/seo - JSON Report Generator\n * Generate AI-friendly JSON reports\n */\n\nimport type {\n SeoReport,\n SeoIssue,\n UrlInspectionResult,\n CrawlResult,\n ReportSummary,\n Recommendation,\n IssueCategory,\n IssueSeverity,\n} from '../types/index.js';\n\nexport interface JsonReportOptions {\n includeRawData?: boolean;\n prettyPrint?: boolean;\n /** Maximum URLs to include per issue group (default: 10) */\n maxUrlsPerIssue?: number;\n}\n\n/**\n * Generate a comprehensive JSON report\n */\nexport function generateJsonReport(\n siteUrl: string,\n data: {\n issues: SeoIssue[];\n urlInspections?: UrlInspectionResult[];\n crawlResults?: CrawlResult[];\n },\n options: JsonReportOptions = {}\n): SeoReport {\n const { issues, urlInspections = [], crawlResults = [] } = data;\n const maxUrlsPerIssue = options.maxUrlsPerIssue ?? 10;\n\n // Limit issues to maxUrlsPerIssue per title group\n const limitedIssues = limitIssuesByTitle(issues, maxUrlsPerIssue);\n\n const report: SeoReport = {\n id: generateReportId(),\n siteUrl,\n generatedAt: new Date().toISOString(),\n summary: generateSummary(issues, urlInspections, crawlResults), // Use original for accurate counts\n issues: sortIssues(limitedIssues),\n urlInspections: options.includeRawData ? urlInspections.slice(0, 100) : [],\n crawlResults: options.includeRawData ? crawlResults.slice(0, 100) : [],\n recommendations: generateRecommendations(issues, maxUrlsPerIssue),\n };\n\n return report;\n}\n\n/**\n * Limit issues to maxUrls per issue title group\n */\nfunction limitIssuesByTitle(issues: SeoIssue[], maxUrls: number): SeoIssue[] {\n const byTitle = new Map<string, SeoIssue[]>();\n\n for (const issue of issues) {\n const existing = byTitle.get(issue.title) || [];\n existing.push(issue);\n byTitle.set(issue.title, existing);\n }\n\n const limited: SeoIssue[] = [];\n for (const [, group] of byTitle) {\n const sorted = group.sort((a, b) => {\n const severityOrder = { critical: 0, error: 1, warning: 2, info: 3 };\n return severityOrder[a.severity] - severityOrder[b.severity];\n });\n limited.push(...sorted.slice(0, maxUrls));\n }\n\n return limited;\n}\n\n/**\n * Generate report summary\n */\nfunction generateSummary(\n issues: SeoIssue[],\n urlInspections: UrlInspectionResult[],\n crawlResults: CrawlResult[]\n): ReportSummary {\n const totalUrls = Math.max(\n urlInspections.length,\n crawlResults.length,\n new Set(issues.map((i) => i.url)).size\n );\n\n const indexedUrls = urlInspections.filter(\n (r) => r.indexStatusResult.coverageState === 'SUBMITTED_AND_INDEXED'\n ).length;\n\n const notIndexedUrls = urlInspections.filter(\n (r) =>\n r.indexStatusResult.coverageState === 'NOT_INDEXED' ||\n r.indexStatusResult.coverageState === 'CRAWLED_CURRENTLY_NOT_INDEXED' ||\n r.indexStatusResult.coverageState === 'DISCOVERED_CURRENTLY_NOT_INDEXED'\n ).length;\n\n const issuesByCategory = issues.reduce(\n (acc, issue) => {\n acc[issue.category] = (acc[issue.category] || 0) + 1;\n return acc;\n },\n {} as Record<IssueCategory, number>\n );\n\n const issuesBySeverity = issues.reduce(\n (acc, issue) => {\n acc[issue.severity] = (acc[issue.severity] || 0) + 1;\n return acc;\n },\n {} as Record<IssueSeverity, number>\n );\n\n // Calculate health score (0-100)\n const healthScore = calculateHealthScore(issues, totalUrls);\n\n return {\n totalUrls,\n indexedUrls,\n notIndexedUrls,\n issuesByCategory,\n issuesBySeverity,\n healthScore,\n };\n}\n\n/**\n * Calculate overall SEO health score\n */\nfunction calculateHealthScore(issues: SeoIssue[], totalUrls: number): number {\n if (totalUrls === 0) return 100;\n\n const severityWeights: Record<IssueSeverity, number> = {\n critical: 10,\n error: 5,\n warning: 2,\n info: 0.5,\n };\n\n const totalPenalty = issues.reduce(\n (sum, issue) => sum + severityWeights[issue.severity],\n 0\n );\n\n // Max penalty per URL is 20 points\n const maxPenalty = totalUrls * 20;\n const penaltyRatio = Math.min(totalPenalty / maxPenalty, 1);\n\n return Math.round((1 - penaltyRatio) * 100);\n}\n\n/**\n * Generate prioritized recommendations\n */\nfunction generateRecommendations(issues: SeoIssue[], maxUrls: number = 10): Recommendation[] {\n const recommendations: Recommendation[] = [];\n const issueGroups = new Map<string, SeoIssue[]>();\n\n // Group issues by title (similar issues)\n for (const issue of issues) {\n const key = `${issue.category}:${issue.title}`;\n if (!issueGroups.has(key)) {\n issueGroups.set(key, []);\n }\n issueGroups.get(key)!.push(issue);\n }\n\n // Create recommendations for each group\n for (const [, groupedIssues] of issueGroups) {\n const firstIssue = groupedIssues[0];\n if (!firstIssue) continue;\n const severity = firstIssue.severity;\n\n const priority: 1 | 2 | 3 | 4 | 5 =\n severity === 'critical'\n ? 1\n : severity === 'error'\n ? 2\n : severity === 'warning'\n ? 3\n : 4;\n\n const impact: 'high' | 'medium' | 'low' =\n priority <= 2 ? 'high' : priority === 3 ? 'medium' : 'low';\n\n const allUrls = groupedIssues.map((i) => i.url);\n const totalCount = allUrls.length;\n const limitedUrls = allUrls.slice(0, maxUrls);\n\n recommendations.push({\n priority,\n category: firstIssue.category,\n title: firstIssue.title,\n description: totalCount > maxUrls\n ? `${firstIssue.description} (showing ${maxUrls} of ${totalCount} URLs)`\n : firstIssue.description,\n affectedUrls: limitedUrls,\n estimatedImpact: impact,\n actionItems: [firstIssue.recommendation],\n });\n }\n\n // Sort by priority\n return recommendations.sort((a, b) => a.priority - b.priority);\n}\n\n/**\n * Sort issues by severity and category\n */\nfunction sortIssues(issues: SeoIssue[]): SeoIssue[] {\n const severityOrder: Record<IssueSeverity, number> = {\n critical: 0,\n error: 1,\n warning: 2,\n info: 3,\n };\n\n return [...issues].sort((a, b) => {\n const severityDiff = severityOrder[a.severity] - severityOrder[b.severity];\n if (severityDiff !== 0) return severityDiff;\n return a.category.localeCompare(b.category);\n });\n}\n\n/**\n * Generate unique report ID\n */\nfunction generateReportId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `seo-report-${timestamp}-${random}`;\n}\n\n/**\n * Export report as JSON string\n */\nexport function exportJsonReport(report: SeoReport, pretty = true): string {\n return JSON.stringify(report, null, pretty ? 2 : 0);\n}\n\n/**\n * Generate AI-optimized schema for the report\n * This schema helps AI understand the report structure\n */\nexport const AI_REPORT_SCHEMA = {\n $schema: 'http://json-schema.org/draft-07/schema#',\n title: 'SEO Report',\n description: 'AI-friendly SEO analysis report with issues and recommendations',\n type: 'object',\n properties: {\n id: { type: 'string', description: 'Unique report identifier' },\n siteUrl: { type: 'string', description: 'Analyzed site URL' },\n generatedAt: { type: 'string', format: 'date-time' },\n summary: {\n type: 'object',\n description: 'Quick overview of SEO health',\n properties: {\n totalUrls: { type: 'number' },\n indexedUrls: { type: 'number' },\n notIndexedUrls: { type: 'number' },\n healthScore: {\n type: 'number',\n minimum: 0,\n maximum: 100,\n description: '0-100 score, higher is better',\n },\n },\n },\n issues: {\n type: 'array',\n description: 'List of detected SEO issues sorted by severity',\n items: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['critical', 'error', 'warning', 'info'],\n },\n category: {\n type: 'string',\n enum: [\n 'indexing',\n 'crawling',\n 'content',\n 'technical',\n 'mobile',\n 'performance',\n 'structured-data',\n 'security',\n ],\n },\n title: { type: 'string' },\n description: { type: 'string' },\n recommendation: { type: 'string' },\n url: { type: 'string' },\n },\n },\n },\n recommendations: {\n type: 'array',\n description: 'Prioritized action items',\n items: {\n type: 'object',\n properties: {\n priority: { type: 'number', minimum: 1, maximum: 5 },\n title: { type: 'string' },\n affectedUrls: { type: 'array', items: { type: 'string' } },\n actionItems: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n },\n};\n","/**\n * @djangocfg/seo - Markdown Report Generator\n * Generate human-readable Markdown reports\n */\n\nimport type { SeoReport, SeoIssue, IssueSeverity, IssueCategory } from '../types/index.js';\n\nexport interface MarkdownReportOptions {\n includeRawIssues?: boolean;\n includeUrls?: boolean;\n maxUrlsPerIssue?: number;\n}\n\n/**\n * Generate a Markdown report from SEO data\n */\nexport function generateMarkdownReport(\n report: SeoReport,\n options: MarkdownReportOptions = {}\n): string {\n const { includeRawIssues = true, includeUrls = true, maxUrlsPerIssue = 10 } = options;\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# SEO Analysis Report`);\n lines.push('');\n lines.push(`**Site:** ${report.siteUrl}`);\n lines.push(`**Generated:** ${new Date(report.generatedAt).toLocaleString()}`);\n lines.push(`**Report ID:** ${report.id}`);\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| Health Score | ${getHealthScoreEmoji(report.summary.healthScore)} **${report.summary.healthScore}/100** |`);\n lines.push(`| Total URLs | ${report.summary.totalUrls} |`);\n lines.push(`| Indexed URLs | ${report.summary.indexedUrls} |`);\n lines.push(`| Not Indexed | ${report.summary.notIndexedUrls} |`);\n lines.push('');\n\n // Issues by Severity\n lines.push('### Issues by Severity');\n lines.push('');\n const severities: IssueSeverity[] = ['critical', 'error', 'warning', 'info'];\n for (const severity of severities) {\n const count = report.summary.issuesBySeverity[severity] || 0;\n lines.push(`- ${getSeverityEmoji(severity)} **${capitalize(severity)}:** ${count}`);\n }\n lines.push('');\n\n // Issues by Category\n lines.push('### Issues by Category');\n lines.push('');\n const categories = Object.entries(report.summary.issuesByCategory).sort(\n ([, a], [, b]) => b - a\n );\n for (const [category, count] of categories) {\n lines.push(`- ${getCategoryEmoji(category as IssueCategory)} **${formatCategory(category)}:** ${count}`);\n }\n lines.push('');\n\n // Recommendations\n lines.push('## Prioritized Recommendations');\n lines.push('');\n\n for (const rec of report.recommendations) {\n lines.push(`### ${getPriorityEmoji(rec.priority)} Priority ${rec.priority}: ${rec.title}`);\n lines.push('');\n lines.push(`**Category:** ${formatCategory(rec.category)}`);\n lines.push(`**Impact:** ${capitalize(rec.estimatedImpact)}`);\n lines.push(`**Affected URLs:** ${rec.affectedUrls.length}`);\n lines.push('');\n lines.push(`${rec.description}`);\n lines.push('');\n lines.push('**Action Items:**');\n for (const action of rec.actionItems) {\n lines.push(`- ${action}`);\n }\n lines.push('');\n\n if (includeUrls && rec.affectedUrls.length > 0) {\n const urlsToShow = rec.affectedUrls.slice(0, maxUrlsPerIssue);\n lines.push('<details>');\n lines.push(`<summary>Affected URLs (${rec.affectedUrls.length})</summary>`);\n lines.push('');\n for (const url of urlsToShow) {\n lines.push(`- ${url}`);\n }\n if (rec.affectedUrls.length > maxUrlsPerIssue) {\n lines.push(`- ... and ${rec.affectedUrls.length - maxUrlsPerIssue} more`);\n }\n lines.push('</details>');\n lines.push('');\n }\n\n lines.push('---');\n lines.push('');\n }\n\n // Detailed Issues\n if (includeRawIssues) {\n lines.push('## All Issues');\n lines.push('');\n\n const issuesByCategory = groupBy(report.issues, 'category');\n\n for (const [category, issues] of Object.entries(issuesByCategory)) {\n lines.push(`### ${getCategoryEmoji(category as IssueCategory)} ${formatCategory(category)}`);\n lines.push('');\n\n for (const issue of issues) {\n lines.push(\n `#### ${getSeverityEmoji(issue.severity)} ${issue.title}`\n );\n lines.push('');\n lines.push(`**URL:** \\`${issue.url}\\``);\n lines.push(`**Severity:** ${capitalize(issue.severity)}`);\n lines.push('');\n lines.push(issue.description);\n lines.push('');\n lines.push(`**Recommendation:** ${issue.recommendation}`);\n lines.push('');\n }\n }\n }\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push('*Report generated by [@djangocfg/seo](https://djangocfg.com)*');\n lines.push('');\n lines.push('> This report is designed to be processed by AI assistants for automated SEO improvements.');\n\n return lines.join('\\n');\n}\n\n/**\n * Generate a concise summary for AI consumption\n */\nexport function generateAiSummary(report: SeoReport): string {\n const lines: string[] = [];\n\n lines.push('# SEO Report Summary for AI Processing');\n lines.push('');\n lines.push('## Context');\n lines.push(`Site: ${report.siteUrl}`);\n lines.push(`Health Score: ${report.summary.healthScore}/100`);\n lines.push(`Critical Issues: ${report.summary.issuesBySeverity.critical || 0}`);\n lines.push(`Errors: ${report.summary.issuesBySeverity.error || 0}`);\n lines.push(`Warnings: ${report.summary.issuesBySeverity.warning || 0}`);\n lines.push('');\n lines.push('## Top Priority Actions');\n lines.push('');\n\n const topRecommendations = report.recommendations.slice(0, 5);\n for (let i = 0; i < topRecommendations.length; i++) {\n const rec = topRecommendations[i];\n if (!rec) continue;\n lines.push(`${i + 1}. **${rec.title}** (${rec.affectedUrls.length} URLs)`);\n lines.push(` - ${rec.actionItems[0]}`);\n }\n\n lines.push('');\n lines.push('## Issue Categories');\n lines.push('');\n\n const sortedCategories = Object.entries(report.summary.issuesByCategory)\n .sort(([, a], [, b]) => b - a);\n\n for (const [category, count] of sortedCategories) {\n lines.push(`- ${formatCategory(category)}: ${count} issues`);\n }\n\n return lines.join('\\n');\n}\n\n// Helper functions\nfunction getSeverityEmoji(severity: IssueSeverity): string {\n const emojis: Record<IssueSeverity, string> = {\n critical: 'đ´',\n error: 'đ ',\n warning: 'đĄ',\n info: 'đĩ',\n };\n return emojis[severity];\n}\n\nfunction getCategoryEmoji(category: IssueCategory): string {\n const emojis: Record<IssueCategory, string> = {\n indexing: 'đ',\n crawling: 'đˇī¸',\n content: 'đ',\n technical: 'âī¸',\n mobile: 'đą',\n performance: 'âĄ',\n 'structured-data': 'đˇī¸',\n security: 'đ',\n };\n return emojis[category] || 'đ';\n}\n\nfunction getPriorityEmoji(priority: number): string {\n const emojis: Record<number, string> = {\n 1: 'đ¨',\n 2: 'â ī¸',\n 3: 'đ',\n 4: 'đĄ',\n 5: 'âšī¸',\n };\n return emojis[priority] || 'đ';\n}\n\nfunction getHealthScoreEmoji(score: number): string {\n if (score >= 90) return 'đĸ';\n if (score >= 70) return 'đĄ';\n if (score >= 50) return 'đ ';\n return 'đ´';\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction formatCategory(category: string): string {\n return category\n .split('-')\n .map(capitalize)\n .join(' ');\n}\n\nfunction groupBy<T>(array: T[], key: keyof T): Record<string, T[]> {\n return array.reduce(\n (acc, item) => {\n const groupKey = String(item[key]);\n if (!acc[groupKey]) {\n acc[groupKey] = [];\n }\n acc[groupKey].push(item);\n return acc;\n },\n {} as Record<string, T[]>\n );\n}\n","/**\n * @djangocfg/seo - Split Report Generator\n * Generates AI-friendly split reports (max 1000 lines each)\n */\n\nimport { writeFileSync, mkdirSync, existsSync, rmSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { SeoReport, SeoIssue, IssueCategory, IssueSeverity } from '../types/index.js';\n\nconst MAX_LINES = 1000;\n\nexport interface SplitReportOptions {\n outputDir: string;\n /** Clear output directory before generating */\n clearOutputDir?: boolean;\n}\n\nexport interface SplitReportResult {\n indexFile: string;\n categoryFiles: string[];\n totalFiles: number;\n}\n\n/**\n * Generate split reports for AI processing\n */\nexport function generateSplitReports(\n report: SeoReport,\n options: SplitReportOptions\n): SplitReportResult {\n const { outputDir, clearOutputDir = true } = options;\n\n // Clear output directory\n if (clearOutputDir && existsSync(outputDir)) {\n const files = readdirSync(outputDir);\n for (const file of files) {\n if (file.startsWith('seo-') && file.endsWith('.md')) {\n rmSync(join(outputDir, file), { force: true });\n }\n }\n }\n\n // Ensure output directory exists\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);\n const siteName = new URL(report.siteUrl).hostname.replace(/\\./g, '-');\n const prefix = `seo-${siteName}-${timestamp}`;\n\n const categoryFiles: string[] = [];\n\n // Group issues by category\n const issuesByCategory = groupIssuesByCategory(report.issues);\n const categories = Object.keys(issuesByCategory) as IssueCategory[];\n\n // Generate category files\n for (const category of categories) {\n const issues = issuesByCategory[category] || [];\n if (issues.length === 0) continue;\n\n const chunks = splitIntoChunks(issues, category);\n\n for (let i = 0; i < chunks.length; i++) {\n const suffix = chunks.length > 1 ? `-${i + 1}` : '';\n const filename = `${prefix}-${category}${suffix}.md`;\n const filepath = join(outputDir, filename);\n\n const chunk = chunks[i];\n if (!chunk) continue;\n const content = generateCategoryFile(report.siteUrl, category, chunk, {\n part: chunks.length > 1 ? i + 1 : undefined,\n totalParts: chunks.length > 1 ? chunks.length : undefined,\n });\n\n writeFileSync(filepath, content, 'utf-8');\n categoryFiles.push(filename);\n }\n }\n\n // Generate index file\n const indexFilename = `${prefix}-index.md`;\n const indexFilepath = join(outputDir, indexFilename);\n const indexContent = generateIndexFile(report, categoryFiles);\n writeFileSync(indexFilepath, indexContent, 'utf-8');\n\n return {\n indexFile: indexFilename,\n categoryFiles,\n totalFiles: categoryFiles.length + 1,\n };\n}\n\n/**\n * Generate compact index file\n */\nfunction generateIndexFile(report: SeoReport, categoryFiles: string[]): string {\n const lines: string[] = [];\n\n lines.push('# SEO Report Index');\n lines.push('');\n lines.push(`Site: ${report.siteUrl}`);\n lines.push(`Score: ${report.summary.healthScore}/100`);\n lines.push(`Date: ${report.generatedAt.slice(0, 10)}`);\n lines.push('');\n\n // Severity counts\n lines.push('## Issues');\n lines.push('');\n lines.push('| Severity | Count |');\n lines.push('|----------|-------|');\n const severities: IssueSeverity[] = ['critical', 'error', 'warning', 'info'];\n for (const sev of severities) {\n const count = report.summary.issuesBySeverity[sev] || 0;\n if (count > 0) {\n lines.push(`| ${sev} | ${count} |`);\n }\n }\n lines.push('');\n\n // Top 10 recommendations (compact)\n lines.push('## Actions');\n lines.push('');\n const topRecs = report.recommendations.slice(0, 10);\n for (let i = 0; i < topRecs.length; i++) {\n const rec = topRecs[i];\n if (!rec) continue;\n lines.push(`${i + 1}. **${rec.title}** (${rec.affectedUrls.length})`);\n lines.push(` ${rec.actionItems[0]}`);\n }\n lines.push('');\n\n // File index\n lines.push('## Files');\n lines.push('');\n for (const file of categoryFiles) {\n lines.push(`- [${file}](./${file})`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Generate compact category file\n */\nfunction generateCategoryFile(\n siteUrl: string,\n category: IssueCategory,\n issues: SeoIssue[],\n opts: { part?: number; totalParts?: number }\n): string {\n const lines: string[] = [];\n const partStr = opts.part ? ` (Part ${opts.part}/${opts.totalParts})` : '';\n\n lines.push(`# ${formatCategory(category)}${partStr}`);\n lines.push('');\n lines.push(`Site: ${siteUrl}`);\n lines.push(`Issues: ${issues.length}`);\n lines.push('');\n\n // Group by title for compact display\n const byTitle = new Map<string, SeoIssue[]>();\n for (const issue of issues) {\n const group = byTitle.get(issue.title) || [];\n group.push(issue);\n byTitle.set(issue.title, group);\n }\n\n for (const [title, groupIssues] of byTitle) {\n const first = groupIssues[0];\n if (!first) continue;\n\n lines.push(`## ${title}`);\n lines.push('');\n lines.push(`Severity: ${first.severity}`);\n lines.push(`Count: ${groupIssues.length}`);\n lines.push('');\n lines.push(`> ${first.recommendation}`);\n lines.push('');\n\n // Compact URL list\n lines.push('URLs:');\n for (const issue of groupIssues.slice(0, 20)) {\n lines.push(`- ${issue.url}`);\n }\n if (groupIssues.length > 20) {\n lines.push(`- ... +${groupIssues.length - 20} more`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Split issues into chunks that fit within MAX_LINES\n */\nfunction splitIntoChunks(issues: SeoIssue[], category: IssueCategory): SeoIssue[][] {\n // Estimate lines per issue group (title + severity + recommendation + URLs)\n const byTitle = new Map<string, SeoIssue[]>();\n for (const issue of issues) {\n const group = byTitle.get(issue.title) || [];\n group.push(issue);\n byTitle.set(issue.title, group);\n }\n\n const chunks: SeoIssue[][] = [];\n let currentChunk: SeoIssue[] = [];\n let currentLines = 10; // Header overhead\n\n for (const [, groupIssues] of byTitle) {\n // Estimate: 6 lines header + min(20, count) URLs + 2 spacing\n const urlCount = Math.min(20, groupIssues.length);\n const groupLines = 8 + urlCount;\n\n if (currentLines + groupLines > MAX_LINES && currentChunk.length > 0) {\n chunks.push(currentChunk);\n currentChunk = [];\n currentLines = 10;\n }\n\n currentChunk.push(...groupIssues);\n currentLines += groupLines;\n }\n\n if (currentChunk.length > 0) {\n chunks.push(currentChunk);\n }\n\n return chunks.length > 0 ? chunks : [[]];\n}\n\nfunction groupIssuesByCategory(issues: SeoIssue[]): Record<IssueCategory, SeoIssue[]> {\n const result: Partial<Record<IssueCategory, SeoIssue[]>> = {};\n\n for (const issue of issues) {\n if (!result[issue.category]) {\n result[issue.category] = [];\n }\n result[issue.category]!.push(issue);\n }\n\n return result as Record<IssueCategory, SeoIssue[]>;\n}\n\nfunction formatCategory(category: string): string {\n return category\n .split('-')\n .map(s => s.charAt(0).toUpperCase() + s.slice(1))\n .join(' ');\n}\n","/**\n * @djangocfg/seo - CLAUDE.md Generator\n * Generates AI context file with package docs and current audit state\n */\n\nimport type { SeoReport } from '../types/index.js';\n\n/**\n * Generate CLAUDE.md content for AI context\n */\nexport function generateClaudeContext(report: SeoReport): string {\n const lines: string[] = [];\n\n // Package docs (static)\n lines.push('# @djangocfg/seo');\n lines.push('');\n lines.push('SEO audit toolkit. Generates AI-optimized split reports (max 1000 lines each).');\n lines.push('');\n lines.push('## Commands');\n lines.push('');\n lines.push('```bash');\n lines.push('# Audit (HTTP-based, crawls live site)');\n lines.push('pnpm seo:audit # Full audit (split reports)');\n lines.push('pnpm seo:audit --env dev # Audit local dev');\n lines.push('pnpm seo:audit --format all # All formats');\n lines.push('');\n lines.push('# Content (file-based, scans MDX/content/)');\n lines.push('pnpm exec djangocfg-seo content check # Check MDX links');\n lines.push('pnpm exec djangocfg-seo content fix # Show fixable links');\n lines.push('pnpm exec djangocfg-seo content fix --fix # Apply fixes');\n lines.push('pnpm exec djangocfg-seo content sitemap # Generate sitemap.ts');\n lines.push('```');\n lines.push('');\n lines.push('## Options');\n lines.push('');\n lines.push('- `--env, -e` - prod (default) or dev');\n lines.push('- `--site, -s` - Site URL (overrides env)');\n lines.push('- `--output, -o` - Output directory');\n lines.push('- `--format, -f` - split (default), json, markdown, ai-summary, all');\n lines.push('- `--max-pages` - Max pages (default: 100)');\n lines.push('- `--service-account` - Google service account JSON path');\n lines.push('- `--content-dir` - Content directory (default: content/)');\n lines.push('- `--base-path` - Base URL path for docs (default: /docs)');\n lines.push('');\n lines.push('## Reports');\n lines.push('');\n lines.push('- `seo-*-index.md` - Summary + links to categories');\n lines.push('- `seo-*-technical.md` - Broken links, sitemap issues');\n lines.push('- `seo-*-content.md` - H1, meta, title issues');\n lines.push('- `seo-*-performance.md` - Load time, TTFB issues');\n lines.push('- `seo-ai-summary-*.md` - Quick overview');\n lines.push('');\n\n // Issue types - important for AI to understand priorities\n lines.push('## Issue Severity');\n lines.push('');\n lines.push('- **critical** - Blocks indexing (fix immediately)');\n lines.push('- **error** - SEO problems (high priority)');\n lines.push('- **warning** - Recommendations (medium priority)');\n lines.push('- **info** - Best practices (low priority)');\n lines.push('');\n lines.push('## Issue Categories');\n lines.push('');\n lines.push('- **technical** - Broken links, sitemap, robots.txt');\n lines.push('- **content** - Missing H1, meta description, title');\n lines.push('- **indexing** - Not indexed, crawl errors from GSC');\n lines.push('- **performance** - Slow load time (>3s), high TTFB (>800ms)');\n lines.push('');\n\n // Routes info\n lines.push('## Routes Scanner');\n lines.push('');\n lines.push('Scans Next.js App Router `app/` directory. Handles:');\n lines.push('- Route groups `(group)` - ignored in URL');\n lines.push('- Dynamic `[slug]` - shown as `:slug`');\n lines.push('- Catch-all `[...slug]` - shown as `:...slug`');\n lines.push('- Parallel `@folder` - skipped');\n lines.push('- Private `_folder` - skipped');\n lines.push('');\n\n // SEO files setup\n lines.push('## SEO Files (Next.js App Router)');\n lines.push('');\n lines.push('**Required files in `app/`:**');\n lines.push('');\n lines.push('### sitemap.xml/route.ts');\n lines.push('```typescript');\n lines.push(\"import { createSitemapHandler } from '@djangocfg/nextjs/sitemap';\");\n lines.push('');\n lines.push('export const dynamic = \"force-static\";');\n lines.push('export const { GET } = createSitemapHandler({');\n lines.push(' siteUrl,');\n lines.push(' staticPages: [');\n lines.push(' { loc: \"/\", priority: 1.0, changefreq: \"daily\" },');\n lines.push(' { loc: \"/about\", priority: 0.8 },');\n lines.push(' ],');\n lines.push(' dynamicPages: async () => fetchPagesFromAPI(),');\n lines.push('});');\n lines.push('```');\n lines.push('');\n lines.push('### robots.ts');\n lines.push('```typescript');\n lines.push(\"import type { MetadataRoute } from 'next';\");\n lines.push('');\n lines.push('export default function robots(): MetadataRoute.Robots {');\n lines.push(' return {');\n lines.push(' rules: { userAgent: \"*\", allow: \"/\" },');\n lines.push(' sitemap: `${siteUrl}/sitemap.xml`,');\n lines.push(' };');\n lines.push('}');\n lines.push('```');\n lines.push('');\n lines.push('### Cloudflare Override');\n lines.push('');\n lines.push('If robots.txt shows \"Content-Signal\" or \"ai-train\" â Cloudflare is overriding your file.');\n lines.push('**Fix:** Dashboard â Security â Settings â \"Manage your robots.txt\" â Set to \"Off\"');\n lines.push('');\n lines.push('### Declarative Routes with SEO');\n lines.push('');\n lines.push('Create `app/_routes/` with SEO metadata for sitemap:');\n lines.push('```typescript');\n lines.push(\"import { defineRoute } from '@djangocfg/nextjs/navigation';\");\n lines.push('');\n lines.push(\"export const home = defineRoute('/', {\");\n lines.push(\" label: 'Home',\");\n lines.push(' protected: false,');\n lines.push(' priority: 1.0, // Sitemap priority 0.0-1.0');\n lines.push(\" changefreq: 'daily', // always|hourly|daily|weekly|monthly|yearly|never\");\n lines.push(' noindex: false, // Exclude from sitemap');\n lines.push('});');\n lines.push('');\n lines.push('export const staticRoutes = [home, about, contact];');\n lines.push('```');\n lines.push('');\n lines.push('Then in `sitemap.xml/route.ts`:');\n lines.push('```typescript');\n lines.push(\"import { routes } from '@/app/_routes';\");\n lines.push('routes.getAllStaticRoutes().filter(r => !r.metadata.noindex)');\n lines.push('```');\n lines.push('');\n\n // Link guidelines\n lines.push('## Link Guidelines');\n lines.push('');\n lines.push('### Nextra/MDX Projects (content/)');\n lines.push('');\n lines.push('For non-index files (e.g., `overview.mdx`):');\n lines.push('- **Sibling file**: `../sibling` (one level up)');\n lines.push('- **Other section**: `/docs/full/path` (absolute)');\n lines.push('- **AVOID**: `./sibling` (browser adds filename to path!)');\n lines.push('- **AVOID**: `../../deep/path` (hard to maintain)');\n lines.push('');\n lines.push('For index files (e.g., `index.mdx`):');\n lines.push('- **Child file**: `./child` works correctly');\n lines.push('- **Sibling folder**: `../sibling/` or absolute');\n lines.push('');\n lines.push('### Next.js App Router Projects');\n lines.push('');\n lines.push('Use declarative routes from `_routes/`:');\n lines.push('```typescript');\n lines.push('import { routes } from \"@/app/_routes\";');\n lines.push('<Link href={routes.dashboard.machines}>Machines</Link>');\n lines.push('```');\n lines.push('');\n lines.push('Benefits: type-safe, refactor-friendly, centralized.');\n lines.push('');\n\n // Current audit state (dynamic)\n lines.push('---');\n lines.push('');\n lines.push('## Current Audit');\n lines.push('');\n lines.push(`Site: ${report.siteUrl}`);\n lines.push(`Score: ${report.summary.healthScore}/100`);\n lines.push(`Date: ${report.generatedAt.slice(0, 10)}`);\n lines.push('');\n\n // Issue summary\n lines.push('### Issues');\n lines.push('');\n const { critical = 0, error = 0, warning = 0, info = 0 } = report.summary.issuesBySeverity;\n if (critical > 0) lines.push(`- Critical: ${critical}`);\n if (error > 0) lines.push(`- Error: ${error}`);\n if (warning > 0) lines.push(`- Warning: ${warning}`);\n if (info > 0) lines.push(`- Info: ${info}`);\n lines.push('');\n\n // Top 5 actions\n lines.push('### Top Actions');\n lines.push('');\n const topRecs = report.recommendations.slice(0, 5);\n for (let i = 0; i < topRecs.length; i++) {\n const rec = topRecs[i];\n if (!rec) continue;\n lines.push(`${i + 1}. **${rec.title}** (${rec.affectedUrls.length} URLs)`);\n }\n lines.push('');\n\n // Report files in this directory\n lines.push('### Report Files');\n lines.push('');\n lines.push('See split reports in this directory:');\n lines.push('- `seo-*-index.md` - Start here');\n lines.push('- `seo-*-technical.md` - Technical issues');\n lines.push('- `seo-*-content.md` - Content issues');\n lines.push('- `seo-*-performance.md` - Performance issues');\n lines.push('');\n\n return lines.join('\\n');\n}\n","/**\n * @djangocfg/seo - Report Generator\n * Main report generation orchestrator\n */\n\nimport { writeFileSync, mkdirSync, existsSync, rmSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\nimport consola from 'consola';\nimport { generateJsonReport, exportJsonReport } from './json-report.js';\nimport { generateMarkdownReport, generateAiSummary } from './markdown-report.js';\nimport { generateSplitReports } from './split-report.js';\nimport { generateClaudeContext } from './claude-context.js';\nimport type {\n SeoReport,\n SeoIssue,\n UrlInspectionResult,\n CrawlResult,\n IssueCategory,\n IssueSeverity,\n} from '../types/index.js';\n\nexport interface ReportGeneratorOptions {\n outputDir: string;\n formats: ('json' | 'markdown' | 'ai-summary' | 'split')[];\n includeRawData?: boolean;\n timestamp?: boolean;\n /** Clear output directory before generating reports */\n clearOutputDir?: boolean;\n /** Maximum URLs to show per issue group (default: 10) */\n maxUrlsPerIssue?: number;\n}\n\nexport interface GeneratedReports {\n report: SeoReport;\n files: {\n json?: string;\n markdown?: string;\n aiSummary?: string;\n split?: {\n index: string;\n categories: string[];\n };\n };\n}\n\n/**\n * Generate and save SEO reports\n */\nexport async function generateAndSaveReports(\n siteUrl: string,\n data: {\n issues: SeoIssue[];\n urlInspections?: UrlInspectionResult[];\n crawlResults?: CrawlResult[];\n },\n options: ReportGeneratorOptions\n): Promise<GeneratedReports> {\n const {\n outputDir,\n formats,\n includeRawData = false,\n timestamp = true,\n clearOutputDir = true,\n maxUrlsPerIssue = 10,\n } = options;\n\n // Clear output directory if requested\n if (clearOutputDir && existsSync(outputDir)) {\n try {\n const files = readdirSync(outputDir);\n for (const file of files) {\n if (file.startsWith('seo-')) {\n rmSync(join(outputDir, file), { force: true });\n }\n }\n } catch {\n // Ignore errors\n }\n }\n\n // Ensure output directory exists\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n // Generate the report\n const report = generateJsonReport(siteUrl, data, { includeRawData, maxUrlsPerIssue });\n\n const result: GeneratedReports = {\n report,\n files: {},\n };\n\n // Generate timestamp for filenames\n const ts = timestamp\n ? `-${new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)}`\n : '';\n const siteName = new URL(siteUrl).hostname.replace(/\\./g, '-');\n\n // Generate JSON report\n if (formats.includes('json')) {\n const filename = `seo-report-${siteName}${ts}.json`;\n const filepath = join(outputDir, filename);\n const content = exportJsonReport(report, true);\n writeFileSync(filepath, content, 'utf-8');\n result.files.json = filepath;\n consola.success(`JSON report saved: ${filepath}`);\n }\n\n // Generate Markdown report\n if (formats.includes('markdown')) {\n const filename = `seo-report-${siteName}${ts}.md`;\n const filepath = join(outputDir, filename);\n const content = generateMarkdownReport(report, {\n includeRawIssues: true,\n includeUrls: true,\n });\n writeFileSync(filepath, content, 'utf-8');\n result.files.markdown = filepath;\n consola.success(`Markdown report saved: ${filepath}`);\n }\n\n // Generate AI summary\n if (formats.includes('ai-summary')) {\n const filename = `seo-ai-summary-${siteName}${ts}.md`;\n const filepath = join(outputDir, filename);\n const content = generateAiSummary(report);\n writeFileSync(filepath, content, 'utf-8');\n result.files.aiSummary = filepath;\n consola.success(`AI summary saved: ${filepath}`);\n }\n\n // Generate split reports (AI-optimized, max 1000 lines each)\n if (formats.includes('split')) {\n const splitResult = generateSplitReports(report, {\n outputDir,\n clearOutputDir: false, // Already cleared above\n });\n result.files.split = {\n index: join(outputDir, splitResult.indexFile),\n categories: splitResult.categoryFiles.map(f => join(outputDir, f)),\n };\n consola.success(`Split reports saved: ${splitResult.totalFiles} files (index + ${splitResult.categoryFiles.length} categories)`);\n }\n\n // Always generate CLAUDE.md for AI context\n const claudeContent = generateClaudeContext(report);\n const claudeFilepath = join(outputDir, 'CLAUDE.md');\n writeFileSync(claudeFilepath, claudeContent, 'utf-8');\n consola.success(`AI context saved: ${claudeFilepath}`);\n\n return result;\n}\n\n/**\n * Print report summary to console\n */\nexport function printReportSummary(report: SeoReport): void {\n consola.box(\n `SEO Report: ${report.siteUrl}\\n` +\n `Health Score: ${report.summary.healthScore}/100\\n` +\n `Total URLs: ${report.summary.totalUrls}\\n` +\n `Indexed: ${report.summary.indexedUrls} | Not Indexed: ${report.summary.notIndexedUrls}\\n` +\n `Issues: ${report.issues.length}`\n );\n\n if (report.summary.issuesBySeverity.critical) {\n consola.error(`Critical issues: ${report.summary.issuesBySeverity.critical}`);\n }\n if (report.summary.issuesBySeverity.error) {\n consola.warn(`Errors: ${report.summary.issuesBySeverity.error}`);\n }\n if (report.summary.issuesBySeverity.warning) {\n consola.info(`Warnings: ${report.summary.issuesBySeverity.warning}`);\n }\n\n consola.log('');\n consola.info('Top recommendations:');\n for (const rec of report.recommendations.slice(0, 3)) {\n consola.log(` ${rec.priority}. ${rec.title} (${rec.affectedUrls.length} URLs)`);\n }\n}\n\n/**\n * Merge multiple reports into one\n */\nexport function mergeReports(reports: SeoReport[]): SeoReport {\n if (reports.length === 0) {\n throw new Error('Cannot merge empty reports array');\n }\n\n const merged: SeoReport = {\n id: `merged-${Date.now().toString(36)}`,\n siteUrl: reports.map((r) => r.siteUrl).join(', '),\n generatedAt: new Date().toISOString(),\n summary: {\n totalUrls: reports.reduce((sum, r) => sum + r.summary.totalUrls, 0),\n indexedUrls: reports.reduce((sum, r) => sum + r.summary.indexedUrls, 0),\n notIndexedUrls: reports.reduce((sum, r) => sum + r.summary.notIndexedUrls, 0),\n issuesByCategory: {} as any,\n issuesBySeverity: {} as any,\n healthScore: Math.round(\n reports.reduce((sum, r) => sum + r.summary.healthScore, 0) / reports.length\n ),\n },\n issues: reports.flatMap((r) => r.issues),\n urlInspections: reports.flatMap((r) => r.urlInspections),\n crawlResults: reports.flatMap((r) => r.crawlResults),\n recommendations: [],\n };\n\n // Merge issue counts\n for (const report of reports) {\n for (const [category, count] of Object.entries(report.summary.issuesByCategory)) {\n const cat = category as IssueCategory;\n merged.summary.issuesByCategory[cat] =\n (merged.summary.issuesByCategory[cat] || 0) + count;\n }\n for (const [severity, count] of Object.entries(report.summary.issuesBySeverity)) {\n const sev = severity as IssueSeverity;\n merged.summary.issuesBySeverity[sev] =\n (merged.summary.issuesBySeverity[sev] || 0) + count;\n }\n }\n\n // Merge and deduplicate recommendations\n const recMap = new Map<string, typeof merged.recommendations[0]>();\n for (const report of reports) {\n for (const rec of report.recommendations) {\n const key = `${rec.category}:${rec.title}`;\n if (recMap.has(key)) {\n const existing = recMap.get(key)!;\n existing.affectedUrls.push(...rec.affectedUrls);\n } else {\n recMap.set(key, { ...rec, affectedUrls: [...rec.affectedUrls] });\n }\n }\n }\n merged.recommendations = Array.from(recMap.values()).sort(\n (a, b) => a.priority - b.priority\n );\n\n return merged;\n}\n"]}
|
package/dist/routes/index.mjs
CHANGED
|
@@ -181,28 +181,29 @@ function getStaticUrls(scanResult, baseUrl) {
|
|
|
181
181
|
function compareWithSitemap(scanResult, sitemapUrls, baseUrl) {
|
|
182
182
|
const appRoutes = scanResult.routes.filter((r) => r.type === "page");
|
|
183
183
|
const sitemapPaths = new Set(
|
|
184
|
-
sitemapUrls.map((url) => {
|
|
184
|
+
sitemapUrls.filter((url) => url).map((url) => {
|
|
185
185
|
try {
|
|
186
186
|
return new URL(url).pathname;
|
|
187
187
|
} catch {
|
|
188
188
|
return url;
|
|
189
189
|
}
|
|
190
|
-
})
|
|
190
|
+
}).filter(Boolean)
|
|
191
191
|
);
|
|
192
192
|
const missingFromSitemap = [];
|
|
193
193
|
const matching = [];
|
|
194
194
|
for (const route of scanResult.staticRoutes) {
|
|
195
|
-
const path = route.path
|
|
195
|
+
const path = route.path || "/";
|
|
196
196
|
if (sitemapPaths.has(path) || sitemapPaths.has(path + "/") || sitemapPaths.has(path.replace(/\/$/, ""))) {
|
|
197
197
|
matching.push(route);
|
|
198
198
|
} else {
|
|
199
199
|
missingFromSitemap.push(route);
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
-
const staticPaths = new Set(scanResult.staticRoutes.map((r) => r.path));
|
|
203
|
-
const dynamicPatterns = scanResult.dynamicRoutes.map((r) => routeToRegex(r.path));
|
|
202
|
+
const staticPaths = new Set(scanResult.staticRoutes.map((r) => r.path).filter(Boolean));
|
|
203
|
+
const dynamicPatterns = scanResult.dynamicRoutes.filter((r) => r.path).map((r) => routeToRegex(r.path));
|
|
204
204
|
const extraInSitemap = [];
|
|
205
205
|
for (const path of sitemapPaths) {
|
|
206
|
+
if (!path) continue;
|
|
206
207
|
if (staticPaths.has(path) || staticPaths.has(path + "/") || staticPaths.has(path.replace(/\/$/, ""))) {
|
|
207
208
|
continue;
|
|
208
209
|
}
|
|
@@ -219,6 +220,7 @@ function compareWithSitemap(scanResult, sitemapUrls, baseUrl) {
|
|
|
219
220
|
};
|
|
220
221
|
}
|
|
221
222
|
function routeToRegex(routePath) {
|
|
223
|
+
if (!routePath) return /^$/;
|
|
222
224
|
let pattern = routePath.replace(/[.+?^${}()|\\]/g, "\\$&").replace(/\[\[\.\.\.([^\]]+)\]\]/g, "(?:/.*)?").replace(/\[\.\.\.([^\]]+)\]/g, "/.+").replace(/\[([^\]]+)\]/g, "/[^/]+");
|
|
223
225
|
pattern = `^${pattern}/?$`;
|
|
224
226
|
return new RegExp(pattern);
|