CI Integration
AFDocs includes vitest helpers so you can add agent-friendliness checks to your CI pipeline. Checks run as tests: each check is its own test case, so you can see exactly what passed, warned, failed, or was skipped.
Quick setup
Install AFDocs and vitest as dev dependencies:
npm install -D afdocs vitestConfig file
Create agent-docs.config.yml in your project root:
url: https://docs.example.comThe helpers look for this file starting from process.cwd() and walking up the directory tree.
Test file
Create agent-docs.test.ts:
import { describeAgentDocsPerCheck } from 'afdocs/helpers';
describeAgentDocsPerCheck();Run it
npx vitest run agent-docs.test.tsEach check appears as its own test in the output:
✓ Agent-Friendly Documentation > llms-txt-exists
✓ Agent-Friendly Documentation > llms-txt-valid
✓ Agent-Friendly Documentation > llms-txt-size
× Agent-Friendly Documentation > markdown-url-support
↓ Agent-Friendly Documentation > page-size-markdownChecks that fail cause the test to fail. Checks that warn still pass (they're informational). Checks skipped due to unmet dependencies show as skipped.
Running a subset of checks
For products on a shared documentation host, Documentation at Scale shows how to run repeatable checks on pages your team chooses, both before deployment and on a schedule. It includes a curated config and explains what those checks do and do not establish about agents' ability to find your documentation.
To exclude specific checks, use skipChecks. For example, a local preview server may not implement the content negotiation or cache headers supplied by your production server:
url: https://docs.example.com
skipChecks:
- content-negotiation
- cache-header-hygieneBoth helpers honor skipChecks. Excluded checks do not run; the per-check helper logs their results with a skip status. Prefer this exclude-list for ongoing CI: checks added in later AFDocs versions still run automatically.
For a deliberately narrow run, use the checks include-list instead:
url: https://docs.example.com
checks:
- llms-txt-exists
- llms-txt-valid
- llms-txt-size
- http-status-codes
- auth-gate-detectionChecks not in the list show as skipped in the test output.
Config options
url: https://docs.example.com
# Optional: skip specific checks (run everything else, including future checks)
# skipChecks:
# - content-negotiation
# - cache-header-hygiene
# Optional: run only specific checks
# checks:
# - llms-txt-exists
# - llms-txt-valid
# - llms-txt-size
# Optional: tune sampling behavior
# options:
# maxLinksToTest: 50
# samplingStrategy: deterministic
# Optional: test specific pages (implies samplingStrategy: curated)
# pages:
# - https://docs.example.com/quickstart
# - url: https://docs.example.com/api/auth
# tag: api-referenceConfig resolution
The helpers look for agent-docs.config.yml (or .yaml) starting from process.cwd() and walking up the directory tree. You can also pass an explicit directory:
describeAgentDocsPerCheck(__dirname);Summary helper
If you don't need per-check granularity, describeAgentDocs provides a simpler two-test suite (one to run checks, one to assert no failures):
import { describeAgentDocs } from 'afdocs/helpers';
describeAgentDocs();Direct imports
For full control, use the programmatic API directly:
import { createContext, getCheck } from 'afdocs';
import { describe, it, expect } from 'vitest';
describe('agent-friendliness', () => {
it('has a valid llms.txt', async () => {
const ctx = createContext('https://docs.example.com');
const check = getCheck('llms-txt-exists')!;
const result = await check.run(ctx);
expect(result.status).toBe('pass');
});
});GitHub Actions
Add a workflow file at .github/workflows/agent-docs.yml:
name: Agent-Friendly Docs
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
agent-docs-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: 22
- run: npm install
- name: Run agent-friendly docs checks
run: npx vitest run agent-docs.test.ts
timeout-minutes: 5Add a test script
Alternatively, add a script to your package.json:
{
"scripts": {
"test:agent-docs": "vitest run agent-docs.test.ts"
}
}Then reference it in the workflow:
- name: Run agent-friendly docs checks
run: npm run test:agent-docsChecking a build and the deployed site
A single workflow pointed at your production URL tells you whether your docs are agent-friendly right now. It can't tell you whether the pull request in front of you is about to change that, because the pull request isn't deployed yet. Two targets cover both questions.
On pull requests, check the build. Build the docs, serve the output, and check localhost. This gates a docs change before it ships, and it measures the branch's own content. Skip the checks only your real server can answer, and set canonicalOrigin so the production URLs baked into your generated llms.txt and sitemap.xml resolve against localhost:
# agent-docs.local.yml
url: http://localhost:4173
options:
canonicalOrigin: https://docs.example.com
skipChecks:
- content-negotiation
- cache-header-hygieneSee Run Locally for which checks a local server can't answer and why.
On release, or on a schedule, check the deployed site. This is the run that covers the checks the build can't answer, along with everything your host supplies: redirects, cache headers, bot protection.
# agent-docs.config.yml
url: https://docs.example.comKeep the deployed-site config in agent-docs.config.yml so it is the one discovered by default, and pass the localhost config explicitly with --config. Restrict the pull request workflow to the paths that can affect the result, so unrelated changes don't pay for a site scan:
on:
pull_request:
paths:
- 'docs/**'The CLI and both vitest helpers honor skipChecks.
AFDocs checks its own docs site this way; the two workflows are agent-docs.yml and agent-docs-live.yml.
Other CI providers
The GitHub Actions workflow is just Node.js setup + npm install + running the test. The same steps work on any CI provider. The test exits with code 0 if all checks pass (or warn) and code 1 if any check fails.
Organizing files
If you prefer to keep test files out of your project root, move agent-docs.config.yml and agent-docs.test.ts into a subdirectory (e.g., tests/). Update the test file to tell AFDocs where to find the config:
import { describeAgentDocsPerCheck } from 'afdocs/helpers';
describeAgentDocsPerCheck(__dirname);Timeouts
The helpers set a 120-second timeout on the check run by default. If your site has many pages or your CI runner is slow, you can increase it by passing a second argument (in milliseconds):
// 5-minute timeout
describeAgentDocsPerCheck(__dirname, 300_000);This works with both helpers:
describeAgentDocs(undefined, 300_000);
describeAgentDocsPerCheck(undefined, 300_000);Ready-to-copy example
The examples/ directory in the AFDocs repo contains a complete, ready-to-copy setup with all the files from this page, including the GitHub Actions workflow.