CLI reference
npx ai-visibility audit <url> scores a live page or local build directory against the same seven-dimension content analyzer described on the scoring page, and --fail-under <n>turns it into a CI gate. Every command and flag below was run directly against the installed 0.5.0 binary's --help output and, for audit/lint, against a real URL and a real local directory — not copied from the README.
Install and invoke
npx ai-visibility <command> # no install required
# or
npm install -D ai-visibility && npx ai-visibility <command>Global flags, from ai-visibility --help:
Usage: ai-visibility [options] [command]
Options:
-V, --version output the version number
-q, --quiet suppress the CrawlPod footer and other non-essential output
-h, --help display help for commandaudit — the headline command
Fetches a live URL, or scans a local build directory with --dir, and scores every HTML file it finds against the same ContentAnalyzer the package exports programmatically:
Usage: ai-visibility audit [options] [url]
Arguments:
url URL to audit (fetches the live page)
Options:
--dir <path> Audit a local build directory instead of a live URL
--json Output results as JSON
--fail-under <n> Exit with a non-zero code if any score is below this
threshold (0-100) — for CI
-h, --help display help for commandReal output, run against a plain HTML fixture with a thin body and no structured data:
🤖 ai-visibility audit
❌ fixture/index.html — 35/100
Answer placement: 20 Fact density: 25 Headings: 100 E-E-A-T: 0 Snippability: 30 Schema: 0 Crawler access: 100
🔴 No substantive paragraph found after H1
Fix: Add a clear, direct answer or description in the first paragraph immediately after your H1
🔴 Very low fact density: 0.0 facts per 100 words (target: 4-6)
Fix: Add specific numbers, dates, statistics, or measurable claims to support your content
🔴 No JSON-LD structured data found
Fix: Add JSON-LD schema markup using SchemaBuilder from ai-visibility
... and 4 more issues
──────────────────────────────────────────────────
Scanned: 1
Average score: 35/100
Passing (≥80): 0 / 1
Powered by CrawlPod — https://crawlpod.com--fail-under is opt-in — there is no implicit default threshold for audit, unlike lint below. Passing it flips the exit code without changing the report:
(same report as above, plus:)
❌ Below threshold: at least one score is under 80
exit: 1For a live URL, audit also best-effort fetches robots.txt and checks for llms.txt at the same origin (local files, for --dir) to feed the crawlerAccessibilitydimension — a failed or missing fetch is treated as "unknown", never a hard error. --json returns the same shape ContentAnalyzer.analyze() returns programmatically, one entry per file/URL scanned:
{
"file": "https://example.com/",
"score": 50,
"result": {
"overallScore": 50,
"breakdown": {
"answerFrontLoading": 95,
"factDensity": 25,
"headingStructure": 100,
"eeatSignals": 0,
"snippability": 30,
"schemaCoverage": 0,
"crawlerAccessibility": 100
},
"issues": [ /* { type, severity, message, fix } */ ],
"recommendations": [ /* string[] */ ]
}
}lint — the CI-friendly shorthand
A thin wrapper around the same audit core with defaults tuned for build-time use — this is the build-time GEO linter, not a separate implementation:
Usage: ai-visibility lint [options]
(shorthand for: audit --dir . --fail-under 50)
Options:
--dir <path> Directory to lint (default: ".")
--json Output results as JSON
--fail-under <n> Exit with a non-zero code if any score is below this
threshold (0-100) (default: "50")
-h, --help display help for commandUnlike audit, lint gates by default — running it with no flags against the same thin fixture above exits 1 because 35 is under the default threshold of 50.
Wiring it into CI
Both audit --fail-under and lint exit non-zero on failure, so either drops into a CI step directly:
- name: GEO lint
run: npx ai-visibility lint --dir ./out --fail-under 60Run the build directory your framework actually emits (./out for a Next.js static export, ./dist for Vite, etc.) — pointing it at source files instead of build output audits pre-render markup, not what a crawler will actually receive.
robots and llms — top-level aliases
New in 0.5.0: flatter top-level aliases for the two most common generate subcommands. generate robots/generate llms/generate schema still work unchanged — see generate below.
Usage: ai-visibility robots [options]
Options:
--out <path> Output path (default: "./public/robots.txt")
--preset <preset> allow-all | block-training | block-all
--block-training Shorthand for --preset block-training (deprecated, kept for back-compat)
--sitemap <url> Sitemap URL to include
-h, --help display help for command
Usage: ai-visibility llms [options]
Options:
--out <path> Output path (default: "./public/llms.txt")
--site-name <name> Site name (default: "My Site")
--description <desc> Site description (default: "A website")
--base-url <url> Base URL (e.g. https://mysite.com)
-h, --help display help for command--preset block-all is new in 0.5.0 too, alongside the existing allow-all/block-training — it maps to RobotsGenerator.blockAll(), a control mechanism for site owners who want every known AI crawler blocked, not a recommendation either way. See the generators API reference for the underlying class.
--quiet
Every command accepts a global -q/--quiet, new in 0.5.0. Without it, non-JSON output ends with a one-line, dimmed "Powered by CrawlPod" footer — no color, no upsell block. With --quiet, the footer (and other non-essential output) is gone entirely; verified by running the same audit both ways and diffing the output.
generate — pre-existing subcommands
generate, init, analyze, and logs predate 0.5.0 and are unchanged by it (except generate robots gaining the same --preset flag as the new top-level robots alias, since they share one implementation):
Usage: ai-visibility generate [options] [command]
Commands:
robots [options] Generate robots.txt with AI crawler rules
llms [options] Generate llms.txt for AI model indexing
schema [options] Generate JSON-LD schema markup
Usage: ai-visibility generate schema [options]
Options:
--type <type> Schema type: faq | product | article | org | person (default: "article")
--out <path> Output path (optional, prints to stdout if not set)
--name <name> Name/headline
--price <price> Price (for product schema)
--author <author> Author nameUsage: ai-visibility init [options]
Options:
--dir <path> Project directory (default: ".")
--site-name <name> Your site name
--site-url <url> Your site URL (e.g. https://myapp.com)
--block-training Block training bots (CCBot, GPTBot) while allowing search bots
Usage: ai-visibility analyze [options]
Options:
--dir <path> Directory to scan (default: ".")
--file <path> Analyze a single file
--json Output results as JSON
--min-score <n> Only show files below this score (default: "101")
Usage: ai-visibility logs [options]
Options:
--crawler <name> Filter by crawler name (e.g. GPTBot)
--days <n> Show logs from last N days (default: "7")
--url <path> Filter by URL path
--summary Show summary statistics only
--log-file <path> Path to log file (default: "./logs/ai-crawler.json")
--json Output as JSONanalyze and audit overlap in purpose — both score HTML for AI readability. audit/lint are the ones worth reaching for now: they add the crawlerAccessibility dimension via robots.txt/llms.txt context, a CI-friendly --fail-under exit code, and JSON output shaped for tooling. analyze remains for its --min-score filter across many files at once.
See the scoring pagefor what the seven breakdown dimensions mean and how they're weighted, and the API reference for the programmatic ContentAnalyzer equivalent of audit.