geo-checker 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/cli.cjs +1380 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1357 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +1254 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +98 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +1214 -0
- package/dist/index.js.map +1 -0
- package/package.json +85 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/context.ts","../src/fetcher/static.ts","../src/fetcher/rendered.ts","../src/fetcher/robots.ts","../src/fetcher/llms-txt.ts","../src/fetcher/sitemap.ts","../src/types.ts","../src/engine.ts","../src/rules/crawler/https.ts","../src/rules/crawler/robots-reachable.ts","../src/rules/crawler/robots-ai-allow.ts","../src/rules/crawler/llms-txt-present.ts","../src/rules/crawler/llms-txt-wellformed.ts","../src/rules/crawler/sitemap-present.ts","../src/rules/crawler/index.ts","../src/rules/structured-data/jsonld-present.ts","../src/rules/util.ts","../src/rules/structured-data/jsonld-valid-json.ts","../src/rules/structured-data/schema-type-recognized.ts","../src/rules/structured-data/required-fields.ts","../src/rules/structured-data/microdata-fallback.ts","../src/rules/structured-data/no-duplicate-types.ts","../src/rules/structured-data/index.ts","../src/rules/citation/title.ts","../src/rules/citation/meta-description.ts","../src/rules/citation/canonical.ts","../src/rules/citation/og-tags.ts","../src/rules/citation/twitter-card.ts","../src/rules/citation/lang-attr.ts","../src/rules/citation/author-visible.ts","../src/rules/citation/dates.ts","../src/rules/citation/index.ts","../src/rules/content/single-h1.ts","../src/rules/content/heading-hierarchy.ts","../src/rules/content/image-alt.ts","../src/rules/content/tldr-or-faq.ts","../src/rules/content/word-count.ts","../src/rules/content/index.ts","../src/rules/index.ts","../src/index.ts","../src/reporters/json.ts","../src/reporters/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { cac } from 'cac';\nimport kleur from 'kleur';\nimport { audit } from './index.js';\nimport { toJson } from './reporters/json.js';\nimport { toCli } from './reporters/cli.js';\nimport type { Category, Status, AuditReport } from './types.js';\n\nconst pkgVersion = '0.1.0';\n\nconst VALID_CATEGORIES: Category[] = ['crawler', 'structured-data', 'citation', 'content'];\n\ntype FailOn = 'fail' | 'warn';\n\ninterface CliFlags {\n json?: boolean;\n render?: boolean;\n category?: string;\n only?: string;\n failOn?: FailOn;\n timeout?: string | number;\n}\n\nfunction parseCategories(raw?: string): Category[] | undefined {\n if (!raw) return undefined;\n const items = raw\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n const valid = items.filter((c): c is Category => (VALID_CATEGORIES as string[]).includes(c));\n const invalid = items.filter((c) => !(VALID_CATEGORIES as string[]).includes(c));\n if (invalid.length > 0) {\n throw new Error(`Unknown category: ${invalid.join(', ')}. Valid: ${VALID_CATEGORIES.join(', ')}.`);\n }\n return valid;\n}\n\nfunction parseOnly(raw?: string): string[] | undefined {\n if (!raw) return undefined;\n return raw.split(',').map((s) => s.trim()).filter(Boolean);\n}\n\nfunction worstStatus(report: AuditReport): Status {\n let worst: Status = 'pass';\n const order: Record<Status, number> = { pass: 0, skip: 0, warn: 1, fail: 2 };\n for (const cat of Object.values(report.categories)) {\n for (const r of cat.results) {\n if (order[r.status] > order[worst]) worst = r.status;\n }\n }\n return worst;\n}\n\nconst cli = cac('geo-checker');\n\ncli\n .command('<url>', 'Audit a URL for GEO (Generative Engine Optimization) readiness')\n .option('--json', 'Output a JSON report to stdout')\n .option('--render', 'Use a headless browser (requires optional playwright dependency)')\n .option('--category <names>', 'Run only the given categories (comma-separated)')\n .option('--only <ids>', 'Run only the given rule IDs (comma-separated)')\n .option('--fail-on <level>', 'Exit non-zero when a result is at or above this level (warn|fail)', {\n default: 'fail',\n })\n .option('--timeout <ms>', 'Per-request timeout in milliseconds', { default: 20000 })\n .action(async (url: string, flags: CliFlags) => {\n const categories = parseCategories(flags.category);\n const only = parseOnly(flags.only);\n const timeoutMs = typeof flags.timeout === 'string' ? parseInt(flags.timeout, 10) : flags.timeout;\n\n const report = await audit(url, {\n ...(flags.render ? { render: true } : {}),\n ...(categories ? { categories } : {}),\n ...(only ? { only } : {}),\n ...(typeof timeoutMs === 'number' && !Number.isNaN(timeoutMs) ? { timeoutMs } : {}),\n });\n\n if (flags.json) {\n process.stdout.write(toJson(report) + '\\n');\n } else {\n process.stdout.write(toCli(report) + '\\n');\n }\n\n const worst = worstStatus(report);\n const failOn: FailOn = flags.failOn === 'warn' ? 'warn' : 'fail';\n if (failOn === 'fail' && worst === 'fail') process.exit(1);\n if (failOn === 'warn' && (worst === 'warn' || worst === 'fail')) process.exit(1);\n });\n\ncli.help();\ncli.version(pkgVersion);\n\nasync function main() {\n cli.parse(process.argv, { run: false });\n await cli.runMatchedCommand();\n}\n\nmain().catch((err) => {\n console.error(kleur.red('geo-checker crashed:'), err instanceof Error ? err.message : err);\n process.exit(2);\n});\n","import { load as cheerioLoad, type CheerioAPI } from 'cheerio';\nimport type { AuditContext } from './types.js';\nimport { fetchStatic, fetchText } from './fetcher/static.js';\nimport { fetchRendered } from './fetcher/rendered.js';\nimport { parseRobots } from './fetcher/robots.js';\nimport { parseLlmsTxt } from './fetcher/llms-txt.js';\nimport { parseSitemap } from './fetcher/sitemap.js';\n\nexport interface BuildContextOptions {\n userAgent?: string;\n timeoutMs?: number;\n render?: boolean;\n}\n\nfunction extractJsonLd($: CheerioAPI): unknown[] {\n const blocks: unknown[] = [];\n $('script[type=\"application/ld+json\"]').each((_i, el) => {\n const txt = $(el).contents().text().trim();\n if (!txt) return;\n try {\n const parsed = JSON.parse(txt);\n if (Array.isArray(parsed)) blocks.push(...parsed);\n else blocks.push(parsed);\n } catch {\n blocks.push({ __parseError: true, raw: txt.slice(0, 200) });\n }\n });\n return blocks;\n}\n\nfunction detectSpa($: CheerioAPI): boolean {\n const bodyText = $('body').clone().find('script, style, noscript').remove().end().text().replace(/\\s+/g, ' ').trim();\n if (bodyText.length >= 500) return false;\n const roots = $('#__next, #root, #app, [data-reactroot], [ng-app], [data-server-rendered]');\n return roots.length > 0;\n}\n\nexport async function buildContext(url: string, opts: BuildContextOptions = {}): Promise<AuditContext> {\n const warnings: string[] = [];\n let finalUrl: string;\n let html: string;\n let headers: Record<string, string>;\n let status: number;\n let renderMode: 'static' | 'rendered';\n\n if (opts.render) {\n const page = await fetchRendered(url, opts);\n finalUrl = page.finalUrl;\n html = page.html;\n headers = page.headers;\n status = page.status;\n renderMode = 'rendered';\n } else {\n const page = await fetchStatic(url, opts);\n finalUrl = page.finalUrl;\n html = page.body;\n headers = page.headers;\n status = page.status;\n renderMode = 'static';\n }\n\n const $ = cheerioLoad(html);\n const origin = new URL(finalUrl).origin;\n\n if (renderMode === 'static' && detectSpa($)) {\n warnings.push(\n 'Site appears to be JS-rendered (sparse body + SPA root element). Re-run with --render for accurate results.',\n );\n }\n\n const [robotsRaw, llmsRaw] = await Promise.all([\n fetchText(`${origin}/robots.txt`, opts),\n fetchText(`${origin}/llms.txt`, opts),\n ]);\n\n let sitemapUrl: string | null = null;\n const robots = robotsRaw ? parseRobots(robotsRaw) : null;\n if (robots && robots.sitemaps.length > 0) sitemapUrl = robots.sitemaps[0] ?? null;\n if (!sitemapUrl) sitemapUrl = `${origin}/sitemap.xml`;\n\n const sitemapRaw = await fetchText(sitemapUrl, opts);\n const sitemap = sitemapRaw ? parseSitemap(sitemapRaw) : null;\n\n return {\n url,\n finalUrl,\n html,\n $,\n headers,\n status,\n robots,\n llmsTxt: llmsRaw ? parseLlmsTxt(llmsRaw) : null,\n sitemap,\n jsonLd: extractJsonLd($),\n renderMode,\n fetchedAt: new Date().toISOString(),\n warnings,\n };\n}\n\nexport const buildStaticContext = buildContext;\n","import { request } from 'undici';\n\nexport const DEFAULT_UA = 'geo-checker/0.1.0 (+https://github.com/BaRam-OSS/geo-checker)';\n\nexport interface StaticFetchOptions {\n userAgent?: string;\n timeoutMs?: number;\n maxRedirects?: number;\n accept?: string;\n}\n\nexport interface StaticFetchResult {\n finalUrl: string;\n status: number;\n headers: Record<string, string>;\n body: string;\n redirectCount: number;\n}\n\nfunction normalizeHeaders(input: Record<string, string | string[] | undefined>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(input)) {\n if (v == null) continue;\n out[k.toLowerCase()] = Array.isArray(v) ? v.join(', ') : v;\n }\n return out;\n}\n\nexport async function fetchStatic(url: string, opts: StaticFetchOptions = {}): Promise<StaticFetchResult> {\n const maxRedirects = opts.maxRedirects ?? 5;\n const timeout = opts.timeoutMs ?? 20_000;\n const userAgent = opts.userAgent ?? DEFAULT_UA;\n const accept = opts.accept ?? 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';\n\n let current = url;\n let redirects = 0;\n\n for (;;) {\n const res = await request(current, {\n method: 'GET',\n headers: {\n 'user-agent': userAgent,\n accept,\n 'accept-language': 'en,*',\n },\n bodyTimeout: timeout,\n headersTimeout: timeout,\n });\n\n const status = res.statusCode;\n const headers = normalizeHeaders(res.headers as Record<string, string | string[] | undefined>);\n\n if (status >= 300 && status < 400 && headers.location && redirects < maxRedirects) {\n redirects += 1;\n current = new URL(headers.location, current).toString();\n await res.body.dump();\n continue;\n }\n\n const body = await res.body.text();\n return { finalUrl: current, status, headers, body, redirectCount: redirects };\n }\n}\n\nexport async function fetchText(url: string, opts: StaticFetchOptions = {}): Promise<string | null> {\n try {\n const res = await fetchStatic(url, opts);\n if (res.status >= 200 && res.status < 300) return res.body;\n return null;\n } catch {\n return null;\n }\n}\n","import type * as PlaywrightNs from 'playwright';\nimport { DEFAULT_UA } from './static.js';\n\nexport interface RenderedResult {\n finalUrl: string;\n html: string;\n status: number;\n headers: Record<string, string>;\n}\n\nexport interface RenderedOptions {\n userAgent?: string;\n timeoutMs?: number;\n}\n\nexport async function fetchRendered(url: string, opts: RenderedOptions = {}): Promise<RenderedResult> {\n let playwright: typeof PlaywrightNs;\n try {\n playwright = (await import('playwright')) as typeof PlaywrightNs;\n } catch {\n throw new Error(\n 'Playwright is required for --render. Install with: npm i -D playwright && npx playwright install chromium',\n );\n }\n\n const userAgent = opts.userAgent ?? DEFAULT_UA;\n const timeout = opts.timeoutMs ?? 30_000;\n\n const browser = await playwright.chromium.launch({ headless: true });\n try {\n const ctx = await browser.newContext({ userAgent });\n const page = await ctx.newPage();\n const response = await page.goto(url, { waitUntil: 'networkidle', timeout });\n const html = await page.content();\n const finalUrl = page.url();\n const status = response?.status() ?? 200;\n const headers = response ? await response.allHeaders() : {};\n return { finalUrl, html, status, headers };\n } finally {\n await browser.close();\n }\n}\n","import type { RobotsTxt, RobotsRuleGroup } from '../types.js';\n\nexport function parseRobots(raw: string): RobotsTxt {\n const groups: RobotsRuleGroup[] = [];\n const sitemaps: string[] = [];\n let current: RobotsRuleGroup | null = null;\n\n const lines = raw.split(/\\r?\\n/);\n for (const rawLine of lines) {\n const line = rawLine.replace(/#.*$/, '').trim();\n if (!line) continue;\n const idx = line.indexOf(':');\n if (idx === -1) continue;\n const field = line.slice(0, idx).trim().toLowerCase();\n const value = line.slice(idx + 1).trim();\n\n if (field === 'user-agent') {\n if (!current || current.allow.length > 0 || current.disallow.length > 0) {\n current = { userAgent: value, allow: [], disallow: [] };\n groups.push(current);\n } else {\n current.userAgent = value;\n }\n } else if (field === 'allow' && current) {\n current.allow.push(value);\n } else if (field === 'disallow' && current) {\n current.disallow.push(value);\n } else if (field === 'sitemap') {\n sitemaps.push(value);\n }\n }\n\n return { raw, groups, sitemaps };\n}\n\nexport function matchGroup(robots: RobotsTxt, userAgent: string): RobotsRuleGroup | null {\n const lower = userAgent.toLowerCase();\n const exact = robots.groups.find((g) => g.userAgent.toLowerCase() === lower);\n if (exact) return exact;\n const wildcard = robots.groups.find((g) => g.userAgent === '*');\n return wildcard ?? null;\n}\n\nexport function isPathAllowed(group: RobotsRuleGroup | null, path: string): boolean {\n if (!group) return true;\n const matches = (pattern: string): number => {\n if (pattern === '') return -1;\n if (path.startsWith(pattern)) return pattern.length;\n return -1;\n };\n let bestAllow = -1;\n let bestDisallow = -1;\n for (const p of group.allow) bestAllow = Math.max(bestAllow, matches(p));\n for (const p of group.disallow) bestDisallow = Math.max(bestDisallow, matches(p));\n if (bestDisallow === -1) return true;\n return bestAllow >= bestDisallow;\n}\n","import type { LlmsTxt, LlmsTxtLink, LlmsTxtSection } from '../types.js';\n\nconst LINK_RE = /^\\s*-\\s*\\[([^\\]]+)\\]\\(([^)]+)\\)\\s*(?::\\s*(.+))?\\s*$/;\n\nexport function parseLlmsTxt(raw: string): LlmsTxt {\n const lines = raw.split(/\\r?\\n/);\n\n let title: string | null = null;\n let summary: string | null = null;\n const sections: LlmsTxtSection[] = [];\n let currentSection: LlmsTxtSection | null = null;\n const summaryParts: string[] = [];\n let inSummaryPhase = false;\n\n for (const line of lines) {\n if (/^#\\s+/.test(line) && title === null) {\n title = line.replace(/^#\\s+/, '').trim();\n inSummaryPhase = true;\n continue;\n }\n if (/^##\\s+/.test(line)) {\n if (inSummaryPhase && summaryParts.length > 0) {\n summary = summaryParts.join(' ').trim();\n }\n inSummaryPhase = false;\n currentSection = { title: line.replace(/^##\\s+/, '').trim(), links: [] };\n sections.push(currentSection);\n continue;\n }\n\n if (inSummaryPhase) {\n const trimmed = line.trim();\n if (trimmed.startsWith('>')) {\n summaryParts.push(trimmed.replace(/^>\\s*/, ''));\n } else if (trimmed.length > 0) {\n summaryParts.push(trimmed);\n }\n continue;\n }\n\n if (currentSection) {\n const m = LINK_RE.exec(line);\n if (m) {\n const link: LlmsTxtLink = { title: m[1]!.trim(), url: m[2]!.trim() };\n if (m[3]) link.description = m[3].trim();\n currentSection.links.push(link);\n }\n }\n }\n\n if (inSummaryPhase && summary === null && summaryParts.length > 0) {\n summary = summaryParts.join(' ').trim();\n }\n\n return { raw, title, summary, sections };\n}\n\nexport function isLlmsTxtWellFormed(parsed: LlmsTxt): { ok: boolean; reason?: string } {\n if (!parsed.title) return { ok: false, reason: 'Missing H1 project title' };\n if (parsed.sections.length === 0) return { ok: false, reason: 'No H2 sections found' };\n const totalLinks = parsed.sections.reduce((n, s) => n + s.links.length, 0);\n if (totalLinks === 0) return { ok: false, reason: 'No link items found under any section' };\n return { ok: true };\n}\n","import type { SitemapSummary } from '../types.js';\n\nconst LOC_RE = /<loc>\\s*([^<\\s]+)\\s*<\\/loc>/gi;\nconst LASTMOD_RE = /<lastmod>\\s*([^<\\s]+)\\s*<\\/lastmod>/i;\n\nexport function parseSitemap(xml: string): SitemapSummary {\n const urls: string[] = [];\n let match: RegExpExecArray | null;\n const re = new RegExp(LOC_RE.source, LOC_RE.flags);\n while ((match = re.exec(xml)) !== null) {\n const url = match[1];\n if (url) urls.push(url);\n }\n const lastmodMatch = LASTMOD_RE.exec(xml);\n const summary: SitemapSummary = { urls };\n if (lastmodMatch?.[1]) summary.lastmod = lastmodMatch[1];\n return summary;\n}\n","import type { CheerioAPI } from 'cheerio';\n\nexport type Status = 'pass' | 'warn' | 'fail' | 'skip';\n\nexport type Category = 'crawler' | 'structured-data' | 'citation' | 'content';\n\nexport interface RobotsRuleGroup {\n userAgent: string;\n allow: string[];\n disallow: string[];\n}\n\nexport interface RobotsTxt {\n raw: string;\n groups: RobotsRuleGroup[];\n sitemaps: string[];\n}\n\nexport interface LlmsTxtLink {\n title: string;\n url: string;\n description?: string;\n}\n\nexport interface LlmsTxtSection {\n title: string;\n links: LlmsTxtLink[];\n}\n\nexport interface LlmsTxt {\n raw: string;\n title: string | null;\n summary: string | null;\n sections: LlmsTxtSection[];\n}\n\nexport interface SitemapSummary {\n urls: string[];\n lastmod?: string;\n}\n\nexport interface AuditContext {\n url: string;\n finalUrl: string;\n html: string;\n $: CheerioAPI;\n headers: Record<string, string>;\n status: number;\n robots: RobotsTxt | null;\n llmsTxt: LlmsTxt | null;\n sitemap: SitemapSummary | null;\n jsonLd: unknown[];\n renderMode: 'static' | 'rendered';\n fetchedAt: string;\n warnings: string[];\n}\n\nexport interface RuleResult {\n status: Status;\n score: number;\n rationale: string;\n evidence?: unknown;\n fixUrl?: string;\n}\n\nexport interface Rule {\n id: string;\n category: Category;\n weight: number;\n title: string;\n description: string;\n run(ctx: AuditContext): Promise<RuleResult> | RuleResult;\n}\n\nexport interface CategoryReport {\n score: number;\n weight: number;\n results: Array<RuleResult & { id: string; title: string; weight: number }>;\n}\n\nexport interface AuditReport {\n url: string;\n finalUrl: string;\n fetchedAt: string;\n renderMode: 'static' | 'rendered';\n overall: number;\n categories: Record<Category, CategoryReport>;\n warnings: string[];\n version: string;\n}\n\nexport interface AuditOptions {\n render?: boolean;\n timeoutMs?: number;\n userAgent?: string;\n extraRules?: Rule[];\n only?: string[];\n categories?: Category[];\n}\n\nexport function defineRule(rule: Rule): Rule {\n return rule;\n}\n\nexport const CATEGORY_WEIGHTS: Record<Category, number> = {\n crawler: 25,\n 'structured-data': 30,\n citation: 25,\n content: 20,\n};\n","import type { AuditContext, AuditReport, Category, CategoryReport, Rule } from './types.js';\nimport { CATEGORY_WEIGHTS } from './types.js';\n\nconst VERSION = '0.1.0';\n\nexport interface RunRulesOptions {\n only?: string[];\n categories?: Category[];\n}\n\nexport async function runRules(\n ctx: AuditContext,\n rules: Rule[],\n opts: RunRulesOptions = {},\n): Promise<AuditReport> {\n const onlySet = opts.only ? new Set(opts.only) : null;\n const catSet = opts.categories ? new Set<Category>(opts.categories) : null;\n\n const buckets: Record<Category, CategoryReport> = {\n crawler: { score: 0, weight: CATEGORY_WEIGHTS.crawler, results: [] },\n 'structured-data': { score: 0, weight: CATEGORY_WEIGHTS['structured-data'], results: [] },\n citation: { score: 0, weight: CATEGORY_WEIGHTS.citation, results: [] },\n content: { score: 0, weight: CATEGORY_WEIGHTS.content, results: [] },\n };\n\n for (const rule of rules) {\n if (onlySet && !onlySet.has(rule.id)) continue;\n if (catSet && !catSet.has(rule.category)) continue;\n\n let result;\n try {\n result = await rule.run(ctx);\n } catch (err) {\n result = {\n status: 'skip' as const,\n score: 0,\n rationale: `Rule crashed: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n buckets[rule.category].results.push({\n id: rule.id,\n title: rule.title,\n weight: rule.weight,\n ...result,\n });\n }\n\n for (const cat of Object.keys(buckets) as Category[]) {\n const b = buckets[cat];\n let weighted = 0;\n let totalWeight = 0;\n for (const r of b.results) {\n if (r.status === 'skip') continue;\n weighted += r.score * r.weight;\n totalWeight += r.weight;\n }\n b.score = totalWeight === 0 ? 0 : Math.round((weighted / totalWeight) * 100);\n }\n\n let overallWeighted = 0;\n let overallWeight = 0;\n for (const cat of Object.keys(buckets) as Category[]) {\n const b = buckets[cat];\n if (b.results.length === 0) continue;\n overallWeighted += b.score * b.weight;\n overallWeight += b.weight;\n }\n const overall = overallWeight === 0 ? 0 : Math.round(overallWeighted / overallWeight);\n\n return {\n url: ctx.url,\n finalUrl: ctx.finalUrl,\n fetchedAt: ctx.fetchedAt,\n renderMode: ctx.renderMode,\n overall,\n categories: buckets,\n warnings: [...ctx.warnings],\n version: VERSION,\n };\n}\n","import { defineRule } from '../../types.js';\n\nexport const httpsRule = defineRule({\n id: 'crawler.https',\n category: 'crawler',\n weight: 2,\n title: 'Site is served over HTTPS',\n description: 'AI crawlers treat HTTPS pages as more trustworthy and some skip plain HTTP entirely.',\n run(ctx) {\n const isHttps = ctx.finalUrl.startsWith('https://');\n return isHttps\n ? { status: 'pass', score: 1, rationale: 'Final URL uses HTTPS.' }\n : {\n status: 'fail',\n score: 0,\n rationale: 'Final URL does not use HTTPS. Redirect HTTP → HTTPS site-wide.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const robotsReachableRule = defineRule({\n id: 'crawler.robots-reachable',\n category: 'crawler',\n weight: 2,\n title: 'robots.txt is reachable',\n description: 'A reachable robots.txt lets crawlers confirm their permissions; missing file is treated as allow-all but blocks explicit signalling.',\n run(ctx) {\n if (ctx.robots) {\n return { status: 'pass', score: 1, rationale: 'robots.txt returned successfully.' };\n }\n return {\n status: 'warn',\n score: 0.3,\n rationale: 'robots.txt is missing. Add one even if empty to explicitly signal crawl policy.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { isPathAllowed, matchGroup } from '../../fetcher/robots.js';\n\nconst AI_BOTS = [\n 'GPTBot',\n 'Google-Extended',\n 'ClaudeBot',\n 'PerplexityBot',\n 'CCBot',\n 'Amazonbot',\n 'anthropic-ai',\n];\n\nexport const robotsAiAllowRule = defineRule({\n id: 'crawler.robots-ai-allow',\n category: 'crawler',\n weight: 5,\n title: 'AI crawlers are allowed',\n description: 'Major AI search crawlers (GPTBot, Google-Extended, ClaudeBot, PerplexityBot, CCBot, Amazonbot) must be allowed to index the homepage.',\n run(ctx) {\n if (!ctx.robots) {\n return {\n status: 'warn',\n score: 0.5,\n rationale: 'robots.txt missing; AI crawlers default to allow, but explicit allow is recommended.',\n };\n }\n\n const path = new URL(ctx.finalUrl).pathname || '/';\n const blocked: string[] = [];\n const mentioned: string[] = [];\n\n for (const bot of AI_BOTS) {\n const group = matchGroup(ctx.robots, bot);\n if (group && group.userAgent.toLowerCase() === bot.toLowerCase()) {\n mentioned.push(bot);\n }\n if (!isPathAllowed(group, path)) blocked.push(bot);\n }\n\n if (blocked.length > 0) {\n return {\n status: 'fail',\n score: 0,\n rationale: `Blocked: ${blocked.join(', ')}. Remove the Disallow or add an explicit Allow for these user-agents.`,\n evidence: { blocked, mentioned },\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n }\n if (mentioned.length === 0) {\n return {\n status: 'warn',\n score: 0.6,\n rationale: 'No AI crawler is explicitly mentioned. Consider adding explicit Allow rules to remove ambiguity.',\n };\n }\n return {\n status: 'pass',\n score: 1,\n rationale: `All AI crawlers can reach the page; ${mentioned.length} explicitly listed.`,\n evidence: { mentioned },\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const llmsTxtPresentRule = defineRule({\n id: 'crawler.llms-txt-present',\n category: 'crawler',\n weight: 4,\n title: 'llms.txt is present',\n description: 'An /llms.txt file at the site root gives AI assistants a curated map of the most citation-worthy pages.',\n run(ctx) {\n if (ctx.llmsTxt) {\n return { status: 'pass', score: 1, rationale: 'llms.txt found at site root.' };\n }\n return {\n status: 'warn',\n score: 0,\n rationale: 'No /llms.txt found. Add one to curate the pages AI assistants should read.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { isLlmsTxtWellFormed } from '../../fetcher/llms-txt.js';\n\nexport const llmsTxtWellformedRule = defineRule({\n id: 'crawler.llms-txt-wellformed',\n category: 'crawler',\n weight: 3,\n title: 'llms.txt follows the spec',\n description: 'Must start with an H1 project title, then a brief summary, then at least one H2 section containing link items.',\n run(ctx) {\n if (!ctx.llmsTxt) {\n return { status: 'skip', score: 0, rationale: 'No llms.txt to validate.' };\n }\n const check = isLlmsTxtWellFormed(ctx.llmsTxt);\n if (check.ok) {\n const totalLinks = ctx.llmsTxt.sections.reduce((n, s) => n + s.links.length, 0);\n return {\n status: 'pass',\n score: 1,\n rationale: `Well-formed with ${ctx.llmsTxt.sections.length} section(s) and ${totalLinks} link(s).`,\n };\n }\n return {\n status: 'warn',\n score: 0.3,\n rationale: `llms.txt does not fully match the spec: ${check.reason}.`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const sitemapPresentRule = defineRule({\n id: 'crawler.sitemap-present',\n category: 'crawler',\n weight: 4,\n title: 'sitemap.xml is present',\n description: 'A sitemap helps AI crawlers discover and prioritise pages; many crawlers short-circuit discovery without one.',\n run(ctx) {\n if (ctx.sitemap && ctx.sitemap.urls.length > 0) {\n return {\n status: 'pass',\n score: 1,\n rationale: `Sitemap found with ${ctx.sitemap.urls.length} URL(s).`,\n };\n }\n return {\n status: 'warn',\n score: 0.2,\n rationale: 'No sitemap.xml found (checked /sitemap.xml and Sitemap: directive in robots.txt).',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { httpsRule } from './https.js';\nimport { robotsReachableRule } from './robots-reachable.js';\nimport { robotsAiAllowRule } from './robots-ai-allow.js';\nimport { llmsTxtPresentRule } from './llms-txt-present.js';\nimport { llmsTxtWellformedRule } from './llms-txt-wellformed.js';\nimport { sitemapPresentRule } from './sitemap-present.js';\n\nexport const crawlerRules = [\n httpsRule,\n robotsReachableRule,\n robotsAiAllowRule,\n llmsTxtPresentRule,\n llmsTxtWellformedRule,\n sitemapPresentRule,\n];\n","import { defineRule } from '../../types.js';\n\nexport const jsonLdPresentRule = defineRule({\n id: 'sd.jsonld-present',\n category: 'structured-data',\n weight: 5,\n title: 'JSON-LD structured data is present',\n description: 'At least one <script type=\"application/ld+json\"> block is the primary way AI engines map your page to an entity.',\n run(ctx) {\n if (ctx.jsonLd.length > 0) {\n return { status: 'pass', score: 1, rationale: `Found ${ctx.jsonLd.length} JSON-LD block(s).` };\n }\n return {\n status: 'fail',\n score: 0,\n rationale: 'No JSON-LD blocks found. Add schema.org structured data.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","export const KNOWN_SCHEMA_TYPES = [\n 'Article',\n 'NewsArticle',\n 'BlogPosting',\n 'FAQPage',\n 'HowTo',\n 'Organization',\n 'Person',\n 'BreadcrumbList',\n 'Product',\n 'WebSite',\n 'WebPage',\n];\n\nexport const REQUIRED_FIELDS: Record<string, string[]> = {\n Article: ['headline', 'author', 'datePublished'],\n NewsArticle: ['headline', 'author', 'datePublished'],\n BlogPosting: ['headline', 'author', 'datePublished'],\n FAQPage: ['mainEntity'],\n HowTo: ['name', 'step'],\n Product: ['name', 'offers'],\n Organization: ['name'],\n Person: ['name'],\n BreadcrumbList: ['itemListElement'],\n};\n\nexport function getTypes(node: unknown): string[] {\n if (!node || typeof node !== 'object') return [];\n const t = (node as { '@type'?: unknown })['@type'];\n if (typeof t === 'string') return [t];\n if (Array.isArray(t)) return t.filter((x): x is string => typeof x === 'string');\n return [];\n}\n\nexport function flattenJsonLd(blocks: unknown[]): unknown[] {\n const out: unknown[] = [];\n const visit = (node: unknown) => {\n if (!node || typeof node !== 'object') return;\n if (Array.isArray(node)) {\n for (const item of node) visit(item);\n return;\n }\n out.push(node);\n const graph = (node as { '@graph'?: unknown })['@graph'];\n if (Array.isArray(graph)) for (const item of graph) visit(item);\n };\n for (const b of blocks) visit(b);\n return out;\n}\n\nexport function hasParseError(blocks: unknown[]): boolean {\n return blocks.some((b) => b && typeof b === 'object' && (b as { __parseError?: boolean }).__parseError);\n}\n\nexport function hasField(node: unknown, field: string): boolean {\n if (!node || typeof node !== 'object') return false;\n const v = (node as Record<string, unknown>)[field];\n if (v == null) return false;\n if (typeof v === 'string') return v.trim().length > 0;\n if (Array.isArray(v)) return v.length > 0;\n return true;\n}\n","import { defineRule } from '../../types.js';\nimport { hasParseError } from '../util.js';\n\nexport const jsonLdValidJsonRule = defineRule({\n id: 'sd.jsonld-valid-json',\n category: 'structured-data',\n weight: 3,\n title: 'JSON-LD blocks parse as valid JSON',\n description: 'Malformed JSON in an ld+json block is silently ignored by most consumers — a costly silent failure.',\n run(ctx) {\n if (ctx.jsonLd.length === 0) {\n return { status: 'skip', score: 0, rationale: 'No JSON-LD to validate.' };\n }\n if (hasParseError(ctx.jsonLd)) {\n return {\n status: 'fail',\n score: 0,\n rationale: 'One or more JSON-LD blocks failed to parse.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n }\n return { status: 'pass', score: 1, rationale: 'All JSON-LD blocks parse cleanly.' };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { flattenJsonLd, getTypes, KNOWN_SCHEMA_TYPES } from '../util.js';\n\nexport const schemaTypeRecognizedRule = defineRule({\n id: 'sd.schema-type-recognized',\n category: 'structured-data',\n weight: 4,\n title: 'Schema.org @type is a recognised kind',\n description: 'AI engines match pages against well-known types (Article, Product, FAQPage...). Obscure types weaken the signal.',\n run(ctx) {\n if (ctx.jsonLd.length === 0) {\n return { status: 'skip', score: 0, rationale: 'No JSON-LD to analyse.' };\n }\n const nodes = flattenJsonLd(ctx.jsonLd);\n const recognized = new Set<string>();\n const seenTypes = new Set<string>();\n for (const node of nodes) {\n for (const t of getTypes(node)) {\n seenTypes.add(t);\n if (KNOWN_SCHEMA_TYPES.includes(t)) recognized.add(t);\n }\n }\n if (recognized.size > 0) {\n return {\n status: 'pass',\n score: 1,\n rationale: `Recognised: ${[...recognized].join(', ')}.`,\n evidence: { recognized: [...recognized], all: [...seenTypes] },\n };\n }\n return {\n status: 'warn',\n score: 0.3,\n rationale: `No recognised schema.org types. Saw: ${[...seenTypes].join(', ') || '(none)'}.`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { flattenJsonLd, getTypes, hasField, REQUIRED_FIELDS } from '../util.js';\n\nexport const requiredFieldsRule = defineRule({\n id: 'sd.required-fields',\n category: 'structured-data',\n weight: 6,\n title: 'Required fields for recognised types are set',\n description: 'Article needs headline/author/datePublished, FAQPage needs mainEntity, Product needs offers, etc.',\n run(ctx) {\n if (ctx.jsonLd.length === 0) {\n return { status: 'skip', score: 0, rationale: 'No JSON-LD to analyse.' };\n }\n const nodes = flattenJsonLd(ctx.jsonLd);\n const missing: Array<{ type: string; field: string }> = [];\n const checked: string[] = [];\n for (const node of nodes) {\n for (const t of getTypes(node)) {\n const required = REQUIRED_FIELDS[t];\n if (!required) continue;\n checked.push(t);\n for (const f of required) {\n if (!hasField(node, f)) missing.push({ type: t, field: f });\n }\n }\n }\n if (checked.length === 0) {\n return {\n status: 'skip',\n score: 0,\n rationale: 'No types with known required fields were found.',\n };\n }\n if (missing.length === 0) {\n return {\n status: 'pass',\n score: 1,\n rationale: `Required fields set on ${checked.length} node(s).`,\n };\n }\n const msg = missing.map((m) => `${m.type}.${m.field}`).join(', ');\n return {\n status: 'fail',\n score: Math.max(0, 1 - missing.length / (checked.length * 2)),\n rationale: `Missing required fields: ${msg}.`,\n evidence: missing,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const microdataFallbackRule = defineRule({\n id: 'sd.microdata-fallback',\n category: 'structured-data',\n weight: 2,\n title: 'Microdata or RDFa fallback when JSON-LD is missing',\n description: 'If JSON-LD is absent, inline microdata (itemscope/itemtype) or RDFa still gives some structured signal.',\n run(ctx) {\n if (ctx.jsonLd.length > 0) {\n return { status: 'skip', score: 0, rationale: 'JSON-LD is present; fallback not needed.' };\n }\n const microdata = ctx.$('[itemscope][itemtype]').length;\n const rdfa = ctx.$('[typeof][vocab], [typeof][property]').length;\n if (microdata > 0 || rdfa > 0) {\n return {\n status: 'pass',\n score: 1,\n rationale: `Found ${microdata} microdata and ${rdfa} RDFa nodes.`,\n };\n }\n return {\n status: 'fail',\n score: 0,\n rationale: 'No structured data at all (no JSON-LD, no microdata, no RDFa).',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { flattenJsonLd, getTypes } from '../util.js';\n\nconst UNIQUE_TYPES = new Set(['Article', 'NewsArticle', 'BlogPosting', 'Product', 'Organization']);\n\nexport const noDuplicateTypesRule = defineRule({\n id: 'sd.no-duplicate-types',\n category: 'structured-data',\n weight: 2,\n title: 'No conflicting duplicate @types',\n description: 'Multiple competing entities of the same primary type (e.g. two Articles) confuse the engine about which one represents the page.',\n run(ctx) {\n if (ctx.jsonLd.length === 0) {\n return { status: 'skip', score: 0, rationale: 'No JSON-LD to analyse.' };\n }\n const counts = new Map<string, number>();\n for (const node of flattenJsonLd(ctx.jsonLd)) {\n for (const t of getTypes(node)) {\n if (UNIQUE_TYPES.has(t)) counts.set(t, (counts.get(t) ?? 0) + 1);\n }\n }\n const dupes = [...counts.entries()].filter(([, n]) => n > 1);\n if (dupes.length === 0) {\n return { status: 'pass', score: 1, rationale: 'No duplicate primary types.' };\n }\n return {\n status: 'warn',\n score: 0.4,\n rationale: `Duplicate primary types: ${dupes.map(([t, n]) => `${t}×${n}`).join(', ')}.`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { jsonLdPresentRule } from './jsonld-present.js';\nimport { jsonLdValidJsonRule } from './jsonld-valid-json.js';\nimport { schemaTypeRecognizedRule } from './schema-type-recognized.js';\nimport { requiredFieldsRule } from './required-fields.js';\nimport { microdataFallbackRule } from './microdata-fallback.js';\nimport { noDuplicateTypesRule } from './no-duplicate-types.js';\n\nexport const structuredDataRules = [\n jsonLdPresentRule,\n jsonLdValidJsonRule,\n schemaTypeRecognizedRule,\n requiredFieldsRule,\n microdataFallbackRule,\n noDuplicateTypesRule,\n];\n","import { defineRule } from '../../types.js';\n\nexport const titleRule = defineRule({\n id: 'cit.title',\n category: 'citation',\n weight: 2,\n title: '<title> is set with a reasonable length',\n description: 'The document title is the single most-cited piece of text and should be 10–70 characters.',\n run(ctx) {\n const title = ctx.$('head > title').first().text().trim();\n if (!title) {\n return {\n status: 'fail',\n score: 0,\n rationale: 'Page has no <title>.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n }\n if (title.length < 10) {\n return {\n status: 'warn',\n score: 0.4,\n rationale: `Title is only ${title.length} chars; consider a more descriptive one.`,\n };\n }\n if (title.length > 70) {\n return {\n status: 'warn',\n score: 0.6,\n rationale: `Title is ${title.length} chars; search UIs commonly truncate after ~70.`,\n };\n }\n return { status: 'pass', score: 1, rationale: `Title length ${title.length} is within range.` };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const metaDescriptionRule = defineRule({\n id: 'cit.meta-description',\n category: 'citation',\n weight: 2,\n title: 'meta description is set (50–160 chars)',\n description: 'AI snippets often quote the meta description verbatim; aim for 50–160 chars.',\n run(ctx) {\n const desc = ctx.$('head meta[name=\"description\"]').attr('content')?.trim() ?? '';\n if (!desc) {\n return {\n status: 'warn',\n score: 0,\n rationale: 'No meta description set.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n }\n if (desc.length < 50) {\n return { status: 'warn', score: 0.5, rationale: `Only ${desc.length} chars; aim for 50+.` };\n }\n if (desc.length > 160) {\n return { status: 'warn', score: 0.7, rationale: `${desc.length} chars; may be truncated after 160.` };\n }\n return { status: 'pass', score: 1, rationale: `Description length ${desc.length} is within range.` };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const canonicalRule = defineRule({\n id: 'cit.canonical',\n category: 'citation',\n weight: 3,\n title: 'Canonical URL is declared',\n description: 'rel=\"canonical\" tells crawlers which URL is the source of truth, preventing duplicate-citation confusion.',\n run(ctx) {\n const href = ctx.$('head link[rel=\"canonical\"]').attr('href')?.trim();\n if (!href) {\n return {\n status: 'warn',\n score: 0,\n rationale: 'No <link rel=\"canonical\"> found.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n }\n try {\n const abs = new URL(href, ctx.finalUrl).toString();\n return { status: 'pass', score: 1, rationale: `Canonical URL: ${abs}.` };\n } catch {\n return { status: 'fail', score: 0, rationale: `Canonical href is not a valid URL: ${href}` };\n }\n },\n});\n","import { defineRule } from '../../types.js';\n\nconst REQUIRED = ['og:title', 'og:type', 'og:url', 'og:image'] as const;\n\nexport const ogTagsRule = defineRule({\n id: 'cit.og-tags',\n category: 'citation',\n weight: 3,\n title: 'Open Graph tags are set',\n description: 'og:title/type/url/image power rich previews on AI chat, social, and messaging.',\n run(ctx) {\n const missing: string[] = [];\n for (const prop of REQUIRED) {\n const val = ctx.$(`head meta[property=\"${prop}\"]`).attr('content')?.trim();\n if (!val) missing.push(prop);\n }\n if (missing.length === 0) {\n return { status: 'pass', score: 1, rationale: 'All required OG tags present.' };\n }\n const ratio = 1 - missing.length / REQUIRED.length;\n return {\n status: missing.length === REQUIRED.length ? 'fail' : 'warn',\n score: ratio,\n rationale: `Missing: ${missing.join(', ')}.`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const twitterCardRule = defineRule({\n id: 'cit.twitter-card',\n category: 'citation',\n weight: 2,\n title: 'Twitter Card metadata is set',\n description: 'twitter:card + twitter:title give better previews on X/Twitter and some AI surfaces that reuse the tags.',\n run(ctx) {\n const card = ctx.$('head meta[name=\"twitter:card\"]').attr('content')?.trim();\n const title = ctx.$('head meta[name=\"twitter:title\"]').attr('content')?.trim();\n if (card && title) {\n return { status: 'pass', score: 1, rationale: `Card type: ${card}.` };\n }\n if (card || title) {\n return { status: 'warn', score: 0.5, rationale: 'Partial twitter:* metadata; add the missing tag.' };\n }\n return {\n status: 'warn',\n score: 0,\n rationale: 'No twitter:card metadata.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const langAttrRule = defineRule({\n id: 'cit.lang-attr',\n category: 'citation',\n weight: 2,\n title: '<html lang> is set',\n description: 'A lang attribute helps AI engines route the page to the right-language search surface (and helps screen readers).',\n run(ctx) {\n const lang = ctx.$('html').attr('lang')?.trim();\n if (!lang) {\n return {\n status: 'warn',\n score: 0,\n rationale: 'No lang attribute on <html>.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n }\n return { status: 'pass', score: 1, rationale: `lang=\"${lang}\".` };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { flattenJsonLd, hasField } from '../util.js';\n\nexport const authorVisibleRule = defineRule({\n id: 'cit.author-visible',\n category: 'citation',\n weight: 4,\n title: 'Author is declared',\n description: 'AI engines prefer citing content with an identifiable author; expose one via JSON-LD, meta[name=author], rel=author, or a .author class.',\n run(ctx) {\n for (const node of flattenJsonLd(ctx.jsonLd)) {\n if (hasField(node, 'author')) {\n return { status: 'pass', score: 1, rationale: 'Author found in JSON-LD.' };\n }\n }\n const metaAuthor = ctx.$('head meta[name=\"author\"]').attr('content')?.trim();\n if (metaAuthor) return { status: 'pass', score: 1, rationale: `meta[name=author] = \"${metaAuthor}\".` };\n if (ctx.$('[rel=\"author\"]').length > 0) {\n return { status: 'pass', score: 1, rationale: 'rel=\"author\" link found.' };\n }\n if (ctx.$('.author, [class*=\"author\"], [itemprop=\"author\"]').length > 0) {\n return { status: 'pass', score: 0.8, rationale: 'Author-ish DOM selector found (weaker signal).' };\n }\n return {\n status: 'warn',\n score: 0,\n rationale: 'No author signal found (JSON-LD, meta, rel, or .author).',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { flattenJsonLd, hasField } from '../util.js';\n\nexport const datesRule = defineRule({\n id: 'cit.dates',\n category: 'citation',\n weight: 5,\n title: 'Publish / modified date is present',\n description: 'AI engines rank recent pages higher; expose datePublished via JSON-LD, <time datetime>, or article:published_time meta.',\n run(ctx) {\n for (const node of flattenJsonLd(ctx.jsonLd)) {\n if (hasField(node, 'datePublished')) {\n return { status: 'pass', score: 1, rationale: 'datePublished found in JSON-LD.' };\n }\n }\n const articleTime = ctx.$('head meta[property=\"article:published_time\"]').attr('content')?.trim();\n if (articleTime) {\n return { status: 'pass', score: 1, rationale: `article:published_time = ${articleTime}.` };\n }\n const timeEl = ctx.$('time[datetime]').first().attr('datetime')?.trim();\n if (timeEl) {\n return { status: 'pass', score: 0.8, rationale: `<time datetime=\"${timeEl}\"> found.` };\n }\n return {\n status: 'warn',\n score: 0,\n rationale: 'No publish date found (JSON-LD, meta article:published_time, or <time datetime>).',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { titleRule } from './title.js';\nimport { metaDescriptionRule } from './meta-description.js';\nimport { canonicalRule } from './canonical.js';\nimport { ogTagsRule } from './og-tags.js';\nimport { twitterCardRule } from './twitter-card.js';\nimport { langAttrRule } from './lang-attr.js';\nimport { authorVisibleRule } from './author-visible.js';\nimport { datesRule } from './dates.js';\n\nexport const citationRules = [\n titleRule,\n metaDescriptionRule,\n canonicalRule,\n ogTagsRule,\n twitterCardRule,\n langAttrRule,\n authorVisibleRule,\n datesRule,\n];\n","import { defineRule } from '../../types.js';\n\nexport const singleH1Rule = defineRule({\n id: 'cnt.single-h1',\n category: 'content',\n weight: 3,\n title: 'Exactly one <h1>',\n description: 'A single H1 tells AI engines the primary topic of the page without ambiguity.',\n run(ctx) {\n const n = ctx.$('h1').length;\n if (n === 1) return { status: 'pass', score: 1, rationale: 'Exactly one <h1>.' };\n if (n === 0) {\n return {\n status: 'fail',\n score: 0,\n rationale: 'No <h1> on the page.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules/cnt.single-h1.md',\n };\n }\n return {\n status: 'warn',\n score: Math.max(0.3, 1 / n),\n rationale: `Found ${n} <h1> tags; prefer one primary heading.`,\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const headingHierarchyRule = defineRule({\n id: 'cnt.heading-hierarchy',\n category: 'content',\n weight: 3,\n title: 'Heading levels do not skip',\n description: 'Going from H2 directly to H4 breaks the outline AI engines use to segment content.',\n run(ctx) {\n const levels: number[] = [];\n ctx.$('h1, h2, h3, h4, h5, h6').each((_i, el) => {\n const name = (el as { tagName?: string }).tagName?.toLowerCase() ?? 'h1';\n const m = /^h([1-6])$/.exec(name);\n if (m?.[1]) levels.push(parseInt(m[1], 10));\n });\n if (levels.length === 0) {\n return { status: 'skip', score: 0, rationale: 'No headings found.' };\n }\n const skips: Array<{ from: number; to: number }> = [];\n for (let i = 1; i < levels.length; i++) {\n const prev = levels[i - 1]!;\n const curr = levels[i]!;\n if (curr > prev + 1) skips.push({ from: prev, to: curr });\n }\n if (skips.length === 0) {\n return { status: 'pass', score: 1, rationale: 'No heading-level skips.' };\n }\n return {\n status: 'warn',\n score: Math.max(0.3, 1 - skips.length / levels.length),\n rationale: `${skips.length} heading skip(s) detected (e.g. h${skips[0]!.from}→h${skips[0]!.to}).`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const imageAltRule = defineRule({\n id: 'cnt.image-alt',\n category: 'content',\n weight: 3,\n title: '≥80% of <img> have alt text',\n description: 'Alt text gives AI engines a textual anchor for visual content and improves accessibility.',\n run(ctx) {\n const imgs = ctx.$('img');\n const total = imgs.length;\n if (total === 0) return { status: 'skip', score: 0, rationale: 'No <img> on the page.' };\n\n let withAlt = 0;\n imgs.each((_i, el) => {\n const alt = ctx.$(el).attr('alt');\n if (typeof alt === 'string' && alt.trim().length > 0) withAlt += 1;\n });\n const ratio = withAlt / total;\n if (ratio >= 0.8) {\n return { status: 'pass', score: 1, rationale: `${withAlt}/${total} images have alt (${Math.round(ratio * 100)}%).` };\n }\n return {\n status: 'warn',\n score: ratio,\n rationale: `Only ${withAlt}/${total} images have alt text (${Math.round(ratio * 100)}%). Aim for ≥80%.`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\nimport { flattenJsonLd, getTypes } from '../util.js';\n\nexport const tldrOrFaqRule = defineRule({\n id: 'cnt.tldr-or-faq',\n category: 'content',\n weight: 5,\n title: 'TL;DR summary or FAQ block',\n description: 'AI engines strongly prefer content with a quotable summary or FAQ — it makes the page \"citation-ready\".',\n run(ctx) {\n for (const node of flattenJsonLd(ctx.jsonLd)) {\n if (getTypes(node).includes('FAQPage')) {\n return { status: 'pass', score: 1, rationale: 'FAQPage schema present.' };\n }\n }\n const sel = [\n 'section[id*=\"tldr\" i]',\n 'section[id*=\"summary\" i]',\n 'section[id*=\"faq\" i]',\n '.tldr',\n '.summary',\n '.faq',\n '[data-tldr]',\n ].join(', ');\n if (ctx.$(sel).length > 0) {\n return { status: 'pass', score: 0.85, rationale: 'TL;DR / summary / FAQ region detected by selector.' };\n }\n return {\n status: 'warn',\n score: 0,\n rationale: 'No TL;DR / summary / FAQ found; add one to boost AI citation odds.',\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { defineRule } from '../../types.js';\n\nexport const wordCountRule = defineRule({\n id: 'cnt.word-count',\n category: 'content',\n weight: 2,\n title: 'Page has enough body text',\n description: 'Thin pages (under ~100 words) are rarely cited by AI engines. Aim for ≥300 words of meaningful body copy.',\n run(ctx) {\n const $ = ctx.$;\n const clone = $('body').clone();\n clone.find('script, style, noscript, nav, header, footer, aside').remove();\n const text = clone.text().replace(/\\s+/g, ' ').trim();\n const words = text ? text.split(' ').length : 0;\n if (words >= 300) return { status: 'pass', score: 1, rationale: `${words} words of body text.` };\n if (words >= 100) return { status: 'warn', score: 0.5, rationale: `Only ${words} words; aim for 300+.` };\n return {\n status: 'fail',\n score: 0,\n rationale: `Only ${words} words; too thin to be cited.`,\n fixUrl: 'https://github.com/BaRam-OSS/geo-checker/blob/main/docs/rules.md',\n };\n },\n});\n","import { singleH1Rule } from './single-h1.js';\nimport { headingHierarchyRule } from './heading-hierarchy.js';\nimport { imageAltRule } from './image-alt.js';\nimport { tldrOrFaqRule } from './tldr-or-faq.js';\nimport { wordCountRule } from './word-count.js';\n\nexport const contentRules = [\n singleH1Rule,\n headingHierarchyRule,\n imageAltRule,\n tldrOrFaqRule,\n wordCountRule,\n];\n","import type { Rule } from '../types.js';\nimport { crawlerRules } from './crawler/index.js';\nimport { structuredDataRules } from './structured-data/index.js';\nimport { citationRules } from './citation/index.js';\nimport { contentRules } from './content/index.js';\n\nexport const defaultRules: Rule[] = [\n ...crawlerRules,\n ...structuredDataRules,\n ...citationRules,\n ...contentRules,\n];\n\nexport { crawlerRules, structuredDataRules, citationRules, contentRules };\n","import type { AuditOptions, AuditReport } from './types.js';\nimport { buildContext } from './context.js';\nimport { runRules } from './engine.js';\nimport { defaultRules } from './rules/index.js';\n\nexport { defineRule, CATEGORY_WEIGHTS } from './types.js';\nexport { defaultRules } from './rules/index.js';\nexport type {\n Status,\n Category,\n Rule,\n RuleResult,\n AuditContext,\n AuditOptions,\n AuditReport,\n CategoryReport,\n RobotsTxt,\n RobotsRuleGroup,\n LlmsTxt,\n LlmsTxtLink,\n LlmsTxtSection,\n SitemapSummary,\n} from './types.js';\n\nexport async function audit(url: string, options: AuditOptions = {}): Promise<AuditReport> {\n const ctx = await buildContext(url, {\n ...(options.render ? { render: true } : {}),\n ...(options.userAgent !== undefined ? { userAgent: options.userAgent } : {}),\n ...(options.timeoutMs !== undefined ? { timeoutMs: options.timeoutMs } : {}),\n });\n const rules = [...defaultRules, ...(options.extraRules ?? [])];\n return runRules(ctx, rules, {\n ...(options.only ? { only: options.only } : {}),\n ...(options.categories ? { categories: options.categories } : {}),\n });\n}\n","import type { AuditReport } from '../types.js';\n\nexport function toJson(report: AuditReport, pretty = true): string {\n return pretty ? JSON.stringify(report, null, 2) : JSON.stringify(report);\n}\n","import kleur from 'kleur';\nimport Table from 'cli-table3';\nimport type { AuditReport, Category, Status } from '../types.js';\n\nconst CATEGORY_LABELS: Record<Category, string> = {\n crawler: 'AI Crawler Access',\n 'structured-data': 'Structured Data',\n citation: 'Citation Signals',\n content: 'Content Structure',\n};\n\nfunction colorScore(score: number): string {\n if (score >= 85) return kleur.green().bold(`${score}`);\n if (score >= 60) return kleur.yellow().bold(`${score}`);\n return kleur.red().bold(`${score}`);\n}\n\nfunction statusBadge(status: Status): string {\n switch (status) {\n case 'pass':\n return kleur.green('pass');\n case 'warn':\n return kleur.yellow('warn');\n case 'fail':\n return kleur.red('fail');\n default:\n return kleur.gray('skip');\n }\n}\n\nfunction bar(score: number, width = 20): string {\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 85 ? kleur.green : score >= 60 ? kleur.yellow : kleur.red;\n return color('█'.repeat(filled)) + kleur.gray('░'.repeat(empty));\n}\n\nexport function toCli(report: AuditReport): string {\n const lines: string[] = [];\n lines.push('');\n lines.push(\n kleur.bold('geo-checker') +\n kleur.gray(' · ') +\n report.finalUrl +\n kleur.gray(` (${report.renderMode})`),\n );\n lines.push(\n kleur.gray('fetched ') +\n report.fetchedAt +\n kleur.gray(' · v') +\n report.version,\n );\n lines.push('');\n lines.push(kleur.bold('Overall ') + colorScore(report.overall) + kleur.gray(' / 100'));\n lines.push('');\n\n for (const w of report.warnings) {\n lines.push(kleur.yellow('! ') + w);\n }\n if (report.warnings.length > 0) lines.push('');\n\n for (const cat of Object.keys(report.categories) as Category[]) {\n const b = report.categories[cat];\n if (b.results.length === 0) continue;\n lines.push(\n ` ${kleur.bold(CATEGORY_LABELS[cat].padEnd(20))} ${bar(b.score)} ${colorScore(b.score).padStart(3)}/100`,\n );\n const table = new Table({\n head: [kleur.gray('status'), kleur.gray('rule'), kleur.gray('note')],\n colWidths: [7, 34, 70],\n wordWrap: true,\n style: { head: [], border: ['grey'] },\n });\n for (const r of b.results) {\n table.push([statusBadge(r.status), r.id, r.rationale]);\n }\n lines.push(\n table\n .toString()\n .split('\\n')\n .map((l) => ' ' + l)\n .join('\\n'),\n );\n lines.push('');\n }\n\n const fixUrls = Object.values(report.categories)\n .flatMap((c) => c.results)\n .filter((r) => (r.status === 'fail' || r.status === 'warn') && r.fixUrl)\n .map((r) => ` - ${r.id}: ${r.fixUrl}`);\n if (fixUrls.length > 0) {\n lines.push(kleur.bold('How to fix:'));\n lines.push(...fixUrls);\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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","names":["kleur","kleur"]}
|