ax-audit 4.2.1 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +39 -4
- package/dist/baseline.js +1 -1
- package/dist/baseline.js.map +1 -1
- package/dist/check-ids.js +1 -1
- package/dist/check-ids.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -85
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -135
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/license.d.ts +8 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +18 -0
- package/dist/license.js.map +1 -0
- package/dist/metadata.d.ts +6 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +205 -0
- package/dist/metadata.js.map +1 -0
- package/dist/orchestrator.d.ts +1 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +134 -56
- package/dist/orchestrator.js.map +1 -1
- package/dist/scorer.js +2 -2
- package/dist/scorer.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/api.md +14 -3
- package/docs/architecture.md +9 -98
- package/docs/ci.md +19 -0
- package/docs/cli.md +11 -0
- package/docs/faq.md +18 -0
- package/docs/getting-started.md +33 -1
- package/package.json +5 -5
- package/dist/checks/agent-access.d.ts +0 -33
- package/dist/checks/agent-access.d.ts.map +0 -1
- package/dist/checks/agent-access.js +0 -256
- package/dist/checks/agent-access.js.map +0 -1
- package/dist/checks/agent-card.d.ts +0 -37
- package/dist/checks/agent-card.d.ts.map +0 -1
- package/dist/checks/agent-card.js +0 -352
- package/dist/checks/agent-card.js.map +0 -1
- package/dist/checks/agent-operability.d.ts +0 -66
- package/dist/checks/agent-operability.d.ts.map +0 -1
- package/dist/checks/agent-operability.js +0 -383
- package/dist/checks/agent-operability.js.map +0 -1
- package/dist/checks/agent-skills.d.ts +0 -24
- package/dist/checks/agent-skills.d.ts.map +0 -1
- package/dist/checks/agent-skills.js +0 -316
- package/dist/checks/agent-skills.js.map +0 -1
- package/dist/checks/ai-catalog.d.ts +0 -28
- package/dist/checks/ai-catalog.d.ts.map +0 -1
- package/dist/checks/ai-catalog.js +0 -254
- package/dist/checks/ai-catalog.js.map +0 -1
- package/dist/checks/ai-directives.d.ts +0 -57
- package/dist/checks/ai-directives.d.ts.map +0 -1
- package/dist/checks/ai-directives.js +0 -263
- package/dist/checks/ai-directives.js.map +0 -1
- package/dist/checks/api-discovery.d.ts +0 -26
- package/dist/checks/api-discovery.d.ts.map +0 -1
- package/dist/checks/api-discovery.js +0 -432
- package/dist/checks/api-discovery.js.map +0 -1
- package/dist/checks/auth-discovery.d.ts +0 -28
- package/dist/checks/auth-discovery.d.ts.map +0 -1
- package/dist/checks/auth-discovery.js +0 -302
- package/dist/checks/auth-discovery.js.map +0 -1
- package/dist/checks/commerce-discovery.d.ts +0 -40
- package/dist/checks/commerce-discovery.d.ts.map +0 -1
- package/dist/checks/commerce-discovery.js +0 -295
- package/dist/checks/commerce-discovery.js.map +0 -1
- package/dist/checks/content-negotiation.d.ts +0 -4
- package/dist/checks/content-negotiation.d.ts.map +0 -1
- package/dist/checks/content-negotiation.js +0 -253
- package/dist/checks/content-negotiation.js.map +0 -1
- package/dist/checks/crawl-efficiency.d.ts +0 -16
- package/dist/checks/crawl-efficiency.d.ts.map +0 -1
- package/dist/checks/crawl-efficiency.js +0 -186
- package/dist/checks/crawl-efficiency.js.map +0 -1
- package/dist/checks/frontmatter.d.ts +0 -34
- package/dist/checks/frontmatter.d.ts.map +0 -1
- package/dist/checks/frontmatter.js +0 -100
- package/dist/checks/frontmatter.js.map +0 -1
- package/dist/checks/html-rendering.d.ts +0 -21
- package/dist/checks/html-rendering.d.ts.map +0 -1
- package/dist/checks/html-rendering.js +0 -221
- package/dist/checks/html-rendering.js.map +0 -1
- package/dist/checks/html-utils.d.ts +0 -66
- package/dist/checks/html-utils.d.ts.map +0 -1
- package/dist/checks/html-utils.js +0 -139
- package/dist/checks/html-utils.js.map +0 -1
- package/dist/checks/http-headers.d.ts +0 -11
- package/dist/checks/http-headers.d.ts.map +0 -1
- package/dist/checks/http-headers.js +0 -249
- package/dist/checks/http-headers.js.map +0 -1
- package/dist/checks/http-hygiene.d.ts +0 -26
- package/dist/checks/http-hygiene.d.ts.map +0 -1
- package/dist/checks/http-hygiene.js +0 -257
- package/dist/checks/http-hygiene.js.map +0 -1
- package/dist/checks/index.d.ts +0 -3
- package/dist/checks/index.d.ts.map +0 -1
- package/dist/checks/index.js +0 -55
- package/dist/checks/index.js.map +0 -1
- package/dist/checks/llms-txt.d.ts +0 -19
- package/dist/checks/llms-txt.d.ts.map +0 -1
- package/dist/checks/llms-txt.js +0 -281
- package/dist/checks/llms-txt.js.map +0 -1
- package/dist/checks/mcp-discovery.d.ts +0 -30
- package/dist/checks/mcp-discovery.d.ts.map +0 -1
- package/dist/checks/mcp-discovery.js +0 -523
- package/dist/checks/mcp-discovery.js.map +0 -1
- package/dist/checks/meta-tags.d.ts +0 -17
- package/dist/checks/meta-tags.d.ts.map +0 -1
- package/dist/checks/meta-tags.js +0 -188
- package/dist/checks/meta-tags.js.map +0 -1
- package/dist/checks/robots-parser.d.ts +0 -110
- package/dist/checks/robots-parser.d.ts.map +0 -1
- package/dist/checks/robots-parser.js +0 -277
- package/dist/checks/robots-parser.js.map +0 -1
- package/dist/checks/robots-txt.d.ts +0 -6
- package/dist/checks/robots-txt.d.ts.map +0 -1
- package/dist/checks/robots-txt.js +0 -367
- package/dist/checks/robots-txt.js.map +0 -1
- package/dist/checks/rsl.d.ts +0 -4
- package/dist/checks/rsl.d.ts.map +0 -1
- package/dist/checks/rsl.js +0 -242
- package/dist/checks/rsl.js.map +0 -1
- package/dist/checks/security-txt.d.ts +0 -4
- package/dist/checks/security-txt.d.ts.map +0 -1
- package/dist/checks/security-txt.js +0 -81
- package/dist/checks/security-txt.js.map +0 -1
- package/dist/checks/seo-basics.d.ts +0 -13
- package/dist/checks/seo-basics.d.ts.map +0 -1
- package/dist/checks/seo-basics.js +0 -221
- package/dist/checks/seo-basics.js.map +0 -1
- package/dist/checks/sitemap.d.ts +0 -12
- package/dist/checks/sitemap.d.ts.map +0 -1
- package/dist/checks/sitemap.js +0 -240
- package/dist/checks/sitemap.js.map +0 -1
- package/dist/checks/structured-data.d.ts +0 -4
- package/dist/checks/structured-data.d.ts.map +0 -1
- package/dist/checks/structured-data.js +0 -408
- package/dist/checks/structured-data.js.map +0 -1
- package/dist/checks/structured-fields.d.ts +0 -46
- package/dist/checks/structured-fields.d.ts.map +0 -1
- package/dist/checks/structured-fields.js +0 -112
- package/dist/checks/structured-fields.js.map +0 -1
- package/dist/checks/surface.d.ts +0 -59
- package/dist/checks/surface.d.ts.map +0 -1
- package/dist/checks/surface.js +0 -106
- package/dist/checks/surface.js.map +0 -1
- package/dist/checks/tls-https.d.ts +0 -13
- package/dist/checks/tls-https.d.ts.map +0 -1
- package/dist/checks/tls-https.js +0 -163
- package/dist/checks/tls-https.js.map +0 -1
- package/dist/checks/usage-policy.d.ts +0 -53
- package/dist/checks/usage-policy.d.ts.map +0 -1
- package/dist/checks/usage-policy.js +0 -339
- package/dist/checks/usage-policy.js.map +0 -1
- package/dist/checks/utils.d.ts +0 -40
- package/dist/checks/utils.d.ts.map +0 -1
- package/dist/checks/utils.js +0 -74
- package/dist/checks/utils.js.map +0 -1
- package/dist/checks/waf.d.ts +0 -75
- package/dist/checks/waf.d.ts.map +0 -1
- package/dist/checks/waf.js +0 -203
- package/dist/checks/waf.js.map +0 -1
- package/dist/checks/webmcp.d.ts +0 -55
- package/dist/checks/webmcp.d.ts.map +0 -1
- package/dist/checks/webmcp.js +0 -209
- package/dist/checks/webmcp.js.map +0 -1
- package/dist/checks/well-known.d.ts +0 -38
- package/dist/checks/well-known.d.ts.map +0 -1
- package/dist/checks/well-known.js +0 -202
- package/dist/checks/well-known.js.map +0 -1
- package/dist/fetcher.d.ts +0 -15
- package/dist/fetcher.d.ts.map +0 -1
- package/dist/fetcher.js +0 -127
- package/dist/fetcher.js.map +0 -1
- package/dist/guide-urls.d.ts +0 -2
- package/dist/guide-urls.d.ts.map +0 -1
- package/dist/guide-urls.js +0 -5
- package/dist/guide-urls.js.map +0 -1
- package/docs/roadmap.md +0 -367
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* "llms-txt" — the curated index a site publishes for language models.
|
|
4
|
-
*
|
|
5
|
-
* Two things are worth being honest about in the report. Google has stated
|
|
6
|
-
* plainly that Search ignores llms.txt, and adoption studies find the large
|
|
7
|
-
* majority of published files are never fetched by any AI search crawler. The
|
|
8
|
-
* consumers that *do* read it are coding agents — Claude Code, Cursor,
|
|
9
|
-
* OpenCode — which makes it a developer-tooling signal rather than a search
|
|
10
|
-
* visibility one. A report that implies otherwise is selling something.
|
|
11
|
-
*
|
|
12
|
-
* The specification was revised in 2026 ("v2"), adding three things this check
|
|
13
|
-
* now looks for: files scoped to a subpath, a `describedby` link relation
|
|
14
|
-
* pointing a page at the file that covers it, and per-page Markdown mirrors
|
|
15
|
-
* reached by appending `.md`.
|
|
16
|
-
*/
|
|
17
|
-
export declare const meta: CheckMeta;
|
|
18
|
-
export default function check(ctx: CheckContext): Promise<CheckResult>;
|
|
19
|
-
//# sourceMappingURL=llms-txt.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"llms-txt.d.ts","sourceRoot":"","sources":["../../src/checks/llms-txt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAKjF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AAOF,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA6H3E"}
|
package/dist/checks/llms-txt.js
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
import { guideUrl } from '../guide-urls.js';
|
|
2
|
-
import { buildResult, checkContentType } from './utils.js';
|
|
3
|
-
import { findLinkTags } from './html-utils.js';
|
|
4
|
-
import { parseLinkHeader } from './http-headers.js';
|
|
5
|
-
/**
|
|
6
|
-
* "llms-txt" — the curated index a site publishes for language models.
|
|
7
|
-
*
|
|
8
|
-
* Two things are worth being honest about in the report. Google has stated
|
|
9
|
-
* plainly that Search ignores llms.txt, and adoption studies find the large
|
|
10
|
-
* majority of published files are never fetched by any AI search crawler. The
|
|
11
|
-
* consumers that *do* read it are coding agents — Claude Code, Cursor,
|
|
12
|
-
* OpenCode — which makes it a developer-tooling signal rather than a search
|
|
13
|
-
* visibility one. A report that implies otherwise is selling something.
|
|
14
|
-
*
|
|
15
|
-
* The specification was revised in 2026 ("v2"), adding three things this check
|
|
16
|
-
* now looks for: files scoped to a subpath, a `describedby` link relation
|
|
17
|
-
* pointing a page at the file that covers it, and per-page Markdown mirrors
|
|
18
|
-
* reached by appending `.md`.
|
|
19
|
-
*/
|
|
20
|
-
export const meta = {
|
|
21
|
-
id: 'llms-txt',
|
|
22
|
-
name: 'LLMs.txt',
|
|
23
|
-
description: 'Checks /llms.txt presence, spec compliance, and link health',
|
|
24
|
-
category: 'discovery',
|
|
25
|
-
};
|
|
26
|
-
/** How many links to sample for liveness. Enough to catch rot without a crawl. */
|
|
27
|
-
const LINK_SAMPLE_SIZE = 15;
|
|
28
|
-
/** A file larger than this is unlikely to fit an agent's context budget usefully. */
|
|
29
|
-
const LARGE_FILE_BYTES = 50_000;
|
|
30
|
-
export default async function check(ctx) {
|
|
31
|
-
const start = performance.now();
|
|
32
|
-
const findings = [];
|
|
33
|
-
let score = 100;
|
|
34
|
-
const res = await ctx.fetch(`${ctx.url}/llms.txt`);
|
|
35
|
-
if (!res.ok) {
|
|
36
|
-
findings.push({
|
|
37
|
-
status: 'fail',
|
|
38
|
-
message: '/llms.txt not found',
|
|
39
|
-
detail: `HTTP ${res.status || 'network error'}`,
|
|
40
|
-
hint: 'Create a /llms.txt file at your site root following the llmstxt.org specification. It should be a Markdown file starting with "# Your Site Name" and include a description, sections, and links.',
|
|
41
|
-
learnMoreUrl: guideUrl(meta.id, 'not-found'),
|
|
42
|
-
});
|
|
43
|
-
return buildResult(meta, 0, findings, start);
|
|
44
|
-
}
|
|
45
|
-
findings.push({ status: 'pass', message: '/llms.txt exists' });
|
|
46
|
-
const ctFinding = checkContentType(res, ['text/plain', 'text/markdown'], {
|
|
47
|
-
checkId: meta.id,
|
|
48
|
-
resourceLabel: '/llms.txt',
|
|
49
|
-
anchor: 'wrong-content-type',
|
|
50
|
-
});
|
|
51
|
-
if (ctFinding) {
|
|
52
|
-
findings.push(ctFinding);
|
|
53
|
-
score -= 5;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
findings.push({
|
|
57
|
-
status: 'pass',
|
|
58
|
-
message: `/llms.txt Content-Type OK (${res.headers['content-type']?.split(';')[0]})`,
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
const text = res.body;
|
|
62
|
-
const lines = text
|
|
63
|
-
.split('\n')
|
|
64
|
-
.map((l) => l.trim())
|
|
65
|
-
.filter(Boolean);
|
|
66
|
-
if (!lines[0]?.startsWith('# ')) {
|
|
67
|
-
findings.push({
|
|
68
|
-
status: 'warn',
|
|
69
|
-
message: 'Missing H1 heading (first line should start with "# ")',
|
|
70
|
-
hint: 'Add an H1 heading as the first line of your llms.txt file, e.g.: # Your Site Name',
|
|
71
|
-
learnMoreUrl: guideUrl(meta.id, 'missing-h1'),
|
|
72
|
-
});
|
|
73
|
-
score -= 15;
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
findings.push({ status: 'pass', message: `H1 heading: "${lines[0].slice(2)}"` });
|
|
77
|
-
}
|
|
78
|
-
const hasBlockquote = lines.some((l) => l.startsWith('> '));
|
|
79
|
-
if (!hasBlockquote) {
|
|
80
|
-
findings.push({
|
|
81
|
-
status: 'warn',
|
|
82
|
-
message: 'No blockquote description found ("> ...")',
|
|
83
|
-
hint: 'Add a blockquote description after the H1 heading, e.g.: > A brief summary of your site for AI agents.',
|
|
84
|
-
learnMoreUrl: guideUrl(meta.id, 'missing-blockquote'),
|
|
85
|
-
});
|
|
86
|
-
score -= 10;
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
findings.push({ status: 'pass', message: 'Blockquote description present' });
|
|
90
|
-
}
|
|
91
|
-
const sections = lines.filter((l) => l.startsWith('## '));
|
|
92
|
-
if (sections.length === 0) {
|
|
93
|
-
findings.push({
|
|
94
|
-
status: 'warn',
|
|
95
|
-
message: 'No section headings found (## ...)',
|
|
96
|
-
hint: 'Organize your llms.txt content with ## section headings (e.g., ## About, ## API, ## Documentation).',
|
|
97
|
-
learnMoreUrl: guideUrl(meta.id, 'missing-sections'),
|
|
98
|
-
});
|
|
99
|
-
score -= 10;
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
findings.push({ status: 'pass', message: `${sections.length} section heading(s) found` });
|
|
103
|
-
}
|
|
104
|
-
const linkPattern = /\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g;
|
|
105
|
-
const links = [...text.matchAll(linkPattern)];
|
|
106
|
-
if (links.length === 0) {
|
|
107
|
-
findings.push({
|
|
108
|
-
status: 'warn',
|
|
109
|
-
message: 'No Markdown links found',
|
|
110
|
-
hint: 'Add Markdown links to relevant pages: [Page Title](https://example.com/page). This helps AI agents navigate your site.',
|
|
111
|
-
learnMoreUrl: guideUrl(meta.id, 'no-links'),
|
|
112
|
-
});
|
|
113
|
-
score -= 10;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
findings.push({ status: 'pass', message: `${links.length} link(s) found` });
|
|
117
|
-
}
|
|
118
|
-
if (text.length < 100) {
|
|
119
|
-
findings.push({
|
|
120
|
-
status: 'warn',
|
|
121
|
-
message: 'Content appears minimal (< 100 characters)',
|
|
122
|
-
hint: 'Expand your llms.txt with more descriptive content about your site, its purpose, and available resources.',
|
|
123
|
-
learnMoreUrl: guideUrl(meta.id, 'minimal-content'),
|
|
124
|
-
});
|
|
125
|
-
score -= 10;
|
|
126
|
-
}
|
|
127
|
-
const fullRes = await ctx.fetch(`${ctx.url}/llms-full.txt`);
|
|
128
|
-
if (fullRes.ok) {
|
|
129
|
-
findings.push({ status: 'pass', message: '/llms-full.txt also available (bonus)' });
|
|
130
|
-
score = Math.min(100, score + 10);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
findings.push({
|
|
134
|
-
status: 'warn',
|
|
135
|
-
message: '/llms-full.txt not found (optional but recommended)',
|
|
136
|
-
hint: 'Create a /llms-full.txt with expanded content — full documentation, API details, and comprehensive site information for AI agents.',
|
|
137
|
-
learnMoreUrl: guideUrl(meta.id, 'missing-full'),
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
// Everything below is informational in 3.x: new findings inside a weighted
|
|
141
|
-
// check must not move the score.
|
|
142
|
-
reportSize(text, findings);
|
|
143
|
-
reportDescribedBy(ctx, findings);
|
|
144
|
-
await reportLinkHealth(ctx, links, findings);
|
|
145
|
-
await reportMarkdownMirror(ctx, findings);
|
|
146
|
-
reportConsumers(findings);
|
|
147
|
-
return buildResult(meta, score, findings, start);
|
|
148
|
-
}
|
|
149
|
-
/* ── llms.txt v2 additions and link health (informational in 3.x) ───────── */
|
|
150
|
-
/** A file too large to be read whole is a file an agent truncates. */
|
|
151
|
-
function reportSize(text, findings) {
|
|
152
|
-
const bytes = Buffer.byteLength(text, 'utf-8');
|
|
153
|
-
if (bytes <= LARGE_FILE_BYTES)
|
|
154
|
-
return;
|
|
155
|
-
findings.push({
|
|
156
|
-
status: 'warn',
|
|
157
|
-
message: `/llms.txt is ${Math.round(bytes / 1024)} KB`,
|
|
158
|
-
hint: 'An index this large competes with the content it points at for context budget. Keep llms.txt to a map of links ' +
|
|
159
|
-
'and move the prose into llms-full.txt or the pages themselves.',
|
|
160
|
-
learnMoreUrl: guideUrl(meta.id, 'large-file'),
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* llms.txt v2 added a `describedby` relation so a page can point at the file
|
|
165
|
-
* covering it. Without it, an agent that landed deep in the site has to guess
|
|
166
|
-
* that a root llms.txt exists.
|
|
167
|
-
*/
|
|
168
|
-
function reportDescribedBy(ctx, findings) {
|
|
169
|
-
const inHeader = parseLinkHeader(ctx.headers?.['link'] ?? '').some((entry) => (entry.params['rel'] ?? '').split(/\s+/).includes('describedby'));
|
|
170
|
-
const inHtml = findLinkTags(ctx.html ?? '', 'describedby').length > 0;
|
|
171
|
-
if (inHeader || inHtml) {
|
|
172
|
-
findings.push({
|
|
173
|
-
status: 'pass',
|
|
174
|
-
message: `Pages point at their llms.txt via rel="describedby" (${inHeader ? 'Link header' : 'HTML link'})`,
|
|
175
|
-
});
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
findings.push({
|
|
179
|
-
status: 'warn',
|
|
180
|
-
message: 'No rel="describedby" link to llms.txt',
|
|
181
|
-
hint: 'llms.txt v2 uses this relation so a page can name the file that covers it. Add ' +
|
|
182
|
-
'<link rel="describedby" href="/llms.txt"> or the equivalent Link header, so an agent that landed on a deep ' +
|
|
183
|
-
'page does not have to guess that an index exists.',
|
|
184
|
-
learnMoreUrl: guideUrl(meta.id, 'no-describedby'),
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Sample the links and report the dead ones. An index of broken links is the
|
|
189
|
-
* failure mode this file is most prone to: it is written once and never
|
|
190
|
-
* revalidated, while the site moves underneath it.
|
|
191
|
-
*/
|
|
192
|
-
async function reportLinkHealth(ctx, links, findings) {
|
|
193
|
-
const urls = [...new Set(links.map((m) => m[2]))];
|
|
194
|
-
if (urls.length === 0)
|
|
195
|
-
return;
|
|
196
|
-
const duplicates = links.length - urls.length;
|
|
197
|
-
if (duplicates > 0) {
|
|
198
|
-
findings.push({
|
|
199
|
-
status: 'warn',
|
|
200
|
-
message: `${duplicates} duplicate link(s) in llms.txt`,
|
|
201
|
-
hint: 'Each URL should appear once. Duplicates spend an agent’s budget re-reading what it already has.',
|
|
202
|
-
learnMoreUrl: guideUrl(meta.id, 'duplicate-links'),
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
const sample = urls.slice(0, LINK_SAMPLE_SIZE);
|
|
206
|
-
const dead = [];
|
|
207
|
-
const redirected = [];
|
|
208
|
-
for (const url of sample) {
|
|
209
|
-
const head = await ctx.fetch(url, { method: 'HEAD', redirect: 'manual' });
|
|
210
|
-
// Some origins refuse HEAD; a GET settles it rather than reporting a live
|
|
211
|
-
// page as dead.
|
|
212
|
-
const res = head.status === 405 || head.status === 501 ? await ctx.fetch(url, { redirect: 'manual' }) : head;
|
|
213
|
-
if (res.status >= 300 && res.status < 400) {
|
|
214
|
-
redirected.push(`${url} → ${res.redirectLocation ?? '(no Location)'}`);
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
if (!res.ok)
|
|
218
|
-
dead.push(`${url} (HTTP ${res.status || 'network error'})`);
|
|
219
|
-
}
|
|
220
|
-
if (dead.length > 0) {
|
|
221
|
-
findings.push({
|
|
222
|
-
status: 'fail',
|
|
223
|
-
message: `${dead.length}/${sample.length} sampled llms.txt link(s) are broken`,
|
|
224
|
-
detail: dead.join('\n'),
|
|
225
|
-
hint: 'An index of dead links wastes exactly the budget it was meant to save, and an agent has no way to tell a ' +
|
|
226
|
-
'moved page from a removed one. Revalidate llms.txt when you move pages.',
|
|
227
|
-
learnMoreUrl: guideUrl(meta.id, 'broken-links'),
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
else {
|
|
231
|
-
findings.push({ status: 'pass', message: `${sample.length} sampled link(s) resolve` });
|
|
232
|
-
}
|
|
233
|
-
if (redirected.length > 0) {
|
|
234
|
-
findings.push({
|
|
235
|
-
status: 'warn',
|
|
236
|
-
message: `${redirected.length} sampled link(s) redirect`,
|
|
237
|
-
detail: redirected.join('\n'),
|
|
238
|
-
hint: 'Point llms.txt at the final URL. Each redirect is a round trip the agent pays for on every visit.',
|
|
239
|
-
learnMoreUrl: guideUrl(meta.id, 'redirecting-links'),
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* llms.txt v2 documents per-page Markdown mirrors reached by appending `.md`.
|
|
245
|
-
* They matter more than the index itself: an agent that found a page still has
|
|
246
|
-
* to read it, and the HTML costs several times the tokens.
|
|
247
|
-
*/
|
|
248
|
-
async function reportMarkdownMirror(ctx, findings) {
|
|
249
|
-
for (const path of ['/index.md', '/index.html.md']) {
|
|
250
|
-
const res = await ctx.fetch(`${ctx.url}${path}`);
|
|
251
|
-
if (!res.ok || res.body.trim().length === 0)
|
|
252
|
-
continue;
|
|
253
|
-
if (/^\s*(?:<!doctype\s+html|<html[\s>])/i.test(res.body))
|
|
254
|
-
continue;
|
|
255
|
-
findings.push({
|
|
256
|
-
status: 'pass',
|
|
257
|
-
message: `Per-page Markdown mirror available at ${path}`,
|
|
258
|
-
detail: 'Agents that cannot negotiate on Accept can still read the cheap representation.',
|
|
259
|
-
});
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
findings.push({
|
|
263
|
-
status: 'warn',
|
|
264
|
-
message: 'No per-page Markdown mirror found',
|
|
265
|
-
detail: 'Tried /index.md and /index.html.md.',
|
|
266
|
-
hint: 'llms.txt v2 documents appending .md to a URL for its Markdown version. The index tells an agent which pages ' +
|
|
267
|
-
'exist; the mirrors are what make reading them cheap.',
|
|
268
|
-
learnMoreUrl: guideUrl(meta.id, 'no-markdown-mirror'),
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
/** State plainly who reads this file, so nobody over-invests on the wrong premise. */
|
|
272
|
-
function reportConsumers(findings) {
|
|
273
|
-
findings.push({
|
|
274
|
-
status: 'pass',
|
|
275
|
-
message: 'Consumer note: llms.txt is read by coding agents, not by search',
|
|
276
|
-
detail: 'Google has stated that Search ignores llms.txt, and adoption studies find most published files are never ' +
|
|
277
|
-
'fetched by an AI search crawler. Claude Code, Cursor and OpenCode do fetch it. Treat it as developer tooling, ' +
|
|
278
|
-
'not as a search-visibility signal.',
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
//# sourceMappingURL=llms-txt.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"llms-txt.js","sourceRoot":"","sources":["../../src/checks/llms-txt.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* "mcp-discovery" — how an agent finds this site's MCP server.
|
|
4
|
-
*
|
|
5
|
-
* ax-audit used to look for `/.well-known/mcp.json` and validate a `tools[]`
|
|
6
|
-
* array inside it. That path was never part of the Model Context Protocol
|
|
7
|
-
* specification — it was a plausible-looking convention that several tools,
|
|
8
|
-
* this one included, recommended before the ecosystem settled. Advertising
|
|
9
|
-
* static tool lists was the wrong idea anyway: tools come from a live
|
|
10
|
-
* `tools/list` call, and a copy in a static file starts drifting the day it is
|
|
11
|
-
* written.
|
|
12
|
-
*
|
|
13
|
-
* What actually emerged is the **server card**: a small document identifying
|
|
14
|
-
* the server and listing its remote endpoints, deliberately without tools.
|
|
15
|
-
* SEP-2127 and the `experimental-ext-server-card` repository recommend serving
|
|
16
|
-
* it at `<streamable-http-url>/server-card`, or referencing it from
|
|
17
|
-
* `/.well-known/ai-catalog.json`. Cloudflare and Mintlify serve one at
|
|
18
|
-
* `/.well-known/mcp/server-card.json`.
|
|
19
|
-
*
|
|
20
|
-
* All of that is still draft, and drafts get renamed — so this check probes the
|
|
21
|
-
* whole chain, labels each hit with its standing, and never treats one draft
|
|
22
|
-
* path as the single correct answer.
|
|
23
|
-
*
|
|
24
|
-
* Scoring note for 3.x: a site whose only MCP document is the legacy
|
|
25
|
-
* `/.well-known/mcp.json` is validated with the pre-3.7 rules, so its score is
|
|
26
|
-
* exactly what 3.6 produced. The path itself is reported, not penalised.
|
|
27
|
-
*/
|
|
28
|
-
export declare const meta: CheckMeta;
|
|
29
|
-
export default function check(ctx: CheckContext): Promise<CheckResult>;
|
|
30
|
-
//# sourceMappingURL=mcp-discovery.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-discovery.d.ts","sourceRoot":"","sources":["../../src/checks/mcp-discovery.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAA0B,MAAM,aAAa,CAAC;AAKhG;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,IAAI,EAAE,SAMlB,CAAC;AAqFF,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2D3E"}
|