agentblog.dev/docs

CLI

Every agentblog command, its flags, what doctor checks, and what --fix will and will not repair.

npx agentblog@latest <command>

Published to npm as agentblog. It bundles its own copy of TypeScript rather than resolving one from your node_modules, because it edits config files in projects whose TypeScript version it does not control.

Commands

CommandDoes
initCheck the stack, prompt, install, patch the configs, generate keys, run doctor
create <name>Scaffold a new Next.js project and install the blog into it
doctor [--fix]Verify the install. Exits non-zero on an error, so it works in CI
audit [slug]The pre-publish checklist, for one post or all of them
new <title>Scaffold a post file with correct frontmatter
ping <slug>Revalidate and submit to IndexNow by hand
revertRestore the last patch set from .agentblog/backup/
uninstallReverse every config patch, remove the AGENTS.md block, list the files to delete
telemetryAnonymous usage data: on, off, or status

Flags

Four flags are global, accepted before the command name and by every command. Everything else belongs to one command or a few, and agentblog <command> --help is the authority.

Global flagEffect
--cwd <path>Run as if agentblog had started in this directory
--no-telemetryDisable anonymous usage data for this run. DO_NOT_TRACK is also honoured
-v, --versionPrint the version
-h, --helpPrint help for the command

There is no global --dry-run, --yes, --force, or --json. Passing one to a command that does not declare it is an error rather than a no-op, which is worth knowing before you script against this.

FlagAccepted byEffect
--dry-runinit, create, doctor --fix, revert, uninstallPrint the unified diff and write nothing
-y, --yesinit, createSkip the prompts. Read the contract below first
--forceinitProceed even when files already exist under app/blog
--jsondoctor, auditPrint the whole report as one JSON document and nothing else
--verbosedoctor, auditList passing checks as well as failures
--offlinedoctorSkip every check that needs the network
--dir <path>audit, newContent directory. Defaults to content/blog

What --yes actually means

--yes does not accept prompt defaults, because three of the prompts have no defensible default. init --yes on its own refuses and tells you so. The non-interactive form is all four flags together:

npx agentblog@latest init --yes \
  --site-url https://yoursite.com \
  --brand "Your Brand" \
  --author your-slug

Each value is validated against the same rule its prompt uses. A flag that accepted what the prompt rejects would be the same bug arriving through a different door.

init

