{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "agentblog",
  "homepage": "https://agentblog.dev",
  "items": [
    {
      "name": "blog-core",
      "title": "AgentBlog core",
      "description": "The library layer every other AgentBlog item builds on: the typed config, the content source facade, shared metadata defaults that survive Next.js's shallow metadata merge, the AI referrer classifier, and the build-time preflight that warns when next.config is missing the wiring a registry cannot write.",
      "dependencies": [
        "zod",
        "server-only",
        "@tailwindcss/typography"
      ],
      "files": [
        {
          "path": "registry/blog/agentblog.config.ts",
          "type": "registry:file",
          "target": "~/agentblog.config.ts"
        },
        {
          "path": "registry/blog/lib/config.ts",
          "type": "registry:lib",
          "target": "lib/config.ts"
        },
        {
          "path": "registry/blog/lib/define-config.ts",
          "type": "registry:lib",
          "target": "lib/define-config.ts"
        },
        {
          "path": "registry/blog/lib/schemas.ts",
          "type": "registry:lib",
          "target": "lib/schemas.ts"
        },
        {
          "path": "registry/blog/lib/types.ts",
          "type": "registry:lib",
          "target": "lib/types.ts"
        },
        {
          "path": "registry/blog/lib/posts.ts",
          "type": "registry:lib",
          "target": "lib/posts.ts"
        },
        {
          "path": "registry/blog/lib/metadata.ts",
          "type": "registry:lib",
          "target": "lib/metadata.ts"
        },
        {
          "path": "registry/blog/lib/preflight.ts",
          "type": "registry:lib",
          "target": "lib/preflight.ts"
        },
        {
          "path": "registry/blog/lib/preflight-checks.ts",
          "type": "registry:lib",
          "target": "lib/preflight-checks.ts"
        },
        {
          "path": "registry/blog/lib/ai-referrers.ts",
          "type": "registry:lib",
          "target": "lib/ai-referrers.ts"
        },
        {
          "path": "registry/blog/lib/reading-time.ts",
          "type": "registry:lib",
          "target": "lib/reading-time.ts"
        },
        {
          "path": "registry/blog/lib/toc.ts",
          "type": "registry:lib",
          "target": "lib/toc.ts"
        },
        {
          "path": "registry/blog/styles/agentblog.css",
          "type": "registry:file",
          "target": "~/styles/agentblog.css"
        }
      ],
      "docs": "REQUIRED, and nothing will warn you if you skip it: import the installed styles/agentblog.css from your global stylesheet, after the Tailwind import. From app/globals.css that is `@import '../styles/agentblog.css';`, and from src/app/globals.css it is `@import '../../styles/agentblog.css';`, because the file lands at your project root. Nothing else loads that file, and without it article prose renders with no typography, no error, and no failing check. It also loads @tailwindcss/typography, which was installed for you as a dependency. Then edit agentblog.config.ts and run `npx agentblog@latest doctor --fix` to finish wiring next.config.ts. Skip that last step and AI crawlers receive <title> inside <body> on any page with streamed metadata.",
      "categories": [
        "blog",
        "seo",
        "library"
      ],
      "type": "registry:lib"
    },
    {
      "name": "blog-schema",
      "title": "AgentBlog JSON-LD builders",
      "description": "Typed schema.org @graph builders for BlogPosting, WebPage, BreadcrumbList, Person, Organization, WebSite, ImageObject, and FAQPage. Cross-references are @id stubs from one helper so the graph cannot drift apart, and there is a single serialization point that escapes the output.",
      "devDependencies": [
        "schema-dts"
      ],
      "registryDependencies": [
        "@agentblog/blog-core"
      ],
      "files": [
        {
          "path": "registry/blog/lib/schema.ts",
          "type": "registry:lib",
          "target": "lib/schema.ts"
        },
        {
          "path": "registry/blog/components/blog/json-ld.tsx",
          "type": "registry:component",
          "target": "components/blog/json-ld.tsx"
        }
      ],
      "categories": [
        "blog",
        "seo",
        "structured-data"
      ],
      "type": "registry:lib"
    },
    {
      "name": "blog-ui",
      "title": "AgentBlog reading experience",
      "description": "The components a blog post is made of: post cards, byline with rel=author and machine-readable dates, answer capsule, server-rendered table of contents, author bio, related posts, breadcrumbs, category pills, and real anchor-based pagination. Styled entirely with your shadcn theme tokens, so it inherits your design system rather than replacing it.",
      "dependencies": [
        "class-variance-authority",
        "clsx",
        "lucide-react",
        "tailwind-merge"
      ],
      "registryDependencies": [
        "card",
        "badge",
        "separator",
        "avatar",
        "button",
        "@agentblog/blog-core"
      ],
      "files": [
        {
          "path": "registry/blog/components/blog/icons.tsx",
          "type": "registry:component",
          "target": "components/blog/icons.tsx"
        },
        {
          "path": "registry/blog/components/blog/type-scale.ts",
          "type": "registry:component",
          "target": "components/blog/type-scale.ts"
        },
        {
          "path": "registry/blog/components/blog/prose.tsx",
          "type": "registry:component",
          "target": "components/blog/prose.tsx"
        },
        {
          "path": "registry/blog/components/blog/post-card.tsx",
          "type": "registry:component",
          "target": "components/blog/post-card.tsx"
        },
        {
          "path": "registry/blog/components/blog/post-list.tsx",
          "type": "registry:component",
          "target": "components/blog/post-list.tsx"
        },
        {
          "path": "registry/blog/components/blog/byline.tsx",
          "type": "registry:component",
          "target": "components/blog/byline.tsx"
        },
        {
          "path": "registry/blog/components/blog/author-bio.tsx",
          "type": "registry:component",
          "target": "components/blog/author-bio.tsx"
        },
        {
          "path": "registry/blog/components/blog/answer-capsule.tsx",
          "type": "registry:component",
          "target": "components/blog/answer-capsule.tsx"
        },
        {
          "path": "registry/blog/components/blog/table-of-contents.tsx",
          "type": "registry:component",
          "target": "components/blog/table-of-contents.tsx"
        },
        {
          "path": "registry/blog/components/blog/related-posts.tsx",
          "type": "registry:component",
          "target": "components/blog/related-posts.tsx"
        },
        {
          "path": "registry/blog/components/blog/breadcrumbs.tsx",
          "type": "registry:component",
          "target": "components/blog/breadcrumbs.tsx"
        },
        {
          "path": "registry/blog/components/blog/category-pills.tsx",
          "type": "registry:component",
          "target": "components/blog/category-pills.tsx"
        },
        {
          "path": "registry/blog/components/blog/pagination.tsx",
          "type": "registry:component",
          "target": "components/blog/pagination.tsx"
        },
        {
          "path": "registry/blog/components/blog/share-buttons.tsx",
          "type": "registry:component",
          "target": "components/blog/share-buttons.tsx"
        },
        {
          "path": "registry/blog/hooks/use-toc-active-heading.ts",
          "type": "registry:hook",
          "target": "hooks/use-toc-active-heading.ts"
        }
      ],
      "categories": [
        "blog",
        "ui"
      ],
      "type": "registry:block"
    },
    {
      "name": "mdx-components",
      "title": "AgentBlog MDX components",
      "description": "The component map an AgentBlog post renders through: headings with stable anchors, real tables, server-highlighted code blocks, callouts, statistics with a required source, pull quotes, key takeaways, and an FAQ built from details elements so the answers are in the raw HTML rather than mounted by JavaScript.",
      "registryDependencies": [
        "@agentblog/blog-ui"
      ],
      "files": [
        {
          "path": "registry/blog/components/mdx/index.tsx",
          "type": "registry:component",
          "target": "components/mdx/index.tsx"
        },
        {
          "path": "registry/blog/components/mdx/callout.tsx",
          "type": "registry:component",
          "target": "components/mdx/callout.tsx"
        },
        {
          "path": "registry/blog/components/mdx/code-block.tsx",
          "type": "registry:component",
          "target": "components/mdx/code-block.tsx"
        },
        {
          "path": "registry/blog/components/mdx/faq.tsx",
          "type": "registry:component",
          "target": "components/mdx/faq.tsx"
        },
        {
          "path": "registry/blog/components/mdx/figure.tsx",
          "type": "registry:component",
          "target": "components/mdx/figure.tsx"
        },
        {
          "path": "registry/blog/components/mdx/key-takeaways.tsx",
          "type": "registry:component",
          "target": "components/mdx/key-takeaways.tsx"
        },
        {
          "path": "registry/blog/components/mdx/quote.tsx",
          "type": "registry:component",
          "target": "components/mdx/quote.tsx"
        },
        {
          "path": "registry/blog/components/mdx/stat.tsx",
          "type": "registry:component",
          "target": "components/mdx/stat.tsx"
        },
        {
          "path": "registry/blog/components/mdx/table.tsx",
          "type": "registry:component",
          "target": "components/mdx/table.tsx"
        }
      ],
      "categories": [
        "blog",
        "mdx"
      ],
      "type": "registry:component"
    },
    {
      "name": "blog-routes",
      "title": "AgentBlog routes",
      "description": "Fully prerendered /blog index, post, category, tag, and author routes. generateStaticParams returns every slug, there is no client component in the article render path, and every segment spreads shared metadata defaults so og:site_name and max-snippet survive Next.js's shallow merge.",
      "registryDependencies": [
        "@agentblog/blog-core",
        "@agentblog/blog-schema",
        "@agentblog/blog-ui",
        "@agentblog/mdx-components",
        "@agentblog/source-mdx",
        "@agentblog/seo-routes",
        "@agentblog/eeat-pages"
      ],
      "files": [
        {
          "path": "registry/blog/app/blog/layout.tsx",
          "type": "registry:page",
          "target": "app/blog/layout.tsx"
        },
        {
          "path": "registry/blog/app/blog/page.tsx",
          "type": "registry:page",
          "target": "app/blog/page.tsx"
        },
        {
          "path": "registry/blog/app/blog/opengraph-image.tsx",
          "type": "registry:page",
          "target": "app/blog/opengraph-image.tsx"
        },
        {
          "path": "registry/blog/app/blog/[slug]/page.tsx",
          "type": "registry:page",
          "target": "app/blog/[slug]/page.tsx"
        },
        {
          "path": "registry/blog/app/blog/[slug]/opengraph-image.tsx",
          "type": "registry:page",
          "target": "app/blog/[slug]/opengraph-image.tsx"
        },
        {
          "path": "registry/blog/app/blog/category/[slug]/page.tsx",
          "type": "registry:page",
          "target": "app/blog/category/[slug]/page.tsx"
        },
        {
          "path": "registry/blog/app/blog/tag/[slug]/page.tsx",
          "type": "registry:page",
          "target": "app/blog/tag/[slug]/page.tsx"
        },
        {
          "path": "registry/blog/app/authors/layout.tsx",
          "type": "registry:page",
          "target": "app/authors/layout.tsx"
        },
        {
          "path": "registry/blog/app/authors/[slug]/page.tsx",
          "type": "registry:page",
          "target": "app/authors/[slug]/page.tsx"
        },
        {
          "path": "registry/blog/lib/og-card.tsx",
          "type": "registry:lib",
          "target": "lib/og-card.tsx"
        }
      ],
      "docs": "Routes installed. If app/blog/page.tsx is not on disk, shadcn did not detect your framework and silently installed nothing. Run `npx agentblog@latest doctor` to confirm. This item also installs @agentblog/seo-routes and @agentblog/eeat-pages, because the blog layout links /feed.xml and /editorial-policy. Without them the routes render links that 404. The Open Graph cards live under app/blog/, so nothing here overwrites an app/opengraph-image.* of your own.",
      "categories": [
        "blog",
        "seo",
        "routes"
      ],
      "type": "registry:block"
    },
    {
      "name": "seo-routes",
      "title": "AgentBlog SEO routes",
      "description": "sitemap.xml built from real content dates rather than the build clock, an environment-guarded robots.txt that declares your AI access preferences, an RSS 2.0 feed, and a 404 that returns a real 404.",
      "registryDependencies": [
        "@agentblog/blog-core"
      ],
      "files": [
        {
          "path": "registry/blog/app/sitemap.ts",
          "type": "registry:page",
          "target": "app/sitemap.ts"
        },
        {
          "path": "registry/blog/app/robots.ts",
          "type": "registry:page",
          "target": "app/robots.ts"
        },
        {
          "path": "registry/blog/app/feed.xml/route.ts",
          "type": "registry:page",
          "target": "app/feed.xml/route.ts"
        },
        {
          "path": "registry/blog/app/llms.txt/route.ts",
          "type": "registry:page",
          "target": "app/llms.txt/route.ts"
        },
        {
          "path": "registry/blog/app/not-found.tsx",
          "type": "registry:page",
          "target": "app/not-found.tsx"
        }
      ],
      "categories": [
        "blog",
        "seo"
      ],
      "type": "registry:block"
    },
    {
      "name": "publish-webhook",
      "title": "AgentBlog publish webhook",
      "description": "A publish endpoint that revalidates the metadata routes as well as the page routes, because sitemap.xml and feed.xml are cached route handlers that a naive webhook leaves stale, and then submits the URL to IndexNow with the response codes surfaced rather than swallowed.",
      "registryDependencies": [
        "@agentblog/blog-core"
      ],
      "files": [
        {
          "path": "registry/blog/app/api/publish/route.ts",
          "type": "registry:page",
          "target": "app/api/publish/route.ts"
        },
        {
          "path": "registry/blog/lib/indexnow.ts",
          "type": "registry:lib",
          "target": "lib/indexnow.ts"
        }
      ],
      "envVars": {
        "AGENTBLOG_REVALIDATE_SECRET": "",
        "INDEXNOW_KEY": ""
      },
      "docs": "Two empty entries were added to .env.local: AGENTBLOG_REVALIDATE_SECRET and INDEXNOW_KEY. They are placeholders, not keys. Run `npx agentblog@latest doctor --fix` to generate real values and write the matching public/<key>.txt file that IndexNow needs. If you keep secrets in a different env file, doctor check 13 runs `git check-ignore` on it and offers to move them somewhere untracked.",
      "categories": [
        "blog",
        "seo",
        "api"
      ],
      "type": "registry:block"
    },
    {
      "name": "source-mdx",
      "title": "AgentBlog MDX content source",
      "description": "Posts as MDX files in your repository, which is the storage option a coding agent can genuinely maintain. Includes the content source adapter, the single MDX compilation point, two local remark plugins, and two seed posts written to the GEO playbook so they double as the format specification.",
      "dependencies": [
        "github-slugger",
        "gray-matter",
        "next-mdx-remote-client",
        "rehype-autolink-headings",
        "rehype-pretty-code",
        "rehype-slug",
        "remark-gfm",
        "shiki"
      ],
      "devDependencies": [
        "@types/mdast",
        "vfile"
      ],
      "registryDependencies": [
        "@agentblog/blog-core",
        "@agentblog/mdx-components"
      ],
      "files": [
        {
          "path": "registry/blog/lib/sources/mdx.ts",
          "type": "registry:lib",
          "target": "lib/sources/mdx.ts"
        },
        {
          "path": "registry/blog/lib/render-mdx.tsx",
          "type": "registry:lib",
          "target": "lib/render-mdx.tsx"
        },
        {
          "path": "registry/blog/lib/mdx-plugins/remark-extract-toc.ts",
          "type": "registry:lib",
          "target": "lib/mdx-plugins/remark-extract-toc.ts"
        },
        {
          "path": "registry/blog/lib/mdx-plugins/remark-answer-capsule.ts",
          "type": "registry:lib",
          "target": "lib/mdx-plugins/remark-answer-capsule.ts"
        },
        {
          "path": "registry/blog/content/authors.json",
          "type": "registry:file",
          "target": "~/content/authors.json"
        },
        {
          "path": "registry/blog/content/categories.json",
          "type": "registry:file",
          "target": "~/content/categories.json"
        },
        {
          "path": "registry/blog/content/blog/how-ai-search-engines-read-your-blog.mdx",
          "type": "registry:file",
          "target": "~/content/blog/how-ai-search-engines-read-your-blog.mdx"
        },
        {
          "path": "registry/blog/content/blog/what-makes-an-ai-engine-cite-your-post.mdx",
          "type": "registry:file",
          "target": "~/content/blog/what-makes-an-ai-engine-cite-your-post.mdx"
        }
      ],
      "docs": "Edit content/authors.json and content/categories.json, then read the two seed posts before writing your own. They are the format specification, not filler.",
      "categories": [
        "blog",
        "content",
        "mdx"
      ],
      "type": "registry:block"
    },
    {
      "name": "eeat-pages",
      "title": "AgentBlog trust pages",
      "description": "An editorial policy page with a real review and corrections process. This is the Trust surface a search quality rater looks for and almost no blog has one, which makes it unusually cheap to differentiate on.",
      "registryDependencies": [
        "@agentblog/blog-core"
      ],
      "files": [
        {
          "path": "registry/blog/app/editorial-policy/page.tsx",
          "type": "registry:page",
          "target": "app/editorial-policy/page.tsx"
        }
      ],
      "docs": "Edit app/editorial-policy/page.tsx before publishing. A placeholder policy is worse than none.",
      "categories": [
        "blog",
        "seo",
        "eeat"
      ],
      "type": "registry:block"
    },
    {
      "name": "blog-minimal",
      "title": "AgentBlog without the webhook or the agent kit",
      "description": "The full blog, minus the two items a reader never sees: no /api/publish route and no secrets in .env, and nothing written into .claude/. Everything else matches @agentblog/blog. It cannot be smaller than that: the routes share one sitemap and one layout, app/sitemap.ts emits category, author, tag, and /editorial-policy URLs, and the blog layout links /editorial-policy and /feed.xml, so dropping those routes would publish a sitemap of 404s rather than a smaller blog. Install this when you want the blog without a publish endpoint to secure.",
      "registryDependencies": [
        "@agentblog/blog-core",
        "@agentblog/blog-schema",
        "@agentblog/blog-ui",
        "@agentblog/mdx-components",
        "@agentblog/blog-routes",
        "@agentblog/source-mdx"
      ],
      "files": [],
      "docs": "Installed without the publish webhook and without the agent skills. Run `npx agentblog@latest doctor --fix` to finish wiring next.config.ts. To publish, redeploy or add @agentblog/publish-webhook later.",
      "categories": [
        "blog",
        "seo"
      ],
      "type": "registry:block"
    },
    {
      "name": "blog",
      "title": "AgentBlog",
      "description": "A complete, production-ready blog for Next.js 16 that AI search engines can actually read. Fully prerendered routes, a typed schema.org graph, sitemap and RSS and IndexNow, Open Graph images, answer capsules and question headings for retrieval, and an editorial policy page. Inherits your shadcn theme rather than imposing one.",
      "registryDependencies": [
        "@agentblog/blog-core",
        "@agentblog/blog-schema",
        "@agentblog/blog-ui",
        "@agentblog/mdx-components",
        "@agentblog/blog-routes",
        "@agentblog/seo-routes",
        "@agentblog/publish-webhook",
        "@agentblog/source-mdx",
        "@agentblog/eeat-pages",
        "@agentblog/agent-kit"
      ],
      "files": [],
      "docs": "Installed. Now run `npx agentblog@latest doctor --fix`. It patches next.config.ts and app/layout.tsx, which a registry cannot do. Skip it and your next.config.ts has no htmlLimitedBots, which means GPTBot, ClaudeBot, and PerplexityBot receive <title> inside <body> instead of <head>.",
      "categories": [
        "blog",
        "seo",
        "geo",
        "content"
      ],
      "type": "registry:block"
    },
    {
      "name": "agent-kit",
      "title": "AgentBlog agent kit",
      "description": "Seven skills that take a blog from install to published: finish the setup for your site, research what to write with real search and AI citation data, plan the topic clusters, write posts to the GEO playbook, refresh them without falsifying dateModified, audit before publish, and publish with the IndexNow response code actually read. Installs into your project's .claude/skills directory, so any agent working in this repository picks them up. Also available as a Claude Code plugin and through npx skills add.",
      "files": [
        {
          "path": "registry/agent/skills/agentblog-setup/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/agentblog-setup/SKILL.md"
        },
        {
          "path": "registry/agent/skills/dataforseo-research/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/dataforseo-research/SKILL.md"
        },
        {
          "path": "registry/agent/skills/dataforseo-research/references/setup.md",
          "type": "registry:file",
          "target": "~/.claude/skills/dataforseo-research/references/setup.md"
        },
        {
          "path": "registry/agent/skills/dataforseo-research/references/endpoints.md",
          "type": "registry:file",
          "target": "~/.claude/skills/dataforseo-research/references/endpoints.md"
        },
        {
          "path": "registry/agent/skills/dataforseo-research/references/playbook.md",
          "type": "registry:file",
          "target": "~/.claude/skills/dataforseo-research/references/playbook.md"
        },
        {
          "path": "registry/agent/skills/dataforseo-research/references/catalog.md",
          "type": "registry:file",
          "target": "~/.claude/skills/dataforseo-research/references/catalog.md"
        },
        {
          "path": "registry/agent/skills/plan-blog-content/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/plan-blog-content/SKILL.md"
        },
        {
          "path": "registry/agent/skills/write-blog-post/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/write-blog-post/SKILL.md"
        },
        {
          "path": "registry/agent/skills/write-blog-post/references/geo-playbook.md",
          "type": "registry:file",
          "target": "~/.claude/skills/write-blog-post/references/geo-playbook.md"
        },
        {
          "path": "registry/agent/skills/write-blog-post/references/schema-reference.md",
          "type": "registry:file",
          "target": "~/.claude/skills/write-blog-post/references/schema-reference.md"
        },
        {
          "path": "registry/agent/skills/write-blog-post/references/voice.md",
          "type": "registry:file",
          "target": "~/.claude/skills/write-blog-post/references/voice.md"
        },
        {
          "path": "registry/agent/skills/write-blog-post/references/checklist.md",
          "type": "registry:file",
          "target": "~/.claude/skills/write-blog-post/references/checklist.md"
        },
        {
          "path": "registry/agent/skills/refresh-blog-post/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/refresh-blog-post/SKILL.md"
        },
        {
          "path": "registry/agent/skills/agentblog-audit/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/agentblog-audit/SKILL.md"
        },
        {
          "path": "registry/agent/skills/publish-blog-post/SKILL.md",
          "type": "registry:file",
          "target": "~/.claude/skills/publish-blog-post/SKILL.md"
        },
        {
          "path": "registry/agent/AGENTS.agentblog.md",
          "type": "registry:file",
          "target": "~/AGENTS.agentblog.md"
        }
      ],
      "docs": "Skills installed. AGENTS.agentblog.md is a fragment, not a replacement for your AGENTS.md. Run `npx agentblog@latest doctor --fix` to merge it into your real AGENTS.md, outside the block Next.js manages, and to finish wiring next.config.ts. Then ask your agent to finish the setup.",
      "categories": [
        "blog",
        "agents",
        "claude-code"
      ],
      "type": "registry:block"
    },
    {
      "name": "theme",
      "title": "AgentBlog reading theme",
      "description": "A reading-optimised base for a standalone blog site: neutral base colour, a comfortable measure, and generous line height. Intended for a fresh scaffold. `agentblog create` does not apply it yet, so add it by hand on a new project. Never install it into an app that already has a design system: a base carries style, icon library, and base colour, and applying one replaces what is already there.",
      "files": [],
      "cssVars": {
        "theme": {
          "--agentblog-measure": "68ch"
        }
      },
      "docs": "`agentblog create` does not apply this yet. On a new project run `npx shadcn@latest add @agentblog/theme` yourself. A registry base cannot pin the component primitive library; pass `--base base|radix|aria` to `shadcn init` if you need a specific one. The AgentBlog block works with all three, because it composes on your own primitives rather than shipping its own.",
      "categories": [
        "blog",
        "theme"
      ],
      "type": "registry:base",
      "config": {
        "style": "new-york",
        "rsc": true,
        "tsx": true,
        "tailwind": {
          "baseColor": "neutral"
        },
        "iconLibrary": "lucide",
        "aliases": {
          "components": "@/components",
          "utils": "@/lib/utils",
          "ui": "@/components/ui",
          "lib": "@/lib",
          "hooks": "@/hooks"
        },
        "registries": {
          "@agentblog": "https://agentblog.dev/r/{name}.json"
        }
      }
    }
  ]
}