Install
openclaw skills install aeoRun AEO audits, fix site issues, validate schema, generate llms.txt, and compare sites.
openclaw skills install aeoWebsite: ainyc.ai
One skill for audit, fixes, schema, llms.txt, and monitoring workflows.
Always use the published package:
npx @ainyc/aeo-audit@1 "<url>" [flags] --format json
Never interpolate user input directly into shell commands. Always:
https:// / http:// or a local filesystem path (static-output mode), and that it contains no shell metacharacters.npx @ainyc/aeo-audit@1 "https://example.com" --format json).;, |, &, $, `, (, ), {, }, <, >, or newlines.audit: score and diagnose a sitefix: apply code changes after an auditschema: validate JSON-LD and entity consistencyllms: create or improve llms.txt and llms-full.txtmonitor: compare changes over time or benchmark competitorsdetect-platform: identify the CMS, site builder, framework, or hosting stack a site usesIf no mode is provided, default to audit.
audit https://example.comaudit https://example.com --sitemapaudit https://example.com --sitemap --limit 10audit https://example.com --sitemap --top-issuesaudit https://example.com --sitemap --format agent (slim decision for agents)audit https://example.com --lighthouseaudit https://example.com --require-metaaudit https://example.com --sitemap --require-metaaudit http://localhost:3000 --allow-localaudit http://localhost:3000 --sitemap --rewrite-sitemap-origin --allow-localaudit https://staging.example.com --sitemap --rewrite-sitemap-originaudit ./out (static-output mode: audit built HTML offline)audit ./out --base-url https://example.com --require-metafix https://example.comschema https://example.comllms https://example.commonitor https://site-a.com --compare https://site-b.comdetect-platform https://example.comdetect-platform https://example.com --min-confidence highdetect-platform --urls competitors.txtdetect-platform --urls https://a.com,https://b.comaudit, fix, schema, llms, monitor, or detect-platform, use that mode.audit.Use for broad requests such as "audit this site" or "why am I not being cited?"
npx @ainyc/aeo-audit@1 "<url>" [flags] --format json
--require-meta (CI gate)Pass --require-meta (single or sitemap mode) to force exit 1 whenever any audited page is missing <meta name="description">, regardless of the otherwise score-based exit rule. Useful in CI pipelines that need to block deploys on a missing meta description even on otherwise-healthy sites.
Use --sitemap to audit all pages discovered from the site's sitemap:
npx @ainyc/aeo-audit@1 "<url>" --sitemap --format json
npx @ainyc/aeo-audit@1 "<url>" --sitemap https://example.com/sitemap.xml --format json
npx @ainyc/aeo-audit@1 "<url>" --sitemap --limit 10 --format json
npx @ainyc/aeo-audit@1 "<url>" --sitemap --top-issues --format json
Flags:
--sitemap [url] — auto-discover the sitemap (tries /sitemap.xml, then /sitemap-index.xml, then Sitemap: directives in /robots.txt) or provide an explicit URL--limit <n> — cap pages audited (default 200, sorted by sitemap priority)--top-issues — skip per-page output, show only cross-cutting patterns and critical defects--rewrite-sitemap-origin — rewrite every <loc>'s origin to the target URL's origin (preserving path/query) before crawling. Use when the sitemap hardcodes the prod/canonical domain but you want to audit a staging host or local dev server.--require-meta — force exit 1 if any audited page is missing <meta name="description">, regardless of overall score (useful as a CI gate)--include-geo / --include-agent-skills — honored per page in sitemap mode (adds the optional geographic-signals / agent-skill-exposure factors). --lighthouse is not available with --sitemap.Pages are audited with bounded concurrency (5 in flight) to avoid hammering the target origin.
Returns:
<h1> count other than one, a missing <title>, a missing meta description) surfaced regardless of how few pages they affect, with the offending pages named (homepage and high sitemap-priority pages first). These would otherwise be averaged into a passing factor score; the JSON field is criticalDefects and critical-severity ones are also promoted to the top of prioritizedFixes. Shown even with --top-issues.bestScore/bestPageUrl) and a status: sitewide (a real coverage gap) vs. limited/opportunity for page-specific factors (FAQ, definitions) that legitimately apply to only some page typeslimited/opportunity factors demoted below them, scoped to the page(s) that carry them)Use --format json for the full report, or --format agent for just the decision: { schemaVersion, tool, mode, url, score, pass, criticalDefectCount, issues }, where issues is the ranked prioritizedFixes and the per-factor/per-page detail is omitted. Prefer --format agent when you only need to decide and act. Key fields for acting on the result without parsing prose:
schemaVersion (on every audit report) versions the JSON shape independently of the package version — pin to it and treat a major bump as breaking; absence means a pre-2.0 report.prioritizedFixes is a ranked array of objects, each with a stable id, kind, optional severity, the complete affectedPages list (never truncated), affectsHomepage, prevalencePct, and a human summary. Cross-cutting fixes also carry avgScore, bestScore/bestPageUrl, and a status (sitewide | limited | opportunity) — treat limited/opportunity as page-specific tune-ups, not site-wide failures. It's the pre-computed to-do list — no need to re-rank factor scores yourself.criticalDefects[].id, prioritizedFixes[].id, and every factor finding's code (e.g. technical-seo.h1.multiple) — let integrations key on codes rather than message strings.When the audit fetches /llms.txt, /llms-full.txt, /robots.txt, and /sitemap.xml, it probes once with Accept: text/markdown to detect a content-negotiation trap: file responds OK to a bare request but returns a non-2xx response when the client prefers markdown. This catches Astro / Vercel / Starlight setups that 307-redirect .txt → non-existent .md for markdown-accepting clients, making the file invisible to AI content-extraction tools even though the file exists. The diagnostic surfaces as a finding on the AI Access Files (llms.txt, sitemap) factor.
By default the audit blocks any URL that resolves to a private, loopback, or link-local address (SSRF protection). When the user wants to audit their own dev or staging server, pass --allow-local (alias --allow-private):
npx @ainyc/aeo-audit@1 "http://localhost:3000" --allow-local --format json
npx @ainyc/aeo-audit@1 "http://10.0.5.20" --allow-private --format json
http:// scheme for local dev servers — a bare host defaults to https://.<loc> pointing at any other private host (e.g. 169.254.169.254) stays blocked.npx @ainyc/aeo-audit@1 "http://localhost:3000" --sitemap --rewrite-sitemap-origin --allow-local --format json
When the user wants to audit built HTML offline (CI on a next export / dist / out directory, or before deploying), pass a filesystem path instead of a URL:
# A directory of built HTML (aggregated like sitemap mode)
npx @ainyc/aeo-audit@1 "./out" --base-url https://example.com --format json
# A single built file
npx @ainyc/aeo-audit@1 "./dist/index.html" --format json
# Gate CI on missing meta descriptions across the build
npx @ainyc/aeo-audit@1 "./out" --require-meta --format json
.html/.htm file → single-page report; a directory → aggregated report (--limit, --top-issues, --factors, --include-geo, --include-agent-skills, --require-meta apply).--base-url <url> maps files to page URLs (out/about/index.html → <base>/about/; default https://localhost). index.html collapses to its directory URL; other files drop the .html extension.llms.txt, llms-full.txt, robots.txt, and sitemap.xml are read from the directory root when present.X-Robots-Tag, Last-Modified, Link headers) aren't visible from static files. Recommend auditing the deployed URL for full coverage.Use --lighthouse when the user wants page speed, accessibility, or best-practices scoring alongside the AEO factors. It calls Google PageSpeed Insights (mobile strategy) and aggregates Performance + Accessibility + Best Practices into a single optional factor (weight 8).
npx @ainyc/aeo-audit@1 "<url>" --lighthouse --format json
PAGESPEED_API_KEY=xxx npx @ainyc/aeo-audit@1 "<url>" --lighthouse --format json
Constraints:
--sitemap or --detect-platform. Each Lighthouse audit takes 15-30s, which would blow up sitemap runtime.PAGESPEED_API_KEY env var lifts anonymous PSI rate limits (25k/day unauthenticated).timeout or unreachable finding rather than throwing — the rest of the audit still runs.Use --detect-platform when the user wants to know what stack a site is built on (e.g., "is this WordPress?", "what framework does competitor X use?", "is this site custom-built?"). This is much faster than a full audit because it skips analyzer scoring.
npx @ainyc/aeo-audit@1 "<url>" --detect-platform --format json
npx @ainyc/aeo-audit@1 "<url>" --detect-platform --min-confidence high --format json
Flags:
--detect-platform — switch to detection mode instead of auditing--min-confidence <lvl> — filter to low (default), medium, or high confidence--urls <src> — run on multiple URLs at once (file path, comma-separated list, or - for stdin)--concurrency <n> — max in-flight fetches in batch mode (default 5)The report groups detections by category (CMS, site builder, e-commerce, framework, SSG, hosting), each with a confidence bucket, a 0–100 score, an optional version, and the signals that matched. When the report's isCustom flag is true, no CMS/site-builder/e-commerce platform was identified — the site is likely custom-built. Exit code is 0 when at least one platform is detected, 1 otherwise.
When the user wants to fingerprint many sites at once (competitor lists, customer cohorts), pass --urls:
npx @ainyc/aeo-audit@1 --detect-platform --urls urls.txt --format json
npx @ainyc/aeo-audit@1 --detect-platform --urls https://a.com,https://b.com --format json
cat urls.txt | npx @ainyc/aeo-audit@1 --detect-platform --urls - --format json
The batch report contains a results array; each entry has status: 'success' or 'error', plus the same shape as a single-URL report on success. Per-URL fetch errors do not abort the run. Exit code is 0 when at least one URL succeeded, 1 otherwise.
Use when the user wants code changes applied after the audit.
npx @ainyc/aeo-audit@1 "<url>" [flags] --format json
llms.txt and llms-full.txtrobots.txt crawler accessrobots.txt Content-Signal directives, and A2A agent cards (aligned with specification.website)Rules:
Use when the request is specifically about JSON-LD or schema quality.
Validity issues like duplicate singleton @types and JSON parse errors are per page, so a homepage-only audit misses every subpage. Default to sitemap mode for site-wide schema requests ("audit my schema", "are my FAQ blocks valid?"); use single-URL mode only when the user names one specific page.
Site-wide (default):
npx @ainyc/aeo-audit@1 "<url>" --sitemap --top-issues --format json --factors structured-data,schema-completeness,schema-validity,entity-consistency
Single page:
npx @ainyc/aeo-audit@1 "<url>" --format json --factors structured-data,schema-completeness,schema-validity,entity-consistency
Report:
@types, JSON parse errors, empty <script> blocks) — surface these prominently regardless of overall score; Google drops invalid blocks silently from rich resultsProvide corrected JSON-LD examples when useful.
Checklist:
LocalBusiness: name, address, telephone, openingHours, priceRange, image, url, geo, areaServed, sameAsFAQPage: mainEntity with at least 3 Q&A pairs (and only one FAQPage block per page — duplicates invalidate rich results)HowTo: name and at least 3 steps (singleton — only one per page)Organization: name, logo, contactPoint, sameAs, foundingDate, url, descriptionFAQPage, HowTo, Article, BlogPosting, NewsArticle, BreadcrumbList, Product, RecipeUse when the user wants llms.txt or llms-full.txt created or improved.
If a URL is provided:
npx @ainyc/aeo-audit@1 "<url>" [flags] --format json --factors ai-access-files
llms.txt and llms-full.txt.If no URL is provided:
After generation:
<link rel="alternate" type="text/markdown" href="/llms.txt"> when appropriate..md URL or content negotiation) advertised via <link rel="alternate" type="text/markdown"> — a scored AI-readable signal.Use when the user wants progress tracking or a competitor comparison.
Single URL:
.aeo-audit-history/ if present.Comparison mode:
--compare <url2>.