milieu-cli 0.1.5 → 0.1.7

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 (40) hide show
  1. package/README.md +53 -7
  2. package/dist/bridges/reachability/index.d.ts.map +1 -1
  3. package/dist/bridges/reachability/index.js +2 -0
  4. package/dist/bridges/reachability/index.js.map +1 -1
  5. package/dist/bridges/separation/api-presence.d.ts +6 -5
  6. package/dist/bridges/separation/api-presence.d.ts.map +1 -1
  7. package/dist/bridges/separation/api-presence.js +9 -5
  8. package/dist/bridges/separation/api-presence.js.map +1 -1
  9. package/dist/bridges/separation/index.d.ts.map +1 -1
  10. package/dist/bridges/separation/index.js +2 -1
  11. package/dist/bridges/separation/index.js.map +1 -1
  12. package/dist/bridges/standards/graphql.d.ts +20 -0
  13. package/dist/bridges/standards/graphql.d.ts.map +1 -0
  14. package/dist/bridges/standards/graphql.js +174 -0
  15. package/dist/bridges/standards/graphql.js.map +1 -0
  16. package/dist/bridges/standards/index.d.ts +10 -5
  17. package/dist/bridges/standards/index.d.ts.map +1 -1
  18. package/dist/bridges/standards/index.js +33 -13
  19. package/dist/bridges/standards/index.js.map +1 -1
  20. package/dist/bridges/standards/markdown-negotiation.d.ts +25 -0
  21. package/dist/bridges/standards/markdown-negotiation.d.ts.map +1 -0
  22. package/dist/bridges/standards/markdown-negotiation.js +127 -0
  23. package/dist/bridges/standards/markdown-negotiation.js.map +1 -0
  24. package/dist/bridges/standards/openapi.d.ts +4 -1
  25. package/dist/bridges/standards/openapi.d.ts.map +1 -1
  26. package/dist/bridges/standards/openapi.js +10 -1
  27. package/dist/bridges/standards/openapi.js.map +1 -1
  28. package/dist/bridges/standards/sitemap.d.ts +21 -0
  29. package/dist/bridges/standards/sitemap.d.ts.map +1 -0
  30. package/dist/bridges/standards/sitemap.js +174 -0
  31. package/dist/bridges/standards/sitemap.js.map +1 -0
  32. package/dist/cli/index.js +0 -0
  33. package/dist/core/explanations.d.ts.map +1 -1
  34. package/dist/core/explanations.js +18 -0
  35. package/dist/core/explanations.js.map +1 -1
  36. package/dist/utils/http-client.d.ts +9 -4
  37. package/dist/utils/http-client.d.ts.map +1 -1
  38. package/dist/utils/http-client.js +23 -3
  39. package/dist/utils/http-client.js.map +1 -1
  40. package/package.json +3 -3
package/README.md CHANGED
@@ -4,6 +4,19 @@ The API is the new product UI. Your customers are no longer just humans. They're
4
4
 
5
5
  As an industry, we've spent decades perfecting UI & UX design for humans. Now we need the same rigor for the interface AI agents actually see: your product's **milieu**.
6
6
 
