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.
Files changed (188) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +39 -4
  3. package/dist/baseline.js +1 -1
  4. package/dist/baseline.js.map +1 -1
  5. package/dist/check-ids.js +1 -1
  6. package/dist/check-ids.js.map +1 -1
  7. package/dist/cli.js +1 -1
  8. package/dist/cli.js.map +1 -1
  9. package/dist/constants.d.ts +1 -85
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/constants.js +0 -135
  12. package/dist/constants.js.map +1 -1
  13. package/dist/index.d.ts +3 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +2 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/license.d.ts +8 -0
  18. package/dist/license.d.ts.map +1 -0
  19. package/dist/license.js +18 -0
  20. package/dist/license.js.map +1 -0
  21. package/dist/metadata.d.ts +6 -0
  22. package/dist/metadata.d.ts.map +1 -0
  23. package/dist/metadata.js +205 -0
  24. package/dist/metadata.js.map +1 -0
  25. package/dist/orchestrator.d.ts +1 -0
  26. package/dist/orchestrator.d.ts.map +1 -1
  27. package/dist/orchestrator.js +134 -56
  28. package/dist/orchestrator.js.map +1 -1
  29. package/dist/scorer.js +2 -2
  30. package/dist/scorer.js.map +1 -1
  31. package/dist/types.d.ts +4 -0
  32. package/dist/types.d.ts.map +1 -1
  33. package/docs/api.md +14 -3
  34. package/docs/architecture.md +9 -98
  35. package/docs/ci.md +19 -0
  36. package/docs/cli.md +11 -0
  37. package/docs/faq.md +18 -0
  38. package/docs/getting-started.md +33 -1
  39. package/package.json +5 -5
  40. package/dist/checks/agent-access.d.ts +0 -33
  41. package/dist/checks/agent-access.d.ts.map +0 -1
  42. package/dist/checks/agent-access.js +0 -256
  43. package/dist/checks/agent-access.js.map +0 -1
  44. package/dist/checks/agent-card.d.ts +0 -37
  45. package/dist/checks/agent-card.d.ts.map +0 -1
  46. package/dist/checks/agent-card.js +0 -352
  47. package/dist/checks/agent-card.js.map +0 -1
  48. package/dist/checks/agent-operability.d.ts +0 -66
  49. package/dist/checks/agent-operability.d.ts.map +0 -1
  50. package/dist/checks/agent-operability.js +0 -383
  51. package/dist/checks/agent-operability.js.map +0 -1
  52. package/dist/checks/agent-skills.d.ts +0 -24
  53. package/dist/checks/agent-skills.d.ts.map +0 -1
  54. package/dist/checks/agent-skills.js +0 -316
  55. package/dist/checks/agent-skills.js.map +0 -1
  56. package/dist/checks/ai-catalog.d.ts +0 -28
  57. package/dist/checks/ai-catalog.d.ts.map +0 -1
  58. package/dist/checks/ai-catalog.js +0 -254
  59. package/dist/checks/ai-catalog.js.map +0 -1
  60. package/dist/checks/ai-directives.d.ts +0 -57
  61. package/dist/checks/ai-directives.d.ts.map +0 -1
  62. package/dist/checks/ai-directives.js +0 -263
  63. package/dist/checks/ai-directives.js.map +0 -1
  64. package/dist/checks/api-discovery.d.ts +0 -26
  65. package/dist/checks/api-discovery.d.ts.map +0 -1
  66. package/dist/checks/api-discovery.js +0 -432
  67. package/dist/checks/api-discovery.js.map +0 -1
  68. package/dist/checks/auth-discovery.d.ts +0 -28
  69. package/dist/checks/auth-discovery.d.ts.map +0 -1
  70. package/dist/checks/auth-discovery.js +0 -302
  71. package/dist/checks/auth-discovery.js.map +0 -1
  72. package/dist/checks/commerce-discovery.d.ts +0 -40
  73. package/dist/checks/commerce-discovery.d.ts.map +0 -1
  74. package/dist/checks/commerce-discovery.js +0 -295
  75. package/dist/checks/commerce-discovery.js.map +0 -1
  76. package/dist/checks/content-negotiation.d.ts +0 -4
  77. package/dist/checks/content-negotiation.d.ts.map +0 -1
  78. package/dist/checks/content-negotiation.js +0 -253
  79. package/dist/checks/content-negotiation.js.map +0 -1
  80. package/dist/checks/crawl-efficiency.d.ts +0 -16
  81. package/dist/checks/crawl-efficiency.d.ts.map +0 -1
  82. package/dist/checks/crawl-efficiency.js +0 -186
  83. package/dist/checks/crawl-efficiency.js.map +0 -1
  84. package/dist/checks/frontmatter.d.ts +0 -34
  85. package/dist/checks/frontmatter.d.ts.map +0 -1
  86. package/dist/checks/frontmatter.js +0 -100
  87. package/dist/checks/frontmatter.js.map +0 -1
  88. package/dist/checks/html-rendering.d.ts +0 -21
  89. package/dist/checks/html-rendering.d.ts.map +0 -1
  90. package/dist/checks/html-rendering.js +0 -221
  91. package/dist/checks/html-rendering.js.map +0 -1
  92. package/dist/checks/html-utils.d.ts +0 -66
  93. package/dist/checks/html-utils.d.ts.map +0 -1
  94. package/dist/checks/html-utils.js +0 -139
  95. package/dist/checks/html-utils.js.map +0 -1
  96. package/dist/checks/http-headers.d.ts +0 -11
  97. package/dist/checks/http-headers.d.ts.map +0 -1
  98. package/dist/checks/http-headers.js +0 -249
  99. package/dist/checks/http-headers.js.map +0 -1
  100. package/dist/checks/http-hygiene.d.ts +0 -26
  101. package/dist/checks/http-hygiene.d.ts.map +0 -1
  102. package/dist/checks/http-hygiene.js +0 -257
  103. package/dist/checks/http-hygiene.js.map +0 -1
  104. package/dist/checks/index.d.ts +0 -3
  105. package/dist/checks/index.d.ts.map +0 -1
  106. package/dist/checks/index.js +0 -55
  107. package/dist/checks/index.js.map +0 -1
  108. package/dist/checks/llms-txt.d.ts +0 -19
  109. package/dist/checks/llms-txt.d.ts.map +0 -1
  110. package/dist/checks/llms-txt.js +0 -281
  111. package/dist/checks/llms-txt.js.map +0 -1
  112. package/dist/checks/mcp-discovery.d.ts +0 -30
  113. package/dist/checks/mcp-discovery.d.ts.map +0 -1
  114. package/dist/checks/mcp-discovery.js +0 -523
  115. package/dist/checks/mcp-discovery.js.map +0 -1
  116. package/dist/checks/meta-tags.d.ts +0 -17
  117. package/dist/checks/meta-tags.d.ts.map +0 -1
  118. package/dist/checks/meta-tags.js +0 -188
  119. package/dist/checks/meta-tags.js.map +0 -1
  120. package/dist/checks/robots-parser.d.ts +0 -110
  121. package/dist/checks/robots-parser.d.ts.map +0 -1
  122. package/dist/checks/robots-parser.js +0 -277
  123. package/dist/checks/robots-parser.js.map +0 -1
  124. package/dist/checks/robots-txt.d.ts +0 -6
  125. package/dist/checks/robots-txt.d.ts.map +0 -1
  126. package/dist/checks/robots-txt.js +0 -367
  127. package/dist/checks/robots-txt.js.map +0 -1
  128. package/dist/checks/rsl.d.ts +0 -4
  129. package/dist/checks/rsl.d.ts.map +0 -1
  130. package/dist/checks/rsl.js +0 -242
  131. package/dist/checks/rsl.js.map +0 -1
  132. package/dist/checks/security-txt.d.ts +0 -4
  133. package/dist/checks/security-txt.d.ts.map +0 -1
  134. package/dist/checks/security-txt.js +0 -81
  135. package/dist/checks/security-txt.js.map +0 -1
  136. package/dist/checks/seo-basics.d.ts +0 -13
  137. package/dist/checks/seo-basics.d.ts.map +0 -1
  138. package/dist/checks/seo-basics.js +0 -221
  139. package/dist/checks/seo-basics.js.map +0 -1
  140. package/dist/checks/sitemap.d.ts +0 -12
  141. package/dist/checks/sitemap.d.ts.map +0 -1
  142. package/dist/checks/sitemap.js +0 -240
  143. package/dist/checks/sitemap.js.map +0 -1
  144. package/dist/checks/structured-data.d.ts +0 -4
  145. package/dist/checks/structured-data.d.ts.map +0 -1
  146. package/dist/checks/structured-data.js +0 -408
  147. package/dist/checks/structured-data.js.map +0 -1
  148. package/dist/checks/structured-fields.d.ts +0 -46
  149. package/dist/checks/structured-fields.d.ts.map +0 -1
  150. package/dist/checks/structured-fields.js +0 -112
  151. package/dist/checks/structured-fields.js.map +0 -1
  152. package/dist/checks/surface.d.ts +0 -59
  153. package/dist/checks/surface.d.ts.map +0 -1
  154. package/dist/checks/surface.js +0 -106
  155. package/dist/checks/surface.js.map +0 -1
  156. package/dist/checks/tls-https.d.ts +0 -13
  157. package/dist/checks/tls-https.d.ts.map +0 -1
  158. package/dist/checks/tls-https.js +0 -163
  159. package/dist/checks/tls-https.js.map +0 -1
  160. package/dist/checks/usage-policy.d.ts +0 -53
  161. package/dist/checks/usage-policy.d.ts.map +0 -1
  162. package/dist/checks/usage-policy.js +0 -339
  163. package/dist/checks/usage-policy.js.map +0 -1
  164. package/dist/checks/utils.d.ts +0 -40
  165. package/dist/checks/utils.d.ts.map +0 -1
  166. package/dist/checks/utils.js +0 -74
  167. package/dist/checks/utils.js.map +0 -1
  168. package/dist/checks/waf.d.ts +0 -75
  169. package/dist/checks/waf.d.ts.map +0 -1
  170. package/dist/checks/waf.js +0 -203
  171. package/dist/checks/waf.js.map +0 -1
  172. package/dist/checks/webmcp.d.ts +0 -55
  173. package/dist/checks/webmcp.d.ts.map +0 -1
  174. package/dist/checks/webmcp.js +0 -209
  175. package/dist/checks/webmcp.js.map +0 -1
  176. package/dist/checks/well-known.d.ts +0 -38
  177. package/dist/checks/well-known.d.ts.map +0 -1
  178. package/dist/checks/well-known.js +0 -202
  179. package/dist/checks/well-known.js.map +0 -1
  180. package/dist/fetcher.d.ts +0 -15
  181. package/dist/fetcher.d.ts.map +0 -1
  182. package/dist/fetcher.js +0 -127
  183. package/dist/fetcher.js.map +0 -1
  184. package/dist/guide-urls.d.ts +0 -2
  185. package/dist/guide-urls.d.ts.map +0 -1
  186. package/dist/guide-urls.js +0 -5
  187. package/dist/guide-urls.js.map +0 -1
  188. package/docs/roadmap.md +0 -367