npx agentblog@latest init [--source mdx] [--site-url https://…] [--brand "Name"] [--author slug]
                          [--yes] [--dry-run] [--force] [--skip-install] [--reinstall]
                          [--registry <url>]

Refuses, before writing anything, when Next.js is older than 16.3 or not on the App Router, React is not 19, Tailwind is not v4, or components.json is absent. The last one prints the shadcn init command rather than running it.

It also refuses when app/blog/** already exists and AgentBlog did not write it, and prints the conflicting paths. --force proceeds.

--skip-install runs only the config patches, which is what you want when the files are already on disk. --reinstall forces the file copy on a project that already has an install manifest. --registry points the @agentblog namespace somewhere other than agentblog.dev, for a local server or a private mirror.

Your content is never overwritten. content/authors.json, content/categories.json, and content/blog/** are snapshotted before the install runs and restored afterwards, so seed content only ever lands where there was nothing.

What a second run does

Nothing. Each patch site has stated semantics rather than "write the value":

Patch siteBehaviour when a value already exists
htmlLimitedBotsUnion, never replace. Replacing is a live SEO regression
images.qualitiesUnion with your array, deduped and sorted
images.remotePatternsAppends when no structurally equal entry exists
metadataBase, title.templateWritten only when absent. Reported, never overwritten
The AGENTS.md blockReplaced between its own markers. Appended when absent
The IndexNow keyGenerated only when both the key file and the environment value are absent

Anything the CLI declines to overwrite becomes a doctor warning, so you are told rather than left half-configured.

AGENTS.md, and the file Next.js also owns

On Next.js 16.3 and later, next dev generates AGENTS.md and CLAUDE.md at your project root and rewrites a managed block inside its own markers on every run. Content outside those markers is preserved.

So init writes strictly after the closing marker, never inside or across it, and never writes CLAUDE.md at all. Next.js generates that file already importing AGENTS.md, so adding our block there would put the same text into context twice. A hand-written CLAUDE.md is left alone.

doctor

npx agentblog@latest doctor [--fix] [--dry-run] [--url https://…] [--offline] [--verbose] [--json]

Exits non-zero on any error-severity finding.

Every finding carries a stable id, printed with the message and included under --json. Search for the id rather than the wording: the wording changes and the id does not.

What it checks

AreaChecks
Crawler confightmlLimitedBots exists and is a superset of the Next.js default list plus the AI crawlers
MetadatametadataBase, title.template, and the RSS entry in the root layout
PrerenderinggenerateStaticParams exists in the post route and is not sliced. An AST check, not a text search
RobotsThe environment guard in app/robots.ts
SitemapNo fabricated lastModified from new Date()
Render pathNo 'use client' anywhere in the article render path
RevalidationEvery revalidateTag call passes a profile, and the publish path uses { expire: 0 }
VersionsNext.js on a patched release, React 19, Tailwind v4, Node 20.9 or newer
Imagesimages.qualities covers every quality the block uses, and preload is on at most one image per route
SecretsThe IndexNow key file exists and matches, and no AgentBlog secret is in a git-tracked file
RoutesNo collision with an existing app/blog/**, and every route file landed
Structured outputPost metadata still spreads the shared defaults, asserted against built HTML rather than source
Agent filesThe AGENTS.md block is outside the Next.js markers and no CLAUDE.md was written by us
Your configdefineConfig is used, siteUrl is real, brand.sameAs is not empty, the author roster has been edited, one config importer
ThemeNo palette utilities, colour literals, or dark-mode colour variants in the installed components
Copy styleNo em dashes in the seed posts, the registry text, or the AGENTS.md block
Client bundleZod is absent from every client chunk
MonorepoReports where each root-level file landed. Never blocks

With --url it adds the live checks: it fetches the URL as GPTBot, ClaudeBot, PerplexityBot, OAI-SearchBot, and Googlebot, and asserts each gets a 200 with body text present and <title> inside <head>. A 403, a challenge page, or an interstitial is a blocking failure that names the CDN it detected.

Run the live checks from outside the deployment

It is an ordinary fetch from wherever the CLI runs. A request originating inside your own network can bypass the exact CDN rule the check exists to find, and then the most valuable check in the product passes on a site no crawler can reach.

What --fix repairs

A fixed list, and nothing else. It never edits a route beyond the robots guard, and it never touches your content.

It writesIt declines when
htmlLimitedBots, as the union of your value, the Next.js list, and the AI crawlersThe key appears twice, a spread could set it, or the current value is not a literal it can read
metadataBase, when absentsiteUrl is missing or still the placeholder, or the layout has no metadata object
title.template, when there is no title or the title is already an objectThe title is a plain string. Converting it changes how every page title on your site is composed, so that is yours
The RSS entry under alternates.typesalternates is not an object literal, or types is already set
The robots environment guardThe default export is not a function body it can edit
images.qualities, unioned and sortedimages appears twice or is not a literal
INDEXNOW_KEY, AGENTBLOG_REVALIDATE_SECRET, and the key file in public/A public/*.txt only counts as a key file when it contains exactly its own name, so security.txt is never touched
The AGENTS.md block, after the Next.js managed regionThe markers are malformed

Everything else is reported with a remedy and never written, for three reasons: it is your code (route files and render paths), it is your decision (tsconfig strictness, config values, components you may have restyled deliberately), or it cannot be written (version floors, missing packages, live HTTP responses).

If the fixable count never goes down

The summary counts findings that are marked fixable, which is a property of the finding rather than a prediction about your file. A project whose root layout has title: 'My Site' as a plain string is told forever that one thing can be repaired, while --fix correctly declines to convert it every time. Read the declined list, or run doctor --fix --json and read fix.declined.

audit

npx agentblog@latest audit [slug] [--dir <path>] [--stale] [--days <n>]
                           [--crawlers <logfile>] [--verbose] [--json]

Runs the pre-publish checklist against one post or all of them, reporting each item pass or fail. It never claims success on a failure.

Every check runs on every post. There is no flag to run a subset, because the checks a writer would switch off are the ones that catch the expensive mistakes. Narrow the input instead: pass a slug, or pass --dir.

--stale lists posts by how overdue a refresh is, ranked by inbound internal links, with --days setting the threshold (90 by default).

--crawlers parses a server or CDN access log and reports hits per bot per week, verifying each hit against the operators' published IP ranges. User agent strings are trivially spoofed, so a count that trusts the string alone is reporting noise.

new

npx agentblog@latest new "Do AI crawlers run JavaScript?" [--slug <slug>] [--dir <path>]
                         [--author <slug>] [--category <slug>]

Writes content/blog/do-ai-crawlers-run-javascript.mdx with complete frontmatter, today's date with an offset, and draft: true. It does not write the post.

Pass --author and --category

new does not read agentblog.config.ts, so without them it writes placeholder values that name no real record. draft: true does not save you: drafts are validated like any other post, so the next build fails with unknown author slug.

ping

npx agentblog@latest ping do-ai-crawlers-run-javascript [--skip-revalidate] [--skip-indexnow]
                          [--site-url <url>] [--key <key>] [--secret <secret>]

Calls your publish webhook and submits the URL to IndexNow, printing the response code with its meaning attached: 200 submitted, 202 accepted with key validation pending, 400 bad format, 403 key invalid or missing, 422 URL and host mismatch, 429 rate limited. The 403 and 422 cases look identical to success from the caller's side, which is why they are printed.

Exit code 0 means every step you asked for happened. A missing credential is an error rather than a warning, because a publish step that silently submits nothing and reports success is the failure this command exists to make loud.

revert and uninstall

npx agentblog@latest revert [--all] [--dry-run]
npx agentblog@latest uninstall [--keep-env] [--keep-backups] [--dry-run]

revert restores the most recent backup only, so a second doctor --fix can be undone without also unwinding your init. revert --all replays every backup newest to oldest, returning the patched files to their state before the first run.

uninstall removes the AGENTS.md block, removes the two environment variables AgentBlog added, restores every backup, removes .agentblog/, and then lists the files the registry wrote without deleting any of them. You have probably edited some, and deleting edited components is not ours to do.

Telemetry

Anonymous and opt-out: install count, framework version, chosen content source, and doctor pass rate. Nothing about your content, your URLs, or your configuration values is collected.

In this release the events are written to a local file and never sent anywhere. --no-telemetry disables it for a run, agentblog telemetry off disables it permanently, and DO_NOT_TRACK is honoured.

On this page