afdocs 0.1.3 → 0.3.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/README.md +48 -24
- package/dist/checks/authentication/auth-alternative-access.d.ts +2 -0
- package/dist/checks/authentication/auth-alternative-access.d.ts.map +1 -0
- package/dist/checks/authentication/auth-alternative-access.js +17 -0
- package/dist/checks/authentication/auth-alternative-access.js.map +1 -0
- package/dist/checks/authentication/auth-gate-detection.d.ts +2 -0
- package/dist/checks/authentication/auth-gate-detection.d.ts.map +1 -0
- package/dist/checks/authentication/auth-gate-detection.js +175 -0
- package/dist/checks/authentication/auth-gate-detection.js.map +1 -0
- package/dist/checks/content-structure/markdown-code-fence-validity.js +119 -5
- package/dist/checks/content-structure/markdown-code-fence-validity.js.map +1 -1
- package/dist/checks/index.d.ts +2 -0
- package/dist/checks/index.d.ts.map +1 -1
- package/dist/checks/index.js +3 -0
- package/dist/checks/index.js.map +1 -1
- package/dist/checks/llms-txt/llms-txt-exists.js +83 -6
- package/dist/checks/llms-txt/llms-txt-exists.js.map +1 -1
- package/dist/checks/llms-txt/llms-txt-links-markdown.js +46 -21
- package/dist/checks/llms-txt/llms-txt-links-markdown.js.map +1 -1
- package/dist/checks/llms-txt/llms-txt-links-resolve.js +10 -3
- package/dist/checks/llms-txt/llms-txt-links-resolve.js.map +1 -1
- package/dist/checks/markdown-availability/content-negotiation.js +101 -5
- package/dist/checks/markdown-availability/content-negotiation.js.map +1 -1
- package/dist/checks/markdown-availability/markdown-url-support.js +82 -5
- package/dist/checks/markdown-availability/markdown-url-support.js.map +1 -1
- package/dist/checks/observability/cache-header-hygiene.js +200 -5
- package/dist/checks/observability/cache-header-hygiene.js.map +1 -1
- package/dist/checks/page-size/content-start-position.js +161 -5
- package/dist/checks/page-size/content-start-position.js.map +1 -1
- package/dist/checks/page-size/page-size-html.js +127 -5
- package/dist/checks/page-size/page-size-html.js.map +1 -1
- package/dist/checks/page-size/page-size-markdown.js +100 -5
- package/dist/checks/page-size/page-size-markdown.js.map +1 -1
- package/dist/checks/url-stability/http-status-codes.js +106 -5
- package/dist/checks/url-stability/http-status-codes.js.map +1 -1
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +9 -1
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/formatters/text.d.ts +4 -1
- package/dist/cli/formatters/text.d.ts.map +1 -1
- package/dist/cli/formatters/text.js +94 -1
- package/dist/cli/formatters/text.js.map +1 -1
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -1
- package/dist/helpers/detect-markdown.d.ts +10 -0
- package/dist/helpers/detect-markdown.d.ts.map +1 -0
- package/dist/helpers/detect-markdown.js +29 -0
- package/dist/helpers/detect-markdown.js.map +1 -0
- package/dist/helpers/get-markdown-content.d.ts +23 -0
- package/dist/helpers/get-markdown-content.d.ts.map +1 -0
- package/dist/helpers/get-markdown-content.js +93 -0
- package/dist/helpers/get-markdown-content.js.map +1 -0
- package/dist/helpers/get-page-urls.d.ts +42 -0
- package/dist/helpers/get-page-urls.d.ts.map +1 -0
- package/dist/helpers/get-page-urls.js +236 -0
- package/dist/helpers/get-page-urls.js.map +1 -0
- package/dist/helpers/html-to-markdown.d.ts +7 -0
- package/dist/helpers/html-to-markdown.d.ts.map +1 -0
- package/dist/helpers/html-to-markdown.js +11 -0
- package/dist/helpers/html-to-markdown.js.map +1 -0
- package/dist/helpers/index.d.ts +5 -0
- package/dist/helpers/index.d.ts.map +1 -1
- package/dist/helpers/index.js +4 -0
- package/dist/helpers/index.js.map +1 -1
- package/dist/helpers/to-md-urls.d.ts +7 -0
- package/dist/helpers/to-md-urls.d.ts.map +1 -0
- package/dist/helpers/to-md-urls.js +24 -0
- package/dist/helpers/to-md-urls.js.map +1 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +21 -14
- package/dist/runner.js.map +1 -1
- package/dist/types.d.ts +13 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -7,7 +7,12 @@ Test your documentation site against the [Agent-Friendly Documentation Spec](htt
|
|
|
7
7
|
|
|
8
8
|
Agents don't use docs like humans. They hit truncation limits, get walls of CSS instead of content, can't follow cross-host redirects, and don't know about quality-of-life improvements like `llms.txt` or `.md` docs pages that would make life swell. Maybe this is because the industry has lacked guidance - until now.
|
|
9
9
|
|
|
10
|
-
afdocs runs
|
|
10
|
+
afdocs runs 21 checks across 8 categories to evaluate how well your docs serve agent consumers. 14 are fully implemented; the rest return `skip` until completed.
|
|
11
|
+
|
|
12
|
+
> **Status: Early development (0.x)**
|
|
13
|
+
> This project is under active development. Check IDs, CLI flags, and output formats may change between minor versions. Feel free to try it out, but don't build automation against specific output until 1.0.
|
|
14
|
+
>
|
|
15
|
+
> Implements [spec v0.1.0](https://agentdocsspec.com/spec) (2026-02-22).
|
|
11
16
|
|
|
12
17
|
## Quick start
|
|
13
18
|
|
|
@@ -27,8 +32,18 @@ llms-txt
|
|
|
27
32
|
✓ llms-txt-links-resolve: All 50 tested links resolve (177 total links)
|
|
28
33
|
✓ llms-txt-links-markdown: 50/50 links point to markdown content (100%)
|
|
29
34
|
|
|
35
|
+
Markdown Availability
|
|
36
|
+
✗ content-negotiation: Server ignores Accept: text/markdown header (0/50 sampled pages return markdown)
|
|
37
|
+
✗ markdown-url-support: No sampled pages support .md URLs (0/50 tested)
|
|
38
|
+
|
|
39
|
+
URL Stability
|
|
40
|
+
✓ http-status-codes: All 50 sampled pages return proper error codes for bad URLs
|
|
41
|
+
|
|
42
|
+
Authentication
|
|
43
|
+
✓ auth-gate-detection: All 50 sampled pages are publicly accessible
|
|
44
|
+
|
|
30
45
|
Summary
|
|
31
|
-
|
|
46
|
+
9 passed, 3 failed, 9 skipped (21 total)
|
|
32
47
|
```
|
|
33
48
|
|
|
34
49
|
## Install
|
|
@@ -55,15 +70,16 @@ afdocs check https://docs.example.com --pass-threshold 30000 --fail-threshold 80
|
|
|
55
70
|
|
|
56
71
|
### Options
|
|
57
72
|
|
|
58
|
-
| Option | Default | Description
|
|
59
|
-
| ----------------------- | -------- |
|
|
60
|
-
| `--format <format>` | `text` | Output format: `text` or `json`
|
|
61
|
-
|
|
|
62
|
-
| `--
|
|
63
|
-
| `--
|
|
64
|
-
| `--
|
|
65
|
-
| `--
|
|
66
|
-
| `--
|
|
73
|
+
| Option | Default | Description |
|
|
74
|
+
| ----------------------- | -------- | -------------------------------------------- |
|
|
75
|
+
| `--format <format>` | `text` | Output format: `text` or `json` |
|
|
76
|
+
| `-v, --verbose` | | Show per-page details for checks with issues |
|
|
77
|
+
| `--checks <ids>` | all | Comma-separated list of check IDs |
|
|
78
|
+
| `--max-concurrency <n>` | `3` | Maximum concurrent HTTP requests |
|
|
79
|
+
| `--request-delay <ms>` | `200` | Delay between requests |
|
|
80
|
+
| `--max-links <n>` | `50` | Maximum links to test in link checks |
|
|
81
|
+
| `--pass-threshold <n>` | `50000` | Size pass threshold (characters) |
|
|
82
|
+
| `--fail-threshold <n>` | `100000` | Size fail threshold (characters) |
|
|
67
83
|
|
|
68
84
|
### Exit codes
|
|
69
85
|
|
|
@@ -128,7 +144,7 @@ describe('agent-friendliness', () => {
|
|
|
128
144
|
|
|
129
145
|
## Checks
|
|
130
146
|
|
|
131
|
-
|
|
147
|
+
21 checks across 8 categories. Checks marked with \* are not yet implemented and return `skip`.
|
|
132
148
|
|
|
133
149
|
### Category 1: llms.txt
|
|
134
150
|
|
|
@@ -142,18 +158,18 @@ describe('agent-friendliness', () => {
|
|
|
142
158
|
|
|
143
159
|
### Category 2: Markdown Availability
|
|
144
160
|
|
|
145
|
-
| Check
|
|
146
|
-
|
|
|
147
|
-
| `markdown-url-support`
|
|
148
|
-
| `content-negotiation`
|
|
161
|
+
| Check | Description |
|
|
162
|
+
| ---------------------- | ------------------------------------------------- |
|
|
163
|
+
| `markdown-url-support` | Whether `.md` URL variants return markdown |
|
|
164
|
+
| `content-negotiation` | Whether the server honors `Accept: text/markdown` |
|
|
149
165
|
|
|
150
166
|
### Category 3: Page Size and Truncation Risk
|
|
151
167
|
|
|
152
|
-
| Check
|
|
153
|
-
|
|
|
154
|
-
| `page-size-markdown`
|
|
155
|
-
| `page-size-html`
|
|
156
|
-
| `content-start-position`
|
|
168
|
+
| Check | Description |
|
|
169
|
+
| ------------------------ | ------------------------------------------------ |
|
|
170
|
+
| `page-size-markdown` | Character count when served as markdown |
|
|
171
|
+
| `page-size-html` | Character count of HTML and post-conversion size |
|
|
172
|
+
| `content-start-position` | How far into the response actual content begins |
|
|
157
173
|
|
|
158
174
|
### Category 4: Content Structure
|
|
159
175
|
|
|
@@ -161,13 +177,13 @@ describe('agent-friendliness', () => {
|
|
|
161
177
|
| --------------------------------- | -------------------------------------------------- |
|
|
162
178
|
| `tabbed-content-serialization` \* | Whether tabbed content creates oversized output |
|
|
163
179
|
| `section-header-quality` \* | Whether headers in tabbed sections include context |
|
|
164
|
-
| `markdown-code-fence-validity`
|
|
180
|
+
| `markdown-code-fence-validity` | Whether markdown has unclosed code fences |
|
|
165
181
|
|
|
166
182
|
### Category 5: URL Stability and Redirects
|
|
167
183
|
|
|
168
184
|
| Check | Description |
|
|
169
185
|
| ---------------------- | ----------------------------------------------- |
|
|
170
|
-
| `http-status-codes`
|
|
186
|
+
| `http-status-codes` | Whether error pages return correct status codes |
|
|
171
187
|
| `redirect-behavior` \* | Whether redirects are same-host HTTP redirects |
|
|
172
188
|
|
|
173
189
|
### Category 6: Agent Discoverability Directives
|
|
@@ -182,7 +198,14 @@ describe('agent-friendliness', () => {
|
|
|
182
198
|
| ---------------------------- | ---------------------------------------------- |
|
|
183
199
|
| `llms-txt-freshness` \* | Whether `llms.txt` reflects current site state |
|
|
184
200
|
| `markdown-content-parity` \* | Whether markdown and HTML versions match |
|
|
185
|
-
| `cache-header-hygiene`
|
|
201
|
+
| `cache-header-hygiene` | Whether cache headers allow timely updates |
|
|
202
|
+
|
|
203
|
+
### Category 8: Authentication and Access
|
|
204
|
+
|
|
205
|
+
| Check | Description |
|
|
206
|
+
| ---------------------------- | -------------------------------------------------------------------- |
|
|
207
|
+
| `auth-gate-detection` | Whether documentation pages require authentication to access content |
|
|
208
|
+
| `auth-alternative-access` \* | Whether auth-gated sites provide alternative access paths for agents |
|
|
186
209
|
|
|
187
210
|
## Check dependencies
|
|
188
211
|
|
|
@@ -194,6 +217,7 @@ Some checks depend on others. If a dependency doesn't pass, the dependent check
|
|
|
194
217
|
- `markdown-code-fence-validity` requires `markdown-url-support` or `content-negotiation`
|
|
195
218
|
- `llms-txt-freshness` requires `llms-txt-exists`
|
|
196
219
|
- `markdown-content-parity` requires `markdown-url-support` or `content-negotiation`
|
|
220
|
+
- `auth-alternative-access` requires `auth-gate-detection` (warn or fail)
|
|
197
221
|
|
|
198
222
|
## Responsible use
|
|
199
223
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-alternative-access.d.ts","sourceRoot":"","sources":["../../../src/checks/authentication/auth-alternative-access.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { registerCheck } from '../registry.js';
|
|
2
|
+
async function check(_ctx) {
|
|
3
|
+
return {
|
|
4
|
+
id: 'auth-alternative-access',
|
|
5
|
+
category: 'authentication',
|
|
6
|
+
status: 'skip',
|
|
7
|
+
message: 'Not yet implemented',
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
registerCheck({
|
|
11
|
+
id: 'auth-alternative-access',
|
|
12
|
+
category: 'authentication',
|
|
13
|
+
description: 'Whether an auth-gated documentation site provides alternative access paths for agents',
|
|
14
|
+
dependsOn: [['auth-gate-detection']],
|
|
15
|
+
run: check,
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=auth-alternative-access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-alternative-access.js","sourceRoot":"","sources":["../../../src/checks/authentication/auth-alternative-access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,KAAK,UAAU,KAAK,CAAC,IAAkB;IACrC,OAAO;QACL,EAAE,EAAE,yBAAyB;QAC7B,QAAQ,EAAE,gBAAgB;QAC1B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,qBAAqB;KAC/B,CAAC;AACJ,CAAC;AAED,aAAa,CAAC;IACZ,EAAE,EAAE,yBAAyB;IAC7B,QAAQ,EAAE,gBAAgB;IAC1B,WAAW,EACT,uFAAuF;IACzF,SAAS,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC;IACpC,GAAG,EAAE,KAAK;CACX,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-gate-detection.d.ts","sourceRoot":"","sources":["../../../src/checks/authentication/auth-gate-detection.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { registerCheck } from '../registry.js';
|
|
2
|
+
import { discoverAndSamplePages } from '../../helpers/get-page-urls.js';
|
|
3
|
+
const SSO_DOMAINS = [
|
|
4
|
+
'okta.com',
|
|
5
|
+
'auth0.com',
|
|
6
|
+
'login.microsoftonline.com',
|
|
7
|
+
'accounts.google.com',
|
|
8
|
+
'login.salesforce.com',
|
|
9
|
+
'sso.',
|
|
10
|
+
'idp.',
|
|
11
|
+
'auth.',
|
|
12
|
+
'login.',
|
|
13
|
+
];
|
|
14
|
+
function isSsoDomain(url) {
|
|
15
|
+
try {
|
|
16
|
+
const hostname = new URL(url).hostname.toLowerCase();
|
|
17
|
+
return SSO_DOMAINS.find((domain) => hostname === domain || hostname.endsWith('.' + domain) || hostname.startsWith(domain));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function detectLoginForm(body) {
|
|
24
|
+
const sample = body.slice(0, 50000).toLowerCase();
|
|
25
|
+
if (sample.includes('<input') && sample.includes('type="password"')) {
|
|
26
|
+
return 'Contains password input field';
|
|
27
|
+
}
|
|
28
|
+
// Check page title for login indicators
|
|
29
|
+
const titleMatch = /<title[^>]*>(.*?)<\/title>/i.exec(sample);
|
|
30
|
+
if (titleMatch) {
|
|
31
|
+
const title = titleMatch[1].toLowerCase();
|
|
32
|
+
if (/sign\s*in|log\s*in|authenticate/i.test(title)) {
|
|
33
|
+
return `Page title suggests login: "${titleMatch[1].trim()}"`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Check for SSO form actions
|
|
37
|
+
if (/<form[^>]*action\s*=\s*["'][^"']*(?:saml|oauth|openid|sso|auth)[^"']*["']/i.test(sample)) {
|
|
38
|
+
return 'Contains SSO-related form action';
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
async function check(ctx) {
|
|
43
|
+
const id = 'auth-gate-detection';
|
|
44
|
+
const category = 'authentication';
|
|
45
|
+
const { urls: pageUrls, totalPages, sampled, warnings } = await discoverAndSamplePages(ctx);
|
|
46
|
+
const results = [];
|
|
47
|
+
const concurrency = ctx.options.maxConcurrency;
|
|
48
|
+
for (let i = 0; i < pageUrls.length; i += concurrency) {
|
|
49
|
+
const batch = pageUrls.slice(i, i + concurrency);
|
|
50
|
+
const batchResults = await Promise.all(batch.map(async (url) => {
|
|
51
|
+
try {
|
|
52
|
+
const response = await ctx.http.fetch(url, { redirect: 'manual' });
|
|
53
|
+
const status = response.status;
|
|
54
|
+
// Auth-required status codes
|
|
55
|
+
if (status === 401 || status === 403) {
|
|
56
|
+
return { url, classification: 'auth-required', status };
|
|
57
|
+
}
|
|
58
|
+
// Redirect — check if it's to an SSO domain
|
|
59
|
+
if (status >= 300 && status < 400) {
|
|
60
|
+
const location = response.headers.get('location');
|
|
61
|
+
if (location) {
|
|
62
|
+
const resolvedLocation = location.startsWith('http')
|
|
63
|
+
? location
|
|
64
|
+
: new URL(location, url).toString();
|
|
65
|
+
const ssoDomain = isSsoDomain(resolvedLocation);
|
|
66
|
+
if (ssoDomain) {
|
|
67
|
+
return {
|
|
68
|
+
url,
|
|
69
|
+
classification: 'auth-redirect',
|
|
70
|
+
status,
|
|
71
|
+
redirectUrl: resolvedLocation,
|
|
72
|
+
ssoDomain,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Non-SSO redirect — treat as accessible (normal redirect)
|
|
77
|
+
return { url, classification: 'accessible', status };
|
|
78
|
+
}
|
|
79
|
+
// 200 — check for soft auth gate (login form)
|
|
80
|
+
if (status === 200) {
|
|
81
|
+
let body;
|
|
82
|
+
try {
|
|
83
|
+
body = await response.text();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return { url, classification: 'accessible', status };
|
|
87
|
+
}
|
|
88
|
+
const loginHint = detectLoginForm(body);
|
|
89
|
+
if (loginHint) {
|
|
90
|
+
return { url, classification: 'soft-auth-gate', status, hint: loginHint };
|
|
91
|
+
}
|
|
92
|
+
return { url, classification: 'accessible', status };
|
|
93
|
+
}
|
|
94
|
+
// Other status codes — treat as accessible
|
|
95
|
+
return { url, classification: 'accessible', status };
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
return {
|
|
99
|
+
url,
|
|
100
|
+
classification: 'accessible',
|
|
101
|
+
status: null,
|
|
102
|
+
error: err instanceof Error ? err.message : String(err),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}));
|
|
106
|
+
results.push(...batchResults);
|
|
107
|
+
}
|
|
108
|
+
const fetchErrors = results.filter((r) => r.error).length;
|
|
109
|
+
const tested = results.filter((r) => !r.error);
|
|
110
|
+
if (tested.length === 0) {
|
|
111
|
+
return {
|
|
112
|
+
id,
|
|
113
|
+
category,
|
|
114
|
+
status: 'fail',
|
|
115
|
+
message: `Could not fetch any pages to check authentication${fetchErrors > 0 ? `; ${fetchErrors} failed to fetch` : ''}`,
|
|
116
|
+
details: {
|
|
117
|
+
totalPages,
|
|
118
|
+
testedPages: results.length,
|
|
119
|
+
sampled,
|
|
120
|
+
fetchErrors,
|
|
121
|
+
pageResults: results,
|
|
122
|
+
discoveryWarnings: warnings,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const accessible = tested.filter((r) => r.classification === 'accessible');
|
|
127
|
+
const authRequired = tested.filter((r) => r.classification === 'auth-required');
|
|
128
|
+
const softAuthGate = tested.filter((r) => r.classification === 'soft-auth-gate');
|
|
129
|
+
const authRedirect = tested.filter((r) => r.classification === 'auth-redirect');
|
|
130
|
+
const gatedCount = authRequired.length + softAuthGate.length + authRedirect.length;
|
|
131
|
+
const ssoDomains = [...new Set(authRedirect.map((r) => r.ssoDomain).filter(Boolean))];
|
|
132
|
+
let status;
|
|
133
|
+
let message;
|
|
134
|
+
const suffix = fetchErrors > 0 ? `; ${fetchErrors} failed to fetch` : '';
|
|
135
|
+
const pageLabel = sampled ? 'sampled pages' : 'pages';
|
|
136
|
+
if (gatedCount === 0) {
|
|
137
|
+
status = 'pass';
|
|
138
|
+
message = `All ${accessible.length} ${pageLabel} are publicly accessible${suffix}`;
|
|
139
|
+
}
|
|
140
|
+
else if (accessible.length > 0 && gatedCount > 0) {
|
|
141
|
+
status = 'warn';
|
|
142
|
+
message = `${gatedCount} of ${tested.length} ${pageLabel} require authentication (${accessible.length} accessible)${suffix}`;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
status = 'fail';
|
|
146
|
+
message = `All ${tested.length} ${pageLabel} require authentication${suffix}`;
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
id,
|
|
150
|
+
category,
|
|
151
|
+
status,
|
|
152
|
+
message,
|
|
153
|
+
details: {
|
|
154
|
+
totalPages,
|
|
155
|
+
testedPages: results.length,
|
|
156
|
+
sampled,
|
|
157
|
+
accessible: accessible.length,
|
|
158
|
+
authRequired: authRequired.length,
|
|
159
|
+
softAuthGate: softAuthGate.length,
|
|
160
|
+
authRedirect: authRedirect.length,
|
|
161
|
+
ssoDomains,
|
|
162
|
+
fetchErrors,
|
|
163
|
+
pageResults: results,
|
|
164
|
+
discoveryWarnings: warnings,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
registerCheck({
|
|
169
|
+
id: 'auth-gate-detection',
|
|
170
|
+
category: 'authentication',
|
|
171
|
+
description: 'Whether documentation pages require authentication to access content',
|
|
172
|
+
dependsOn: [],
|
|
173
|
+
run: check,
|
|
174
|
+
});
|
|
175
|
+
//# sourceMappingURL=auth-gate-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-gate-detection.js","sourceRoot":"","sources":["../../../src/checks/authentication/auth-gate-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,124 @@
|
|
|
1
1
|
import { registerCheck } from '../registry.js';
|
|
2
|
-
|
|
2
|
+
import { getMarkdownContent } from '../../helpers/get-markdown-content.js';
|
|
3
|
+
/**
|
|
4
|
+
* Strip blockquote prefixes (`> `) from a line so that fences inside
|
|
5
|
+
* blockquotes are detected the same way a CommonMark parser would
|
|
6
|
+
* handle them. Supports nested blockquotes (`> > `).
|
|
7
|
+
*/
|
|
8
|
+
function stripBlockquotePrefix(line) {
|
|
9
|
+
return line.replace(/^(?:\s{0,3}> ?)+/, '');
|
|
10
|
+
}
|
|
11
|
+
/** Match a line that opens or closes a code fence (after blockquote stripping). */
|
|
12
|
+
const FENCE_RE = /^( {0,3})((`{3,})|(~{3,}))(.*)?$/;
|
|
13
|
+
function analyzeFences(content) {
|
|
14
|
+
const lines = content.split('\n');
|
|
15
|
+
const issues = [];
|
|
16
|
+
let fenceCount = 0;
|
|
17
|
+
let openFence = null;
|
|
18
|
+
for (let i = 0; i < lines.length; i++) {
|
|
19
|
+
const stripped = stripBlockquotePrefix(lines[i]);
|
|
20
|
+
const match = FENCE_RE.exec(stripped);
|
|
21
|
+
if (!match)
|
|
22
|
+
continue;
|
|
23
|
+
const char = match[3] ? '`' : '~';
|
|
24
|
+
const length = (match[3] || match[4]).length;
|
|
25
|
+
if (!openFence) {
|
|
26
|
+
// Opening fence
|
|
27
|
+
openFence = { line: i + 1, char, length };
|
|
28
|
+
fenceCount++;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Potential closing fence: must use same char and be at least as long
|
|
32
|
+
if (char === openFence.char && length >= openFence.length) {
|
|
33
|
+
// Proper close
|
|
34
|
+
openFence = null;
|
|
35
|
+
}
|
|
36
|
+
else if (char !== openFence.char && length >= openFence.length) {
|
|
37
|
+
// Inconsistent close: different delimiter type
|
|
38
|
+
issues.push({
|
|
39
|
+
line: i + 1,
|
|
40
|
+
type: 'inconsistent-close',
|
|
41
|
+
opener: openFence.char.repeat(openFence.length),
|
|
42
|
+
closer: char.repeat(length),
|
|
43
|
+
});
|
|
44
|
+
openFence = null;
|
|
45
|
+
}
|
|
46
|
+
// Otherwise: different char + shorter length = not a close, just content inside the fence
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (openFence) {
|
|
50
|
+
issues.push({
|
|
51
|
+
line: openFence.line,
|
|
52
|
+
type: 'unclosed',
|
|
53
|
+
opener: openFence.char.repeat(openFence.length),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return { fenceCount, issues };
|
|
57
|
+
}
|
|
58
|
+
function worstStatus(statuses) {
|
|
59
|
+
if (statuses.includes('fail'))
|
|
60
|
+
return 'fail';
|
|
61
|
+
if (statuses.includes('warn'))
|
|
62
|
+
return 'warn';
|
|
63
|
+
return 'pass';
|
|
64
|
+
}
|
|
65
|
+
async function check(ctx) {
|
|
66
|
+
const id = 'markdown-code-fence-validity';
|
|
67
|
+
const category = 'content-structure';
|
|
68
|
+
const mdResult = await getMarkdownContent(ctx);
|
|
69
|
+
if (mdResult.pages.length === 0) {
|
|
70
|
+
if (mdResult.mode === 'cached' && !mdResult.depPassed) {
|
|
71
|
+
return {
|
|
72
|
+
id,
|
|
73
|
+
category,
|
|
74
|
+
status: 'skip',
|
|
75
|
+
message: 'Site does not serve markdown content; nothing to analyze',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const hint = mdResult.mode === 'standalone'
|
|
79
|
+
? '; try running with markdown-url-support or content-negotiation checks'
|
|
80
|
+
: '';
|
|
81
|
+
return { id, category, status: 'skip', message: `No markdown content found${hint}` };
|
|
82
|
+
}
|
|
83
|
+
const results = mdResult.pages.map(({ url, content, source }) => {
|
|
84
|
+
const { fenceCount, issues } = analyzeFences(content);
|
|
85
|
+
const hasUnclosed = issues.some((i) => i.type === 'unclosed');
|
|
86
|
+
const hasInconsistent = issues.some((i) => i.type === 'inconsistent-close');
|
|
87
|
+
let status;
|
|
88
|
+
if (hasUnclosed)
|
|
89
|
+
status = 'fail';
|
|
90
|
+
else if (hasInconsistent)
|
|
91
|
+
status = 'warn';
|
|
92
|
+
else
|
|
93
|
+
status = 'pass';
|
|
94
|
+
return { url, source, fenceCount, issues, status };
|
|
95
|
+
});
|
|
96
|
+
const overallStatus = worstStatus(results.map((r) => r.status));
|
|
97
|
+
const totalFences = results.reduce((sum, r) => sum + r.fenceCount, 0);
|
|
98
|
+
const unclosedCount = results.reduce((sum, r) => sum + r.issues.filter((i) => i.type === 'unclosed').length, 0);
|
|
99
|
+
const inconsistentCount = results.reduce((sum, r) => sum + r.issues.filter((i) => i.type === 'inconsistent-close').length, 0);
|
|
100
|
+
let message;
|
|
101
|
+
if (overallStatus === 'pass') {
|
|
102
|
+
message = `All ${totalFences} code fences properly closed across ${results.length} pages`;
|
|
103
|
+
}
|
|
104
|
+
else if (overallStatus === 'warn') {
|
|
105
|
+
message = `${inconsistentCount} code fences use inconsistent delimiters across ${results.length} pages`;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
message = `${unclosedCount} unclosed code fences found across ${results.length} pages`;
|
|
109
|
+
}
|
|
3
110
|
return {
|
|
4
|
-
id
|
|
5
|
-
category
|
|
6
|
-
status:
|
|
7
|
-
message
|
|
111
|
+
id,
|
|
112
|
+
category,
|
|
113
|
+
status: overallStatus,
|
|
114
|
+
message,
|
|
115
|
+
details: {
|
|
116
|
+
pagesAnalyzed: results.length,
|
|
117
|
+
totalFences,
|
|
118
|
+
unclosedCount,
|
|
119
|
+
inconsistentCount,
|
|
120
|
+
pageResults: results,
|
|
121
|
+
},
|
|
8
122
|
};
|
|
9
123
|
}
|
|
10
124
|
registerCheck({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-code-fence-validity.js","sourceRoot":"","sources":["../../../src/checks/content-structure/markdown-code-fence-validity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown-code-fence-validity.js","sourceRoot":"","sources":["../../../src/checks/content-structure/markdown-code-fence-validity.ts"],"names":[],"mappings":"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"}
|
package/dist/checks/index.d.ts
CHANGED
|
@@ -17,6 +17,8 @@ import './agent-discoverability/llms-txt-directive.js';
|
|
|
17
17
|
import './observability/llms-txt-freshness.js';
|
|
18
18
|
import './observability/markdown-content-parity.js';
|
|
19
19
|
import './observability/cache-header-hygiene.js';
|
|
20
|
+
import './authentication/auth-gate-detection.js';
|
|
21
|
+
import './authentication/auth-alternative-access.js';
|
|
20
22
|
export { getCheck, getAllChecks, getChecksSorted } from './registry.js';
|
|
21
23
|
export { extractMarkdownLinks } from './llms-txt/llms-txt-valid.js';
|
|
22
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAGA,OAAO,+BAA+B,CAAC;AACvC,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,sCAAsC,CAAC;AAC9C,OAAO,uCAAuC,CAAC;AAG/C,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AAGxD,OAAO,mCAAmC,CAAC;AAC3C,OAAO,+BAA+B,CAAC;AACvC,OAAO,uCAAuC,CAAC;AAG/C,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,qDAAqD,CAAC;AAG7D,OAAO,sCAAsC,CAAC;AAC9C,OAAO,sCAAsC,CAAC;AAG9C,OAAO,+CAA+C,CAAC;AAGvD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,4CAA4C,CAAC;AACpD,OAAO,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAGA,OAAO,+BAA+B,CAAC;AACvC,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,sCAAsC,CAAC;AAC9C,OAAO,uCAAuC,CAAC;AAG/C,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AAGxD,OAAO,mCAAmC,CAAC;AAC3C,OAAO,+BAA+B,CAAC;AACvC,OAAO,uCAAuC,CAAC;AAG/C,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,qDAAqD,CAAC;AAG7D,OAAO,sCAAsC,CAAC;AAC9C,OAAO,sCAAsC,CAAC;AAG9C,OAAO,+CAA+C,CAAC;AAGvD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,4CAA4C,CAAC;AACpD,OAAO,yCAAyC,CAAC;AAGjD,OAAO,yCAAyC,CAAC;AACjD,OAAO,6CAA6C,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC"}
|
package/dist/checks/index.js
CHANGED
|
@@ -25,6 +25,9 @@ import './agent-discoverability/llms-txt-directive.js';
|
|
|
25
25
|
import './observability/llms-txt-freshness.js';
|
|
26
26
|
import './observability/markdown-content-parity.js';
|
|
27
27
|
import './observability/cache-header-hygiene.js';
|
|
28
|
+
// Category 8: Authentication
|
|
29
|
+
import './authentication/auth-gate-detection.js';
|
|
30
|
+
import './authentication/auth-alternative-access.js';
|
|
28
31
|
export { getCheck, getAllChecks, getChecksSorted } from './registry.js';
|
|
29
32
|
export { extractMarkdownLinks } from './llms-txt/llms-txt-valid.js';
|
|
30
33
|
//# sourceMappingURL=index.js.map
|
package/dist/checks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,uBAAuB;AACvB,OAAO,+BAA+B,CAAC;AACvC,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,sCAAsC,CAAC;AAC9C,OAAO,uCAAuC,CAAC;AAE/C,oCAAoC;AACpC,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AAExD,wBAAwB;AACxB,OAAO,mCAAmC,CAAC;AAC3C,OAAO,+BAA+B,CAAC;AACvC,OAAO,uCAAuC,CAAC;AAE/C,gCAAgC;AAChC,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,qDAAqD,CAAC;AAE7D,4BAA4B;AAC5B,OAAO,sCAAsC,CAAC;AAC9C,OAAO,sCAAsC,CAAC;AAE9C,oCAAoC;AACpC,OAAO,+CAA+C,CAAC;AAEvD,4BAA4B;AAC5B,OAAO,uCAAuC,CAAC;AAC/C,OAAO,4CAA4C,CAAC;AACpD,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,uBAAuB;AACvB,OAAO,+BAA+B,CAAC;AACvC,OAAO,8BAA8B,CAAC;AACtC,OAAO,6BAA6B,CAAC;AACrC,OAAO,sCAAsC,CAAC;AAC9C,OAAO,uCAAuC,CAAC;AAE/C,oCAAoC;AACpC,OAAO,iDAAiD,CAAC;AACzD,OAAO,gDAAgD,CAAC;AAExD,wBAAwB;AACxB,OAAO,mCAAmC,CAAC;AAC3C,OAAO,+BAA+B,CAAC;AACvC,OAAO,uCAAuC,CAAC;AAE/C,gCAAgC;AAChC,OAAO,qDAAqD,CAAC;AAC7D,OAAO,+CAA+C,CAAC;AACvD,OAAO,qDAAqD,CAAC;AAE7D,4BAA4B;AAC5B,OAAO,sCAAsC,CAAC;AAC9C,OAAO,sCAAsC,CAAC;AAE9C,oCAAoC;AACpC,OAAO,+CAA+C,CAAC;AAEvD,4BAA4B;AAC5B,OAAO,uCAAuC,CAAC;AAC/C,OAAO,4CAA4C,CAAC;AACpD,OAAO,yCAAyC,CAAC;AAEjD,6BAA6B;AAC7B,OAAO,yCAAyC,CAAC;AACjD,OAAO,6CAA6C,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC"}
|