@@ -1,316 +0,0 @@
1
- import { guideUrl } from '../guide-urls.js';
2
- import { buildResult, isHtmlDocument, notApplicable } from './utils.js';
3
- import { parseFrontmatter } from './frontmatter.js';
4
- import { standingNote } from './well-known.js';
5
- import { hasDocsSurface } from './surface.js';
6
- /**
7
- * "agent-skills" — procedural instructions an agent can install, rather than
8
- * prose it has to infer from.
9
- *
10
- * llms.txt answers "what is on this site". A skill answers "how do I do the
11
- * thing this site is for" — the setup steps, the argument shapes, the mistakes
12
- * to avoid — in a format a coding agent installs and follows. For a
13
- * documentation site or a developer tool, that is the difference between an
14
- * agent reading about your API and an agent using it correctly.
15
- *
16
- * Discovery has not settled. Cloudflare's RFC specifies
17
- * `/.well-known/agent-skills/index.json`; Mintlify and Docus ship the shorter
18
- * `/.well-known/skills/index.json`; a single-skill site may just serve
19
- * `/skill.md`. All three are probed.
20
- *
21
- * The check is conditional. A restaurant's website has no skills to publish,
22
- * and scoring it zero would say something false. It reports N/A unless the site
23
- * shows developer-facing signals — a docs section, an llms.txt, or an API
24
- * description — in which case a missing skills index is worth mentioning.
25
- */
26
- export const meta = {
27
- id: 'agent-skills',
28
- name: 'Agent Skills',
29
- description: 'Checks discoverable Agent Skills (SKILL.md) and their frontmatter',
30
- category: 'protocols',
31
- };
32
- const INDEX_PATHS = ['/.well-known/agent-skills/index.json', '/.well-known/skills/index.json'];
33
- const SINGLE_SKILL_PATHS = ['/skill.md', '/SKILL.md'];
34
- /** agentskills.io: lowercase, digits and hyphens, 1–64 characters. */
35
- const SKILL_NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
36
- /** Cloudflare RFC: `sha256:` followed by 64 hex characters. */
37
- const DIGEST_RE = /^sha256:[0-9a-f]{64}$/;
38
- /** agentskills.io caps the description at 1024 characters. */
39
- const MAX_DESCRIPTION = 1024;
40
- /** The specification recommends a skill body stay under 500 lines. */
41
- const MAX_BODY_LINES = 500;
42
- /** How many SKILL.md documents to fetch and validate. */
43
- const SAMPLE_SIZE = 3;
44
- async function fetchDocument(ctx, path) {
45
- const res = await ctx.fetch(`${ctx.url}${path}`);
46
- if (!res.ok || res.body.trim().length === 0 || isHtmlDocument(res.body))
47
- return null;
48
- return res;
49
- }
50
- export default async function check(ctx) {
51
- const start = performance.now();
52
- const findings = [];
53
- for (const path of INDEX_PATHS) {
54
- const res = await fetchDocument(ctx, path);
55
- if (res !== null)
56
- return validateIndex(ctx, path, res, findings, start);
57
- }
58
- for (const path of SINGLE_SKILL_PATHS) {
59
- const res = await fetchDocument(ctx, path);
60
- if (res !== null)
61
- return validateSingleSkill(path, res, findings, start);
62
- }
63
- if (!(await hasDocsSurface(ctx)).found) {
64
- findings.push({
65
- status: 'pass',
66
- message: 'No developer-facing surface — skills do not apply to this site',
67
- detail: 'No documentation links, llms.txt, or API description found. Skills describe procedures an agent follows; a site with no procedures to teach has nothing to publish.',
68
- });
69
- return notApplicable(meta, findings, start);
70
- }
71
- findings.push({
72
- status: 'warn',
73
- message: 'No Agent Skills published',
74
- detail: `Checked ${[...INDEX_PATHS, ...SINGLE_SKILL_PATHS].join(', ')}. ${standingNote(INDEX_PATHS[0]) ?? ''}`.trim(),
75
- hint: 'This site has documentation, so it has procedures worth teaching. A skill is a SKILL.md an agent installs and ' +
76
- 'follows: setup steps, argument shapes, the mistakes to avoid. Publish one per task at ' +
77
- '/.well-known/agent-skills/{name}/SKILL.md and list them in /.well-known/agent-skills/index.json.',
78
- learnMoreUrl: guideUrl(meta.id, 'not-found'),
79
- });
80
- return buildResult(meta, 0, findings, start);
81
- }
82
- /** Validate a skills index and a sample of the skills it lists. */
83
- async function validateIndex(ctx, path, res, findings, start) {
84
- let score = 100;
85
- findings.push({
86
- status: 'pass',
87
- message: `Agent Skills index published at ${path}`,
88
- detail: standingNote(path),
89
- });
90
- let data;
91
- try {
92
- data = JSON.parse(res.body);
93
- }
94
- catch {
95
- findings.push({
96
- status: 'fail',
97
- message: `Skills index at ${path} is not valid JSON`,
98
- hint: 'Fix the JSON syntax so agents can read the index.',
99
- learnMoreUrl: guideUrl(meta.id, 'invalid-json'),
100
- });
101
- return buildResult(meta, 10, findings, start);
102
- }
103
- if (data.$schema === undefined) {
104
- findings.push({
105
- status: 'warn',
106
- message: 'Skills index declares no $schema',
107
- hint: 'Add "$schema": "https://schemas.agentskills.io/discovery/0.2.0/schema.json" so a consumer knows which revision this is.',
108
- learnMoreUrl: guideUrl(meta.id, 'no-schema'),
109
- });
110
- score -= 5;
111
- }
112
- const skills = (Array.isArray(data.skills) ? data.skills : []).map((s) => ({
113
- name: String(s.name ?? ''),
114
- description: String(s.description ?? ''),
115
- type: String(s.type ?? ''),
116
- url: typeof s.url === 'string' ? s.url : undefined,
117
- digest: typeof s.digest === 'string' ? s.digest : undefined,
118
- }));
119
- if (skills.length === 0) {
120
- findings.push({
121
- status: 'warn',
122
- message: 'Skills index lists no skills',
123
- hint: 'An empty index advertises nothing. Add an entry per skill with name, description, type and url.',
124
- learnMoreUrl: guideUrl(meta.id, 'empty-index'),
125
- });
126
- return buildResult(meta, score - 30, findings, start);
127
- }
128
- findings.push({ status: 'pass', message: `${skills.length} skill(s) listed` });
129
- score = validateEntries(skills, findings, score);
130
- score = await sampleSkillDocuments(ctx, skills, findings, score);
131
- return buildResult(meta, score, findings, start);
132
- }
133
- /** Field rules from the Cloudflare discovery RFC and the agentskills.io specification. */
134
- function validateEntries(skills, findings, score) {
135
- const badName = skills.filter((s) => !SKILL_NAME_RE.test(s.name));
136
- if (badName.length > 0) {
137
- findings.push({
138
- status: 'warn',
139
- message: `${badName.length} skill name(s) outside the allowed format`,
140
- detail: badName.map((s) => s.name || '(empty)').join(', '),
141
- hint: 'Skill names are 1–64 characters of lowercase letters, digits and hyphens, and must match the directory the skill lives in.',
142
- learnMoreUrl: guideUrl(meta.id, 'name-format'),
143
- });
144
- score -= 10;
145
- }
146
- const noDescription = skills.filter((s) => s.description.trim() === '');
147
- if (noDescription.length > 0) {
148
- findings.push({
149
- status: 'fail',
150
- message: `${noDescription.length} skill(s) have no description`,
151
- detail: noDescription.map((s) => s.name).join(', '),
152
- hint: 'The description is what an agent reads to decide whether to install a skill. Without one the skill is invisible in practice.',
153
- learnMoreUrl: guideUrl(meta.id, 'no-description'),
154
- });
155
- score -= 15;
156
- }
157
- const longDescription = skills.filter((s) => s.description.length > MAX_DESCRIPTION);
158
- if (longDescription.length > 0) {
159
- findings.push({
160
- status: 'warn',
161
- message: `${longDescription.length} skill description(s) exceed ${MAX_DESCRIPTION} characters`,
162
- hint: 'Keep the index description short enough to scan; the detail belongs in SKILL.md.',
163
- learnMoreUrl: guideUrl(meta.id, 'long-description'),
164
- });
165
- score -= 5;
166
- }
167
- const badType = skills.filter((s) => s.type !== '' && s.type !== 'skill-md' && s.type !== 'archive');
168
- if (badType.length > 0) {
169
- findings.push({
170
- status: 'warn',
171
- message: 'Skill entry with an unrecognised type',
172
- detail: [...new Set(badType.map((s) => s.type))].join(', '),
173
- hint: 'Types are "skill-md" for a single Markdown file and "archive" for a bundle.',
174
- learnMoreUrl: guideUrl(meta.id, 'type-format'),
175
- });
176
- score -= 5;
177
- }
178
- const noDigest = skills.filter((s) => s.digest === undefined);
179
- const badDigest = skills.filter((s) => s.digest !== undefined && !DIGEST_RE.test(s.digest));
180
- if (badDigest.length > 0) {
181
- findings.push({
182
- status: 'warn',
183
- message: `${badDigest.length} skill digest(s) are malformed`,
184
- detail: badDigest.map((s) => `${s.name}: ${s.digest}`).join(', '),
185
- hint: 'A digest is "sha256:" followed by 64 lowercase hex characters.',
186
- learnMoreUrl: guideUrl(meta.id, 'digest-format'),
187
- });
188
- score -= 5;
189
- }
190
- else if (noDigest.length === skills.length) {
191
- findings.push({
192
- status: 'warn',
193
- message: 'No skill declares a content digest',
194
- hint: 'A digest lets an agent verify it installed the skill you published, and notice when it changes. ' +
195
- 'Add "digest": "sha256:…" to each entry.',
196
- learnMoreUrl: guideUrl(meta.id, 'no-digest'),
197
- });
198
- score -= 5;
199
- }
200
- else if (noDigest.length === 0) {
201
- findings.push({ status: 'pass', message: 'Every skill declares a content digest' });
202
- }
203
- return score;
204
- }
205
- /** Fetch a few SKILL.md documents and validate their frontmatter against the index. */
206
- async function sampleSkillDocuments(ctx, skills, findings, score) {
207
- const sample = skills.filter((s) => s.url !== undefined).slice(0, SAMPLE_SIZE);
208
- if (sample.length === 0) {
209
- findings.push({
210
- status: 'warn',
211
- message: 'No skill entry carries a url',
212
- hint: 'Each entry needs a url pointing at its SKILL.md or archive, or an agent cannot install it.',
213
- learnMoreUrl: guideUrl(meta.id, 'no-url'),
214
- });
215
- return score - 15;
216
- }
217
- const problems = [];
218
- for (const skill of sample) {
219
- let url;
220
- try {
221
- url = new URL(skill.url, `${ctx.url}/`).toString();
222
- }
223
- catch {
224
- problems.push(`${skill.name}: url is not resolvable (${skill.url})`);
225
- continue;
226
- }
227
- const res = await ctx.fetch(url);
228
- if (!res.ok || res.body.trim().length === 0) {
229
- problems.push(`${skill.name}: ${url} returns HTTP ${res.status || 'a network error'}`);
230
- continue;
231
- }
232
- if (skill.type === 'archive')
233
- continue; // Binary bundle: nothing to parse.
234
- const { frontmatter, body, present } = parseFrontmatter(res.body);
235
- if (!present) {
236
- problems.push(`${skill.name}: SKILL.md has no YAML frontmatter`);
237
- continue;
238
- }
239
- if (frontmatter.name === undefined) {
240
- problems.push(`${skill.name}: frontmatter has no name`);
241
- }
242
- else if (frontmatter.name !== skill.name) {
243
- problems.push(`${skill.name}: frontmatter name is "${frontmatter.name}", which disagrees with the index`);
244
- }
245
- if (frontmatter.description === undefined || frontmatter.description.trim() === '') {
246
- problems.push(`${skill.name}: frontmatter has no description`);
247
- }
248
- const lines = body.split('\n').length;
249
- if (lines > MAX_BODY_LINES) {
250
- findings.push({
251
- status: 'warn',
252
- message: `Skill "${skill.name}" is ${lines} lines long`,
253
- hint: `The specification recommends keeping a skill under ${MAX_BODY_LINES} lines. Split long procedures into separate skills so an agent loads only what it needs.`,
254
- learnMoreUrl: guideUrl(meta.id, 'long-skill'),
255
- });
256
- }
257
- }
258
- if (problems.length > 0) {
259
- findings.push({
260
- status: 'fail',
261
- message: `${problems.length} problem(s) in the sampled skill document(s)`,
262
- detail: problems.join('\n'),
263
- hint: 'An index entry an agent cannot install is worse than no entry, because it is trusted before it is fetched.',
264
- learnMoreUrl: guideUrl(meta.id, 'broken-skill'),
265
- });
266
- return score - 10 * problems.length;
267
- }
268
- findings.push({ status: 'pass', message: `${sample.length} sampled skill document(s) install cleanly` });
269
- return score;
270
- }
271
- /** A site with one skill and no index still publishes something usable. */
272
- function validateSingleSkill(path, res, findings, start) {
273
- let score = 100;
274
- const { frontmatter, present } = parseFrontmatter(res.body);
275
- findings.push({ status: 'pass', message: `Skill published at ${path}` });
276
- findings.push({
277
- status: 'warn',
278
- message: 'Skill is not listed in a discovery index',
279
- hint: 'A bare /skill.md is only found by guessing. Publish /.well-known/agent-skills/index.json listing it, so an ' +
280
- 'agent discovers it the same way it discovers everything else.',
281
- learnMoreUrl: guideUrl(meta.id, 'no-index'),
282
- });
283
- score -= 20;
284
- if (!present) {
285
- findings.push({
286
- status: 'fail',
287
- message: 'SKILL.md has no YAML frontmatter',
288
- hint: 'A skill needs frontmatter with at least name and description; without it an agent cannot register the skill.',
289
- learnMoreUrl: guideUrl(meta.id, 'no-frontmatter'),
290
- });
291
- return buildResult(meta, score - 30, findings, start);
292
- }
293
- if (frontmatter.name === undefined || !SKILL_NAME_RE.test(frontmatter.name)) {
294
- findings.push({
295
- status: 'warn',
296
- message: `Skill name ${frontmatter.name === undefined ? 'missing' : `"${frontmatter.name}" is outside the allowed format`}`,
297
- hint: 'Names are 1–64 characters of lowercase letters, digits and hyphens.',
298
- learnMoreUrl: guideUrl(meta.id, 'name-format'),
299
- });
300
- score -= 10;
301
- }
302
- if (frontmatter.description === undefined || frontmatter.description.trim() === '') {
303
- findings.push({
304
- status: 'fail',
305
- message: 'Skill has no description',
306
- hint: 'The description is what an agent reads to decide whether to install the skill.',
307
- learnMoreUrl: guideUrl(meta.id, 'no-description'),
308
- });
309
- score -= 15;
310
- }
311
- else {
312
- findings.push({ status: 'pass', message: `Skill "${frontmatter.name ?? '(unnamed)'}" declares a description` });
313
- }
314
- return buildResult(meta, score, findings, start);
315
- }
316
- //# sourceMappingURL=agent-skills.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"agent-skills.js","sourceRoot":"","sources":["../../src/checks/agent-skills.ts"],"names":[],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
2
- /**
3
- * "ai-catalog" — one document listing everything an agent can call on this
4
- * site.
5
- *
6
- * Every protocol arrived with its own discovery file: an A2A card here, an MCP
7
- * server card there, an API catalog somewhere else, a skills index in a fourth
8
- * place. An agent that wants to know what a site offers has to know all four
9
- * conventions in advance and probe each one.
10
- *
11
- * Two efforts are converging on a single index. The Linux Foundation's Agent
12
- * Card working group specifies `/.well-known/ai-catalog.json`; Agentic Resource
13
- * Discovery, with Google, Microsoft and Hugging Face listed, specifies
14
- * `/.well-known/ard.json`. They overlap heavily and neither has won. Google's
15
- * own Lighthouse ships an `ard-schema` audit that accepts four discovery routes
16
- * — a robots.txt `Agentmap:` directive, an `ai-catalog` link relation in the
17
- * header or the HTML, or the well-known path — so this check accepts all of
18
- * them too.
19
- *
20
- * Both are drafts, so the check is informational and its absence is never a
21
- * defect. What it *can* do usefully today is catch a catalog that lies: an
22
- * entry pointing at a document that 404s, or whose media type does not match
23
- * what the entry claims. A broken index is worse than no index, because an
24
- * agent trusts it before it fetches.
25
- */
26
- export declare const meta: CheckMeta;
27
- export default function check(ctx: CheckContext): Promise<CheckResult>;
28
- //# sourceMappingURL=ai-catalog.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai-catalog.d.ts","sourceRoot":"","sources":["../../src/checks/ai-catalog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAA0B,MAAM,aAAa,CAAC;AAOhG;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AA+EF,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA4C3E"}
@@ -1,254 +0,0 @@
1
- import { AI_CATALOG_ENTRY_TYPES } from '../constants.js';
2
- import { guideUrl } from '../guide-urls.js';
3
- import { buildResult, isHtmlDocument } from './utils.js';
4
- import { findLinkTags, getAttribute } from './html-utils.js';
5
- import { parseLinkHeader } from './http-headers.js';
6
- import { parseRobotsTxt } from './robots-parser.js';
7
- import { standingNote } from './well-known.js';
8
- /**
9
- * "ai-catalog" — one document listing everything an agent can call on this
10
- * site.
11
- *
12
- * Every protocol arrived with its own discovery file: an A2A card here, an MCP
13
- * server card there, an API catalog somewhere else, a skills index in a fourth
14
- * place. An agent that wants to know what a site offers has to know all four
15
- * conventions in advance and probe each one.
16
- *
17
- * Two efforts are converging on a single index. The Linux Foundation's Agent
18
- * Card working group specifies `/.well-known/ai-catalog.json`; Agentic Resource
19
- * Discovery, with Google, Microsoft and Hugging Face listed, specifies
20
- * `/.well-known/ard.json`. They overlap heavily and neither has won. Google's
21
- * own Lighthouse ships an `ard-schema` audit that accepts four discovery routes
22
- * — a robots.txt `Agentmap:` directive, an `ai-catalog` link relation in the
23
- * header or the HTML, or the well-known path — so this check accepts all of
24
- * them too.
25
- *
26
- * Both are drafts, so the check is informational and its absence is never a
27
- * defect. What it *can* do usefully today is catch a catalog that lies: an
28
- * entry pointing at a document that 404s, or whose media type does not match
29
- * what the entry claims. A broken index is worse than no index, because an
30
- * agent trusts it before it fetches.
31
- */
32
- export const meta = {
33
- id: 'ai-catalog',
34
- name: 'AI Catalog',
35
- description: 'Checks the agent resource catalog (ai-catalog.json / ard.json) and whether its entries resolve',
36
- category: 'protocols',
37
- };
38
- const MECHANISM_LABEL = {
39
- 'robots-agentmap': 'robots.txt Agentmap: directive',
40
- 'link-header': 'Link header rel="ai-catalog"',
41
- 'html-link': '<link rel="ai-catalog">',
42
- 'well-known': 'well-known path',
43
- };
44
- const WELL_KNOWN_PATHS = ['/.well-known/ai-catalog.json', '/.well-known/ard.json'];
45
- function absolute(url, base) {
46
- try {
47
- return new URL(url, `${base}/`).toString();
48
- }
49
- catch {
50
- return url;
51
- }
52
- }
53
- async function fetchDocument(ctx, url) {
54
- const res = await ctx.fetch(url);
55
- if (!res.ok || res.body.trim().length === 0 || isHtmlDocument(res.body))
56
- return null;
57
- return res;
58
- }
59
- /** Try every documented discovery route, in the order Lighthouse's audit uses. */
60
- async function locate(ctx) {
61
- const robotsRes = await ctx.fetch(`${ctx.url}/robots.txt`);
62
- if (robotsRes.ok) {
63
- for (const target of parseRobotsTxt(robotsRes.body).agentmaps) {
64
- const url = absolute(target, ctx.url);
65
- const res = await fetchDocument(ctx, url);
66
- if (res !== null)
67
- return { mechanism: 'robots-agentmap', url, res };
68
- }
69
- }
70
- for (const entry of parseLinkHeader(ctx.headers?.['link'] ?? '')) {
71
- const rel = (entry.params['rel'] ?? '').split(/\s+/);
72
- if (!rel.includes('ai-catalog') && !rel.includes('ard'))
73
- continue;
74
- const url = absolute(entry.url, ctx.url);
75
- const res = await fetchDocument(ctx, url);
76
- if (res !== null)
77
- return { mechanism: 'link-header', url, res };
78
- }
79
- for (const rel of ['ai-catalog', 'ard']) {
80
- for (const tag of findLinkTags(ctx.html ?? '', rel)) {
81
- const href = getAttribute(tag, 'href');
82
- if (href === null)
83
- continue;
84
- const url = absolute(href, ctx.url);
85
- const res = await fetchDocument(ctx, url);
86
- if (res !== null)
87
- return { mechanism: 'html-link', url, res };
88
- }
89
- }
90
- for (const path of WELL_KNOWN_PATHS) {
91
- const res = await fetchDocument(ctx, `${ctx.url}${path}`);
92
- if (res !== null)
93
- return { mechanism: 'well-known', url: `${ctx.url}${path}`, res };
94
- }
95
- return null;
96
- }
97
- export default async function check(ctx) {
98
- const start = performance.now();
99
- const findings = [];
100
- let score = 100;
101
- const found = await locate(ctx);
102
- if (found === null) {
103
- findings.push({
104
- status: 'warn',
105
- message: 'No agent resource catalog found',
106
- detail: `Checked ${Object.values(MECHANISM_LABEL).join(', ')} and ${WELL_KNOWN_PATHS.join(', ')}. Both specifications are drafts.`,
107
- hint: 'A catalog is one document listing everything an agent can call here — agent cards, MCP servers, APIs, skills — ' +
108
- 'so a client stops probing four conventions to find out. Worth publishing once you have more than one of those. ' +
109
- 'Informational: both ai-catalog.json and ard.json are still drafts, so this never affects your score.',
110
- learnMoreUrl: guideUrl(meta.id, 'not-found'),
111
- });
112
- return buildResult(meta, 0, findings, start);
113
- }
114
- findings.push({
115
- status: 'pass',
116
- message: `Agent resource catalog found via ${MECHANISM_LABEL[found.mechanism]}`,
117
- detail: [found.url, standingNote(new URL(found.url).pathname)].filter(Boolean).join(' — '),
118
- });
119
- let data;
120
- try {
121
- data = JSON.parse(found.res.body);
122
- }
123
- catch {
124
- findings.push({
125
- status: 'fail',
126
- message: 'Catalog is not valid JSON',
127
- hint: 'Fix the JSON syntax. A catalog an agent cannot parse is worse than none, because it is fetched first.',
128
- learnMoreUrl: guideUrl(meta.id, 'invalid-json'),
129
- });
130
- return buildResult(meta, 10, findings, start);
131
- }
132
- score = validateShape(data, findings, score);
133
- score = await resolveEntries(ctx, readEntries(data), findings, score);
134
- return buildResult(meta, score, findings, start);
135
- }
136
- function readEntries(data) {
137
- const raw = Array.isArray(data.entries) ? data.entries : [];
138
- return raw.map((e) => ({
139
- identifier: String(e.identifier ?? ''),
140
- type: String(e.type ?? ''),
141
- displayName: String(e.displayName ?? e.identifier ?? '(unnamed)'),
142
- url: typeof e.url === 'string' ? e.url : undefined,
143
- inline: e.data !== undefined,
144
- }));
145
- }
146
- function validateShape(data, findings, score) {
147
- if (data.specVersion === undefined) {
148
- findings.push({
149
- status: 'warn',
150
- message: 'Catalog declares no specVersion',
151
- hint: 'Add "specVersion": "1.0" so a consumer knows which revision to expect. Both drafts are moving.',
152
- learnMoreUrl: guideUrl(meta.id, 'no-spec-version'),
153
- });
154
- score -= 5;
155
- }
156
- const host = (data.host ?? {});
157
- if (host.identifier === undefined && host.displayName === undefined) {
158
- findings.push({
159
- status: 'warn',
160
- message: 'Catalog declares no host',
161
- hint: 'Add host.displayName and host.identifier so an agent can attribute the resources it finds.',
162
- learnMoreUrl: guideUrl(meta.id, 'no-host'),
163
- });
164
- score -= 5;
165
- }
166
- return score;
167
- }
168
- /**
169
- * Fetch what each entry points at. This is the part of the check that earns its
170
- * keep: an agent trusts a catalog before it fetches, so a dead entry sends it
171
- * somewhere that does not exist.
172
- */
173
- async function resolveEntries(ctx, entries, findings, score) {
174
- if (entries.length === 0) {
175
- findings.push({
176
- status: 'warn',
177
- message: 'Catalog has no entries',
178
- hint: 'An empty catalog advertises nothing. List your agent cards, MCP servers, API descriptions and skills.',
179
- learnMoreUrl: guideUrl(meta.id, 'empty'),
180
- });
181
- return score - 20;
182
- }
183
- findings.push({ status: 'pass', message: `Catalog lists ${entries.length} resource(s)` });
184
- const incomplete = entries.filter((e) => e.identifier === '' || e.type === '' || (e.url === undefined && !e.inline));
185
- if (incomplete.length > 0) {
186
- findings.push({
187
- status: 'warn',
188
- message: `${incomplete.length} entry(ies) missing identifier, type, or url/data`,
189
- detail: incomplete.map((e) => e.displayName).join(', '),
190
- hint: 'Every entry needs an identifier, a media type, and either an inline data object or a url.',
191
- learnMoreUrl: guideUrl(meta.id, 'incomplete-entry'),
192
- });
193
- score -= 10;
194
- }
195
- const unknownTypes = [
196
- ...new Set(entries.map((e) => e.type).filter((t) => t !== '' && !(t in AI_CATALOG_ENTRY_TYPES))),
197
- ];
198
- if (unknownTypes.length > 0) {
199
- findings.push({
200
- status: 'warn',
201
- message: 'Entry with an unrecognised media type',
202
- detail: unknownTypes.join(', '),
203
- hint: `Known types: ${Object.keys(AI_CATALOG_ENTRY_TYPES).join(', ')}.`,
204
- learnMoreUrl: guideUrl(meta.id, 'entry-type'),
205
- });
206
- score -= 5;
207
- }
208
- // Resolve at most five referenced documents; a catalog with more is unusual
209
- // and the point is made by a sample.
210
- const linked = entries.filter((e) => e.url !== undefined).slice(0, 5);
211
- const dead = [];
212
- const mistyped = [];
213
- for (const entry of linked) {
214
- const url = absolute(entry.url, ctx.url);
215
- const res = await ctx.fetch(url, { method: 'HEAD' });
216
- // Some origins refuse HEAD; fall back to GET rather than reporting a
217
- // working document as dead.
218
- const effective = res.status === 405 || res.status === 501 ? await ctx.fetch(url) : res;
219
- if (!effective.ok) {
220
- dead.push(`${entry.displayName} → ${url} (HTTP ${effective.status || 'network error'})`);
221
- continue;
222
- }
223
- const ct = (effective.headers['content-type'] ?? '').toLowerCase();
224
- if (entry.type !== '' && ct !== '' && !ct.includes(entry.type) && !ct.includes('application/json')) {
225
- mistyped.push(`${entry.displayName}: claims ${entry.type}, served ${ct.split(';')[0]}`);
226
- }
227
- }
228
- if (dead.length > 0) {
229
- findings.push({
230
- status: 'fail',
231
- message: `${dead.length} catalog entry(ies) point at a document that cannot be fetched`,
232
- detail: dead.join('\n'),
233
- hint: 'An agent reads the catalog before it reads anything else, so a dead entry sends it somewhere that does not ' +
234
- 'exist. Fix the URL or remove the entry.',
235
- learnMoreUrl: guideUrl(meta.id, 'dead-entry'),
236
- });
237
- score -= 15 * dead.length;
238
- }
239
- else if (linked.length > 0) {
240
- findings.push({ status: 'pass', message: `All ${linked.length} referenced document(s) resolve` });
241
- }
242
- if (mistyped.length > 0) {
243
- findings.push({
244
- status: 'warn',
245
- message: `${mistyped.length} entry(ies) served with a different media type than declared`,
246
- detail: mistyped.join('\n'),
247
- hint: 'Serve each referenced document with the media type its catalog entry claims, so a client can dispatch on it without sniffing.',
248
- learnMoreUrl: guideUrl(meta.id, 'entry-mistyped'),
249
- });
250
- score -= 5;
251
- }
252
- return score;
253
- }
254
- //# sourceMappingURL=ai-catalog.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai-catalog.js","sourceRoot":"","sources":["../../src/checks/ai-catalog.ts"],"names":[],"mappings":"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"}