7
+ ## Table of contents
8
+
9
+ - [What is milieu?](#what-is-milieu)
10
+ - [Quick start](#quick-start)
11
+ - [The 5 Bridges](#the-5-bridges)
12
+ - [Install](#install)
13
+ - [CI/CD integration](#cicd-integration)
14
+ - [Options](#options)
15
+ - [How scoring works](#how-scoring-works)
16
+ - [Programmatic API](#programmatic-api)
17
+ - [Requirements](#requirements)
18
+ - [License](#license)
19
+
7
20
  ## What is milieu?
8
21
 
9
22
  *Milieu* is the totality of machine-readable signals that surround your product — the environment an AI agent encounters when it tries to discover, understand, and integrate with what you've built. It's not any single file or endpoint. It's robots.txt and OpenAPI specs and llms.txt and JSON-LD and developer docs and SDK references, all working together. It's the difference between a product that AI agents can use and one they walk past.
@@ -13,7 +26,7 @@ Good design made products usable for humans. Good milieu design makes products u
13
26
  milieu-cli measures this. It scans your site and tells you what AI agents can actually see.
14
27
 
15
28
  ```bash
16
- npx milieu-cli scan stripe.com
29
+ npx milieu-cli scan petstore.swagger.io
17
30
  ```
18
31
 
19
32
  ```bash
@@ -21,6 +34,39 @@ npx milieu-cli scan stripe.com
21
34
  milieu scan api.example.com --threshold 70
22
35
  ```
23
36
 
37
+ ## Quick start
38
+
39
+ Run your first scan in under a minute:
40
+
41
+ ```bash
42
+ npx milieu-cli scan petstore.swagger.io
43
+ ```
44
+
45
+ No config, no API keys. You'll get a scored report showing what AI agents can see when they visit that site.
46
+
47
+ ### Example sites to try
48
+
49
+ Each of these exercises different parts of the scanner:
50
+
51
+ ```bash
52
+ # The classic OpenAPI demo — Swagger spec at a well-known path
53
+ npx milieu-cli scan petstore.swagger.io
54
+
55
+ # Rich structured data — JSON-LD and Schema.org markup
56
+ npx milieu-cli scan schema.org
57
+
58
+ # Minimal API service — clean reachability, few standards signals
59
+ npx milieu-cli scan httpbin.org
60
+ ```
61
+
62
+ Add `--verbose` to any scan to see individual check results and explanations:
63
+
64
+ ```bash
65
+ npx milieu-cli scan petstore.swagger.io --verbose
66
+ ```
67
+
68
+ Once you've seen how these score, scan your own site and compare.
69
+
24
70
  ## The 5 Bridges
25
71
 
26
72
  Milieu evaluates your product through five progressive bridges. Each one represents a layer of machine legibility that AI agents need, from "can I reach you?" to "can I trust you?"
@@ -28,7 +74,7 @@ Milieu evaluates your product through five progressive bridges. Each one represe
28
74
  | | Bridge | Question | What milieu checks | Score |
29
75
  |---|---|---|---|---|
30
76
  | 1 | **Reachability** | **Can agents reach you?** | HTTPS, HTTP status, robots.txt (RFC 9309), per-bot crawler policies (GPTBot, ClaudeBot, CCBot, Googlebot, Bingbot, PerplexityBot), meta robots, X-Robots-Tag | 0–100 |
31
- | 2 | **Standards** | **Can agents read you?** | OpenAPI spec, llms.txt, llms-full.txt, MCP endpoint, JSON-LD, Schema.org, security.txt, ai-plugin.json | 0–100 |
77
+ | 2 | **Standards** | **Can agents read you?** | OpenAPI spec, GraphQL introspection, XML sitemap, markdown content negotiation, llms.txt, llms-full.txt, MCP endpoint, JSON-LD, Schema.org, security.txt, ai-plugin.json | 0–100 |
32
78
  | 3 | **Separation** | **Can agents integrate with you?** | API endpoints, developer docs, SDK/package references, webhook support | Detection only* |
33
79
  | 4 | **Schema** | **Can agents use you correctly?** | Planned | — |
34
80
  | 5 | **Context** | **Can agents trust you?** | Planned | — |
@@ -39,7 +85,7 @@ The bridges are progressive: there's no point checking your OpenAPI spec (Bridge
39
85
 
40
86
  **Bridge 1 — Reachability** is the front door. Can AI agents get to your content at all? Are you blocking specific crawlers without realizing it? This is the most actionable bridge for most sites — many are unknowingly blocking GPTBot or ClaudeBot in their robots.txt.
41
87
 
42
- **Bridge 2 — Standards** is the shared language. Do you speak the protocols AI agents understand? OpenAPI specs, llms.txt, MCP endpoints, structured data — these are the machine-readable standards that let agents go beyond scraping your HTML.
88
+ **Bridge 2 — Standards** is the shared language. Do you speak the protocols AI agents understand? OpenAPI specs, GraphQL endpoints, XML sitemaps, markdown content negotiation, llms.txt, MCP endpoints, structured data — these are the machine-readable standards that let agents go beyond scraping your HTML. milieu also checks if your server returns markdown via HTTP content negotiation (`Accept: text/markdown`), which cuts agent token usage by ~80% compared to raw HTML.
43
89
 
44
90
  **Bridge 3 — Separation** is the developer surface. Do you have a clear API boundary? Developer docs? SDKs? Webhooks? This is where agents look to determine if your product is something they can build with, not just read from.
45
91
 
@@ -57,9 +103,9 @@ Each policy is checked individually — you might be allowing Googlebot but bloc
57
103
  ## Install
58
104
 
59
105
  ```bash
60
- npx milieu-cli scan stripe.com # one-off, no install
61
- npm install -g milieu-cli # global install
62
- milieu scan stripe.com # short alias after install
106
+ npx milieu-cli scan petstore.swagger.io # one-off, no install
107
+ npm install -g milieu-cli # global install
108
+ milieu scan petstore.swagger.io # short alias after install
63
109
  ```
64
110
 
65
111
  > Both `milieu` and `milieu-cli` work as commands after global install.
@@ -121,7 +167,7 @@ const options: ScanOptions = {
121
167
  silent: true, // suppress spinner output (recommended for library use)
122
168
  };
123
169
 
124
- const result = await scan("https://stripe.com", options);
170
+ const result = await scan("https://petstore.swagger.io", options);
125
171
 
126
172
  console.log(result.overallScore); // number (average of scored bridges)
127
173
  console.log(result.overallScoreLabel); // "pass" | "partial" | "fail"
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAS,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAyC5E;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CAwFvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAS,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAyC5E;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CA2FvB"}
@@ -70,6 +70,8 @@ export async function runReachabilityBridge(ctx) {
70
70
  const httpStatusCheck = checkHttpStatus(pageResponse);
71
71
  // 4. robots.txt fetch + parse
72
72
  const robotsResult = await checkRobotsTxt(ctx.domain, ctx.options.timeout);
73
+ // Store sitemap URLs for Bridge 2 consumption
74
+ ctx.shared.robotsSitemaps = robotsResult.parsed?.sitemaps ?? [];
73
75
  // 5. Crawler policies (uses parsed robots.txt data)
74
76
  let targetPath;
75
77
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEpE;;;;GAIG;AACH,SAAS,cAAc,CAAC,MAAe;IAIrC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,8EAA8E;QAC9E,IACE,KAAK,CAAC,IAAI;YACT,KAAK,CAAC,IAAgC,CAAC,MAAM,KAAK,MAAM,EACzD,CAAC;YACD,SAAS;QACX,CAAC;QAED,SAAS,IAAI,CAAC,CAAC;QACf,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,MAAM,IAAI,CAAC,CAAC;aACpC,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,GAAG,CAAC;QACnD,4BAA4B;IAC9B,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC;IAC3E,MAAM,UAAU,GACd,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1D,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAgB;IAEhB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,gCAAgC;IAChC,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtE,8BAA8B;IAC9B,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO;YACL,EAAE,EAAE,CAAC;YACL,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,CAAC;YACR,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC;YAC3B,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACjD,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,WAAW,CAAC,WAAW;SACrC,CAAC;IACJ,CAAC;IAED,wCAAwC;IACxC,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE;QAC9C,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO;KAC7B,CAAC,CAAC;IAEH,gEAAgE;IAChE,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC;QACpB,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC;QACxC,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC;IAChD,CAAC;IAED,2DAA2D;IAC3D,MAAM,eAAe,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;IAEtD,8BAA8B;IAC9B,MAAM,YAAY,GAAG,MAAM,cAAc,CACvC,GAAG,CAAC,MAAM,EACV,GAAG,CAAC,OAAO,CAAC,OAAO,CACpB,CAAC;IAEF,oDAAoD;IACpD,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,GAAG,CAAC;IACnB,CAAC;IACD,MAAM,aAAa,GAAG,uBAAuB,CAC3C,YAAY,CAAC,MAAM,EACnB,UAAU,CACX,CAAC;IAEF,sCAAsC;IACtC,IAAI,eAAsB,CAAC;IAC3B,IAAI,YAAmB,CAAC;IAExB,IAAI,YAAY,CAAC,EAAE,EAAE,CAAC;QACpB,eAAe,GAAG,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACrD,YAAY,GAAG,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACN,8EAA8E;QAC9E,eAAe,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QACtC,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAY;QACtB,WAAW,CAAC,KAAK;QACjB,eAAe;QACf,YAAY,CAAC,KAAK;QAClB,GAAG,aAAa;QAChB,eAAe;QACf,YAAY;KACb,CAAC;IAEF,qBAAqB;IACrB,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAErD,OAAO;QACL,EAAE,EAAE,CAAC;QACL,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,WAAW;QACnB,KAAK;QACL,UAAU;QACV,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;KAClD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/reachability/index.ts"],"names":[],"mappings":"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"}
@@ -2,13 +2,14 @@ import type { Check, ContentSource } from "../../core/types.js";
2
2
  /**
3
3
  * Detect API presence via multiple signals across content sources.
4
4
  *
5
- * Four signal sources:
5
+ * Five signal sources:
6
6
  * 1. OpenAPI spec detected by Bridge 2 (boolean from ctx.shared.openApiDetected)
7
- * 2. API-related response headers (X-RateLimit-*, X-Request-Id, etc.)
8
- * 3. HTML links containing /api/ paths (scanned from all content sources)
9
- * 4. Markdown links containing /api/ paths (scanned from all content sources)
7
+ * 2. GraphQL endpoint detected by Bridge 2 (boolean from ctx.shared.graphqlDetected)
8
+ * 3. API-related response headers (X-RateLimit-*, X-Request-Id, etc.)
9
+ * 4. HTML links containing /api/ paths (scanned from all content sources)
10
+ * 5. Markdown links containing /api/ paths (scanned from all content sources)
10
11
  *
11
12
  * Pure function -- no HTTP calls.
12
13
  */
13
- export declare function checkApiPresence(openApiDetected: boolean, sources: ContentSource[], headers: Record<string, string>): Check;
14
+ export declare function checkApiPresence(openApiDetected: boolean, sources: ContentSource[], headers: Record<string, string>, graphqlDetected?: boolean): Check;
14
15
  //# sourceMappingURL=api-presence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-presence.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8ChE;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,OAAO,EACxB,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,KAAK,CA0CP"}
1
+ {"version":3,"file":"api-presence.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA8ChE;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,OAAO,EACxB,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,eAAe,UAAQ,GACtB,KAAK,CA6CP"}
@@ -44,21 +44,25 @@ function scanApiLinksMarkdown(text) {
44
44
  /**
45
45
  * Detect API presence via multiple signals across content sources.
46
46
  *
47
- * Four signal sources:
47
+ * Five signal sources:
48
48
  * 1. OpenAPI spec detected by Bridge 2 (boolean from ctx.shared.openApiDetected)
49
- * 2. API-related response headers (X-RateLimit-*, X-Request-Id, etc.)
50
- * 3. HTML links containing /api/ paths (scanned from all content sources)
51
- * 4. Markdown links containing /api/ paths (scanned from all content sources)
49
+ * 2. GraphQL endpoint detected by Bridge 2 (boolean from ctx.shared.graphqlDetected)
50
+ * 3. API-related response headers (X-RateLimit-*, X-Request-Id, etc.)
51
+ * 4. HTML links containing /api/ paths (scanned from all content sources)
52
+ * 5. Markdown links containing /api/ paths (scanned from all content sources)
52
53
  *
53
54
  * Pure function -- no HTTP calls.
54
55
  */
55
- export function checkApiPresence(openApiDetected, sources, headers) {
56
+ export function checkApiPresence(openApiDetected, sources, headers, graphqlDetected = false) {
56
57
  const id = "api_presence";
57
58
  const label = "API Presence";
58
59
  const signals = [];
59
60
  // Signal 1: OpenAPI spec detected by Bridge 2
60
61
  if (openApiDetected)
61
62
  signals.push("OpenAPI spec");
63
+ // Signal 2: GraphQL endpoint detected by Bridge 2
64
+ if (graphqlDetected)
65
+ signals.push("GraphQL endpoint");
62
66
  // Signal 2: API-related response headers
63
67
  const apiHeaders = API_HEADERS.filter((h) => headers[h] !== undefined);
64
68
  if (apiHeaders.length > 0)
@@ -1 +1 @@
1
- {"version":3,"file":"api-presence.js","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-presence.js","sourceRoot":"","sources":["../../../src/bridges/separation/api-presence.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAM3F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CAyDvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAwB,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAM3F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CA0DvB"}
@@ -27,6 +27,7 @@ export async function runSeparationBridge(ctx) {
27
27
  const openApiDetected = ctx.shared.openApiDetected ?? false;
28
28
  const openApiHasWebhooks = ctx.shared.openApiHasWebhooks ?? false;
29
29
  const openApiHasCallbacks = ctx.shared.openApiHasCallbacks ?? false;
30
+ const graphqlDetected = ctx.shared.graphqlDetected ?? false;
30
31
  const llmsTxtBody = ctx.shared.llmsTxtBody ?? null;
31
32
  // Fire async developer docs probe first (non-blocking)
32
33
  const devDocsPromise = checkDeveloperDocs(ctx.baseUrl, pageBody, ctx.options.timeout);
@@ -42,7 +43,7 @@ export async function runSeparationBridge(ctx) {
42
43
  contentSources.push({ content: llmsTxtBody, source: "llms.txt" });
43
44
  contentSources.push(...devDocsResult.pages);
44
45
  // Run 3 synchronous pure-function checks with assembled content sources
45
- const apiPresenceCheck = checkApiPresence(openApiDetected, contentSources, pageHeaders);
46
+ const apiPresenceCheck = checkApiPresence(openApiDetected, contentSources, pageHeaders, graphqlDetected);
46
47
  const sdkRefsCheck = checkSdkReferences(contentSources);
47
48
  const webhookCheck = checkWebhookSupport(contentSources, {
48
49
  pageHeaders,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAgB;IAEhB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,QAAQ,GAAI,GAAG,CAAC,MAAM,CAAC,QAAmB,IAAI,EAAE,CAAC;IACvD,MAAM,WAAW,GACd,GAAG,CAAC,MAAM,CAAC,WAAsC,IAAI,EAAE,CAAC;IAC3D,MAAM,eAAe,GAAI,GAAG,CAAC,MAAM,CAAC,eAA2B,IAAI,KAAK,CAAC;IACzE,MAAM,kBAAkB,GAAI,GAAG,CAAC,MAAM,CAAC,kBAA8B,IAAI,KAAK,CAAC;IAC/E,MAAM,mBAAmB,GAAI,GAAG,CAAC,MAAM,CAAC,mBAA+B,IAAI,KAAK,CAAC;IACjF,MAAM,WAAW,GAAI,GAAG,CAAC,MAAM,CAAC,WAAkC,IAAI,IAAI,CAAC;IAE3E,uDAAuD;IACvD,MAAM,cAAc,GAAG,kBAAkB,CACvC,GAAG,CAAC,OAAO,EACX,QAAQ,EACR,GAAG,CAAC,OAAO,CAAC,OAAO,CACpB,CAAC;IAEF,qDAAqD;IACrD,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;IAE3C,gEAAgE;IAChE,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC;IAE/C,qDAAqD;IACrD,MAAM,cAAc,GAAoB,EAAE,CAAC;IAC3C,IAAI,QAAQ;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7E,IAAI,WAAW;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACnF,cAAc,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE5C,wEAAwE;IACxE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,eAAe,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;IACxF,MAAM,YAAY,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,mBAAmB,CAAC,cAAc,EAAE;QACvD,WAAW;QACX,kBAAkB;QAClB,mBAAmB;KACpB,CAAC,CAAC;IAEH,iCAAiC;IACjC,MAAM,MAAM,GAAY;QACtB,gBAAgB;QAChB,aAAa,CAAC,KAAK;QACnB,YAAY;QACZ,YAAY;KACb,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,CAAC;QACL,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,IAAI;QAChB,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;KAClD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/separation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAgB;IAEhB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEhC,4CAA4C;IAC5C,MAAM,QAAQ,GAAI,GAAG,CAAC,MAAM,CAAC,QAAmB,IAAI,EAAE,CAAC;IACvD,MAAM,WAAW,GACd,GAAG,CAAC,MAAM,CAAC,WAAsC,IAAI,EAAE,CAAC;IAC3D,MAAM,eAAe,GAAI,GAAG,CAAC,MAAM,CAAC,eAA2B,IAAI,KAAK,CAAC;IACzE,MAAM,kBAAkB,GAAI,GAAG,CAAC,MAAM,CAAC,kBAA8B,IAAI,KAAK,CAAC;IAC/E,MAAM,mBAAmB,GAAI,GAAG,CAAC,MAAM,CAAC,mBAA+B,IAAI,KAAK,CAAC;IACjF,MAAM,eAAe,GAAI,GAAG,CAAC,MAAM,CAAC,eAA2B,IAAI,KAAK,CAAC;IACzE,MAAM,WAAW,GAAI,GAAG,CAAC,MAAM,CAAC,WAAkC,IAAI,IAAI,CAAC;IAE3E,uDAAuD;IACvD,MAAM,cAAc,GAAG,kBAAkB,CACvC,GAAG,CAAC,OAAO,EACX,QAAQ,EACR,GAAG,CAAC,OAAO,CAAC,OAAO,CACpB,CAAC;IAEF,qDAAqD;IACrD,MAAM,aAAa,GAAG,MAAM,cAAc,CAAC;IAE3C,gEAAgE;IAChE,GAAG,CAAC,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC,KAAK,CAAC;IAE/C,qDAAqD;IACrD,MAAM,cAAc,GAAoB,EAAE,CAAC;IAC3C,IAAI,QAAQ;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IAC7E,IAAI,WAAW;QAAE,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACnF,cAAc,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAE5C,wEAAwE;IACxE,MAAM,gBAAgB,GAAG,gBAAgB,CAAC,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,CAAC,CAAC;IACzG,MAAM,YAAY,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,mBAAmB,CAAC,cAAc,EAAE;QACvD,WAAW;QACX,kBAAkB;QAClB,mBAAmB;KACpB,CAAC,CAAC;IAEH,iCAAiC;IACjC,MAAM,MAAM,GAAY;QACtB,gBAAgB;QAChB,aAAa,CAAC,KAAK;QACnB,YAAY;QACZ,YAAY;KACb,CAAC;IAEF,OAAO;QACL,EAAE,EAAE,CAAC;QACL,IAAI,EAAE,YAAY;QAClB,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,IAAI;QACX,UAAU,EAAE,IAAI;QAChB,MAAM;QACN,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;KAClD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Check } from "../../core/types.js";
2
+ export interface GraphqlResult {
3
+ check: Check;
4
+ detected: boolean;
5
+ }
6
+ /**
7
+ * Probe common GraphQL endpoint paths via POST introspection query.
8
+ *
9
+ * Detection strategy per path:
10
+ * 1. POST introspection query with Content-Type: application/json
11
+ * 2. Parse response:
12
+ * - pass: 200 + valid __schema in response
13
+ * - partial: 200 + errors mentioning "introspection" (disabled)
14
+ * - partial: 401/403 (auth required)
15
+ * - skip: 404, non-JSON, connection error
16
+ *
17
+ * Returns early on first successful detection (highest confidence first).
18
+ */
19
+ export declare function checkGraphql(baseUrl: string, timeout?: number): Promise<GraphqlResult>;
20
+ //# sourceMappingURL=graphql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../../src/bridges/standards/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAOjD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAgFD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CA4GxB"}
@@ -0,0 +1,174 @@
1
+ import { httpGet } from "../../utils/http-client.js";
2
+ // ---------------------------------------------------------------------------
3
+ // Constants
4
+ // ---------------------------------------------------------------------------
5
+ /** Common GraphQL endpoint paths */
6
+ const GRAPHQL_PATHS = [
7
+ "/graphql",
8
+ "/api/graphql",
9
+ "/graphql/v1",
10
+ "/api/v1/graphql",
11
+ "/gql",
12
+ ];
13
+ /** Minimal introspection query to confirm a GraphQL endpoint */
14
+ const INTROSPECTION_QUERY = JSON.stringify({
15
+ query: "{ __schema { queryType { name } mutationType { name } subscriptionType { name } } }",
16
+ });
17
+ /**
18
+ * Parse a successful introspection response body.
19
+ * Returns metadata if the response contains valid `data.__schema`,
20
+ * or null if the JSON doesn't match the expected shape.
21
+ */
22
+ function parseIntrospectionResponse(body) {
23
+ try {
24
+ const parsed = JSON.parse(body);
25
+ const schema = parsed?.data?.__schema;
26
+ if (!schema || typeof schema !== "object")
27
+ return null;
28
+ return {
29
+ queryType: schema.queryType?.name != null,
30
+ mutationType: schema.mutationType?.name != null,
31
+ subscriptionType: schema.subscriptionType?.name != null,
32
+ };
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ /**
39
+ * Check if a JSON response body indicates a GraphQL endpoint
40
+ * with introspection disabled (common security practice).
41
+ */
42
+ function isIntrospectionDisabled(body) {
43
+ try {
44
+ const parsed = JSON.parse(body);
45
+ if (!parsed?.errors || !Array.isArray(parsed.errors))
46
+ return false;
47
+ return parsed.errors.some((err) => typeof err.message === "string" &&
48
+ err.message.toLowerCase().includes("introspection"));
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ /** Returns true if response is a 401/403 HTTP error */
55
+ function isAuthRequired(statusCode) {
56
+ return statusCode === 401 || statusCode === 403;
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // Public API
60
+ // ---------------------------------------------------------------------------
61
+ /**
62
+ * Probe common GraphQL endpoint paths via POST introspection query.
63
+ *
64
+ * Detection strategy per path:
65
+ * 1. POST introspection query with Content-Type: application/json
66
+ * 2. Parse response:
67
+ * - pass: 200 + valid __schema in response
68
+ * - partial: 200 + errors mentioning "introspection" (disabled)
69
+ * - partial: 401/403 (auth required)
70
+ * - skip: 404, non-JSON, connection error
71
+ *
72
+ * Returns early on first successful detection (highest confidence first).
73
+ */
74
+ export async function checkGraphql(baseUrl, timeout) {
75
+ const id = "graphql_endpoint";
76
+ const label = "GraphQL Endpoint";
77
+ // Fire all probes in parallel
78
+ const responses = await Promise.all(GRAPHQL_PATHS.map((path) => httpGet(new URL(path, baseUrl).href, {
79
+ method: "POST",
80
+ timeout,
81
+ body: INTROSPECTION_QUERY,
82
+ headers: {
83
+ "Content-Type": "application/json",
84
+ Accept: "application/json",
85
+ },
86
+ })));
87
+ // Phase 1: Check for successful introspection (pass)
88
+ for (let i = 0; i < responses.length; i++) {
89
+ const response = responses[i];
90
+ if (!response.ok)
91
+ continue;
92
+ const introspection = parseIntrospectionResponse(response.body);
93
+ if (introspection) {
94
+ const capabilities = [];
95
+ if (introspection.queryType)
96
+ capabilities.push("query");
97
+ if (introspection.mutationType)
98
+ capabilities.push("mutation");
99
+ if (introspection.subscriptionType)
100
+ capabilities.push("subscription");
101
+ return {
102
+ check: {
103
+ id,
104
+ label,
105
+ status: "pass",
106
+ detail: `GraphQL endpoint at ${GRAPHQL_PATHS[i]} with ${capabilities.join(", ")} support`,
107
+ data: {
108
+ path: GRAPHQL_PATHS[i],
109
+ introspectionEnabled: true,
110
+ hasQueries: introspection.queryType,
111
+ hasMutations: introspection.mutationType,
112
+ hasSubscriptions: introspection.subscriptionType,
113
+ },
114
+ },
115
+ detected: true,
116
+ };
117
+ }
118
+ }
119
+ // Phase 2: Check for introspection-disabled endpoints (partial)
120
+ for (let i = 0; i < responses.length; i++) {
121
+ const response = responses[i];
122
+ if (!response.ok)
123
+ continue;
124
+ if (isIntrospectionDisabled(response.body)) {
125
+ return {
126
+ check: {
127
+ id,
128
+ label,
129
+ status: "partial",
130
+ detail: `GraphQL endpoint detected at ${GRAPHQL_PATHS[i]} (introspection disabled)`,
131
+ data: {
132
+ path: GRAPHQL_PATHS[i],
133
+ introspectionEnabled: false,
134
+ },
135
+ },
136
+ detected: true,
137
+ };
138
+ }
139
+ }
140
+ // Phase 3: Check for auth-protected endpoints (partial)
141
+ for (let i = 0; i < responses.length; i++) {
142
+ const response = responses[i];
143
+ if (response.ok)
144
+ continue;
145
+ if (response.error.kind === "http_error" &&
146
+ isAuthRequired(response.error.statusCode)) {
147
+ return {
148
+ check: {
149
+ id,
150
+ label,
151
+ status: "partial",
152
+ detail: `GraphQL endpoint detected at ${GRAPHQL_PATHS[i]} (authentication required)`,
153
+ data: {
154
+ path: GRAPHQL_PATHS[i],
155
+ introspectionEnabled: false,
156
+ protected: true,
157
+ },
158
+ },
159
+ detected: true,
160
+ };
161
+ }
162
+ }
163
+ // Phase 4: Nothing found
164
+ return {
165
+ check: {
166
+ id,
167
+ label,
168
+ status: "fail",
169
+ detail: "No GraphQL endpoint found",
170
+ },
171
+ detected: false,
172
+ };
173
+ }
174
+ //# sourceMappingURL=graphql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.js","sourceRoot":"","sources":["../../../src/bridges/standards/graphql.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAWrD,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,oCAAoC;AACpC,MAAM,aAAa,GAAG;IACpB,UAAU;IACV,cAAc;IACd,aAAa;IACb,iBAAiB;IACjB,MAAM;CACE,CAAC;AAEX,gEAAgE;AAChE,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC;IACzC,KAAK,EACH,qFAAqF;CACxF,CAAC,CAAC;AAYH;;;;GAIG;AACH,SAAS,0BAA0B,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;QACtC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAEvD,OAAO;YACL,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,IAAI,IAAI;YACzC,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,IAAI,IAAI,IAAI;YAC/C,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,IAAI,IAAI,IAAI;SACxD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,uBAAuB,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QAEnE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CACvB,CAAC,GAAyB,EAAE,EAAE,CAC5B,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;YAC/B,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CACtD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,uDAAuD;AACvD,SAAS,cAAc,CAAC,UAA8B;IACpD,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG,CAAC;AAClD,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,OAAe,EACf,OAAgB;IAEhB,MAAM,EAAE,GAAG,kBAAkB,CAAC;IAC9B,MAAM,KAAK,GAAG,kBAAkB,CAAC;IAEjC,8BAA8B;IAC9B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACzB,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE;QACnC,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;SAC3B;KACF,CAAC,CACH,CACF,CAAC;IAEF,qDAAqD;IACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,SAAS;QAE3B,MAAM,aAAa,GAAG,0BAA0B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAChE,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,YAAY,GAAa,EAAE,CAAC;YAClC,IAAI,aAAa,CAAC,SAAS;gBAAE,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,IAAI,aAAa,CAAC,YAAY;gBAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC9D,IAAI,aAAa,CAAC,gBAAgB;gBAAE,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAEtE,OAAO;gBACL,KAAK,EAAE;oBACL,EAAE;oBACF,KAAK;oBACL,MAAM,EAAE,MAAM;oBACd,MAAM,EAAE,uBAAuB,aAAa,CAAC,CAAC,CAAC,SAAS,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU;oBACzF,IAAI,EAAE;wBACJ,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;wBACtB,oBAAoB,EAAE,IAAI;wBAC1B,UAAU,EAAE,aAAa,CAAC,SAAS;wBACnC,YAAY,EAAE,aAAa,CAAC,YAAY;wBACxC,gBAAgB,EAAE,aAAa,CAAC,gBAAgB;qBACjD;iBACF;gBACD,QAAQ,EAAE,IAAI;aACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,SAAS;QAE3B,IAAI,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAO;gBACL,KAAK,EAAE;oBACL,EAAE;oBACF,KAAK;oBACL,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,gCAAgC,aAAa,CAAC,CAAC,CAAC,2BAA2B;oBACnF,IAAI,EAAE;wBACJ,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;wBACtB,oBAAoB,EAAE,KAAK;qBAC5B;iBACF;gBACD,QAAQ,EAAE,IAAI;aACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,QAAQ,CAAC,EAAE;YAAE,SAAS;QAE1B,IACE,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,YAAY;YACpC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,EACzC,CAAC;YACD,OAAO;gBACL,KAAK,EAAE;oBACL,EAAE;oBACF,KAAK;oBACL,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,gCAAgC,aAAa,CAAC,CAAC,CAAC,4BAA4B;oBACpF,IAAI,EAAE;wBACJ,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC;wBACtB,oBAAoB,EAAE,KAAK;wBAC3B,SAAS,EAAE,IAAI;qBAChB;iBACF;gBACD,QAAQ,EAAE,IAAI;aACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,OAAO;QACL,KAAK,EAAE;YACL,EAAE;YACF,KAAK;YACL,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,2BAA2B;SACpC;QACD,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC"}
@@ -2,12 +2,17 @@ import type { BridgeResult, ScanContext } from "../../core/types.js";
2
2
  /**
3
3
  * Run Bridge 2: Standards.
4
4
  *
5
- * Runs 8 checks:
6
- * - 6 independent HTTP probes in parallel (OpenAPI, llms.txt, llms-full.txt, MCP, security.txt, ai-plugin.json)
7
- * - 2 synchronous HTML-based checks (JSON-LD, Schema.org) using ctx.shared.pageBody from Bridge 1
5
+ * Runs 11 checks in two phases:
8
6
  *
9
- * Stores ctx.shared.openApiDetected for Bridge 3 consumption.
10
- * Stores ctx.shared.llmsTxtBody for downstream consumption.
7
+ * Phase 1 (parallel): Sitemap + Markdown negotiation + llms.txt + llms-full.txt + MCP + security.txt + ai-plugin.json
8
+ * Phase 2 (parallel): OpenAPI (fed sitemap API URLs as candidates) + GraphQL
9
+ * Synchronous: JSON-LD + Schema.org (from ctx.shared.pageBody)
10
+ *
11
+ * Two-phase execution is required because sitemap results feed into
12
+ * OpenAPI detection as candidate spec URLs.
13
+ *
14
+ * Stores ctx.shared.openApiDetected, ctx.shared.graphqlDetected,
15
+ * ctx.shared.sitemapUrls, and ctx.shared.llmsTxtBody for Bridge 3 consumption.
11
16
  */
12
17
  export declare function runStandardsBridge(ctx: ScanContext): Promise<BridgeResult>;
13
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/standards/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAS,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAiC5E;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CAyDvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/standards/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAS,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAoC5E;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,YAAY,CAAC,CAuEvB"}
@@ -4,10 +4,13 @@ import { checkMcpEndpoint } from "./mcp.js";
4
4
  import { checkJsonLd } from "./json-ld.js";
5
5
  import { checkSchemaOrg } from "./schema-org.js";
6
6
  import { checkSecurityTxt, checkAiPlugin } from "./well-known.js";
7
+ import { checkGraphql } from "./graphql.js";
8
+ import { checkSitemap } from "./sitemap.js";
9
+ import { checkMarkdownNegotiation } from "./markdown-negotiation.js";
7
10
  /**
8
11
  * Calculate bridge score from check results.
9
12
  * - Pass = 1 point, Partial = 0.5 points, Fail/Error = 0 points
10
- * - All 8 checks always count (no skip concept in Bridge 2)
13
+ * - All checks always count (no skip concept in Bridge 2)
11
14
  */
12
15
  function calculateScore(checks) {
13
16
  let points = 0;
@@ -27,37 +30,54 @@ function calculateScore(checks) {
27
30
  /**
28
31
  * Run Bridge 2: Standards.
29
32
  *
30
- * Runs 8 checks:
31
- * - 6 independent HTTP probes in parallel (OpenAPI, llms.txt, llms-full.txt, MCP, security.txt, ai-plugin.json)
32
- * - 2 synchronous HTML-based checks (JSON-LD, Schema.org) using ctx.shared.pageBody from Bridge 1
33
+ * Runs 11 checks in two phases:
33
34
  *
34
- * Stores ctx.shared.openApiDetected for Bridge 3 consumption.
35
- * Stores ctx.shared.llmsTxtBody for downstream consumption.
35
+ * Phase 1 (parallel): Sitemap + Markdown negotiation + llms.txt + llms-full.txt + MCP + security.txt + ai-plugin.json
36
+ * Phase 2 (parallel): OpenAPI (fed sitemap API URLs as candidates) + GraphQL
37
+ * Synchronous: JSON-LD + Schema.org (from ctx.shared.pageBody)
38
+ *
39
+ * Two-phase execution is required because sitemap results feed into
40
+ * OpenAPI detection as candidate spec URLs.
41
+ *
42
+ * Stores ctx.shared.openApiDetected, ctx.shared.graphqlDetected,
43
+ * ctx.shared.sitemapUrls, and ctx.shared.llmsTxtBody for Bridge 3 consumption.
36
44
  */
37
45
  export async function runStandardsBridge(ctx) {
38
46
  const start = performance.now();
39
- // Get page body from shared context (set by Bridge 1)
47
+ // Get shared context from Bridge 1
40
48
  const pageBody = ctx.shared.pageBody ?? "";
41
- // Run all independent HTTP probes in parallel
42
- const [openApiResult, llmsTxtResult, llmsFullTxtCheck, mcpCheck, securityTxtCheck, aiPluginCheck,] = await Promise.all([
43
- checkOpenApi(ctx.baseUrl, ctx.options.timeout),
49
+ const robotsSitemaps = ctx.shared.robotsSitemaps ?? [];
50
+ // Phase 1: Sitemap + Markdown negotiation + independent HTTP probes (parallel)
51
+ const [sitemapResult, markdownResult, llmsTxtResult, llmsFullTxtCheck, mcpCheck, securityTxtCheck, aiPluginCheck,] = await Promise.all([
52
+ checkSitemap(ctx.baseUrl, robotsSitemaps, ctx.options.timeout),
53
+ checkMarkdownNegotiation(ctx.baseUrl, ctx.options.timeout),
44
54
  checkLlmsTxt(ctx.baseUrl, ctx.options.timeout),
45
55
  checkLlmsFullTxt(ctx.baseUrl, ctx.options.timeout),
46
56
  checkMcpEndpoint(ctx.baseUrl, ctx.options.timeout),
47
57
  checkSecurityTxt(ctx.baseUrl, ctx.options.timeout),
48
58
  checkAiPlugin(ctx.baseUrl, ctx.options.timeout),
49
59
  ]);
50
- // Run HTML-based checks (synchronous, no HTTP)
60
+ // Phase 2: OpenAPI (with sitemap API URLs) + GraphQL (parallel)
61
+ const [openApiResult, graphqlResult] = await Promise.all([
62
+ checkOpenApi(ctx.baseUrl, ctx.options.timeout, sitemapResult.apiRelevantUrls),
63
+ checkGraphql(ctx.baseUrl, ctx.options.timeout),
64
+ ]);
65
+ // Synchronous HTML-based checks (no HTTP)
51
66
  const jsonLdCheck = checkJsonLd(pageBody);
52
67
  const schemaOrgCheck = checkSchemaOrg(pageBody, jsonLdCheck);
53
- // Store OpenAPI detection result for Bridge 3
68
+ // Store detection results for Bridge 3
54
69
  ctx.shared.openApiDetected = openApiResult.detected;
55
70
  ctx.shared.openApiHasWebhooks = openApiResult.hasWebhooks;
56
71
  ctx.shared.openApiHasCallbacks = openApiResult.hasCallbacks;
72
+ ctx.shared.graphqlDetected = graphqlResult.detected;
73
+ ctx.shared.sitemapUrls = sitemapResult.urls;
57
74
  ctx.shared.llmsTxtBody = llmsTxtResult.body;
58
- // Collect all 8 checks in order
75
+ // Collect all 11 checks in order
59
76
  const checks = [
60
77
  openApiResult.check,
78
+ graphqlResult.check,
79
+ sitemapResult.check,
80
+ markdownResult.check,
61
81
  llmsTxtResult.check,
62
82
  llmsFullTxtCheck,
63
83
  mcpCheck,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/standards/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/standards/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Check } from "../../core/types.js";
2
+ export interface MarkdownNegotiationResult {
3
+ check: Check;
4
+ /** Whether the server supports markdown content negotiation */
5
+ supported: boolean;
6
+ }
7
+ /**
8
+ * Detect whether a site supports markdown content negotiation for AI agents.
9
+ *
10
+ * Three signals checked:
11
+ * 1. **Markdown response** — Send `Accept: text/markdown` to homepage,
12
+ * check if response has `content-type: text/markdown`
13
+ * 2. **x-markdown-tokens header** — Indicates the server is markdown-aware
14
+ * and provides token count estimates
15
+ * 3. **Content-Signal header** — AI permission directives like
16
+ * `ai-train=yes, ai-input=yes, search=yes`
17
+ *
18
+ * Status mapping:
19
+ * - pass: Server returns markdown when requested (content negotiation works)
20
+ * - partial: Content-Signal header present but no markdown negotiation,
21
+ * or x-markdown-tokens header found
22
+ * - fail: No markdown support detected
23
+ */
24
+ export declare function checkMarkdownNegotiation(baseUrl: string, timeout?: number): Promise<MarkdownNegotiationResult>;
25
+ //# sourceMappingURL=markdown-negotiation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-negotiation.d.ts","sourceRoot":"","sources":["../../../src/bridges/standards/markdown-negotiation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAOjD,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,KAAK,CAAC;IACb,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;CACpB;AA6CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,yBAAyB,CAAC,CAoFpC"}