@houtini/seo-audit-console 0.2.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 (166) hide show
  1. package/LICENSE +92 -0
  2. package/README.md +211 -0
  3. package/dist/audit/checks.d.ts +35 -0
  4. package/dist/audit/checks.d.ts.map +1 -0
  5. package/dist/audit/checks.js +1475 -0
  6. package/dist/audit/checks.js.map +1 -0
  7. package/dist/audit/drift.d.ts +40 -0
  8. package/dist/audit/drift.d.ts.map +1 -0
  9. package/dist/audit/drift.js +148 -0
  10. package/dist/audit/drift.js.map +1 -0
  11. package/dist/audit/engine.d.ts +33 -0
  12. package/dist/audit/engine.d.ts.map +1 -0
  13. package/dist/audit/engine.js +186 -0
  14. package/dist/audit/engine.js.map +1 -0
  15. package/dist/audit/opportunities.d.ts +23 -0
  16. package/dist/audit/opportunities.d.ts.map +1 -0
  17. package/dist/audit/opportunities.js +149 -0
  18. package/dist/audit/opportunities.js.map +1 -0
  19. package/dist/audit/report.d.ts +11 -0
  20. package/dist/audit/report.d.ts.map +1 -0
  21. package/dist/audit/report.js +59 -0
  22. package/dist/audit/report.js.map +1 -0
  23. package/dist/audit/schema-validate.d.ts +35 -0
  24. package/dist/audit/schema-validate.d.ts.map +1 -0
  25. package/dist/audit/schema-validate.js +293 -0
  26. package/dist/audit/schema-validate.js.map +1 -0
  27. package/dist/audit/templates.d.ts +43 -0
  28. package/dist/audit/templates.d.ts.map +1 -0
  29. package/dist/audit/templates.js +129 -0
  30. package/dist/audit/templates.js.map +1 -0
  31. package/dist/audit/topicGaps.d.ts +42 -0
  32. package/dist/audit/topicGaps.d.ts.map +1 -0
  33. package/dist/audit/topicGaps.js +181 -0
  34. package/dist/audit/topicGaps.js.map +1 -0
  35. package/dist/core/AuditDatabase.d.ts +33 -0
  36. package/dist/core/AuditDatabase.d.ts.map +1 -0
  37. package/dist/core/AuditDatabase.js +481 -0
  38. package/dist/core/AuditDatabase.js.map +1 -0
  39. package/dist/core/Backlinks.d.ts +33 -0
  40. package/dist/core/Backlinks.d.ts.map +1 -0
  41. package/dist/core/Backlinks.js +110 -0
  42. package/dist/core/Backlinks.js.map +1 -0
  43. package/dist/core/Crawler.d.ts +23 -0
  44. package/dist/core/Crawler.d.ts.map +1 -0
  45. package/dist/core/Crawler.js +588 -0
  46. package/dist/core/Crawler.js.map +1 -0
  47. package/dist/core/DataForSeoClient.d.ts +86 -0
  48. package/dist/core/DataForSeoClient.d.ts.map +1 -0
  49. package/dist/core/DataForSeoClient.js +232 -0
  50. package/dist/core/DataForSeoClient.js.map +1 -0
  51. package/dist/core/Entities.d.ts +23 -0
  52. package/dist/core/Entities.d.ts.map +1 -0
  53. package/dist/core/Entities.js +62 -0
  54. package/dist/core/Entities.js.map +1 -0
  55. package/dist/core/GscClient.d.ts +22 -0
  56. package/dist/core/GscClient.d.ts.map +1 -0
  57. package/dist/core/GscClient.js +93 -0
  58. package/dist/core/GscClient.js.map +1 -0
  59. package/dist/core/GscSync.d.ts +20 -0
  60. package/dist/core/GscSync.d.ts.map +1 -0
  61. package/dist/core/GscSync.js +133 -0
  62. package/dist/core/GscSync.js.map +1 -0
  63. package/dist/core/JobManager.d.ts +30 -0
  64. package/dist/core/JobManager.d.ts.map +1 -0
  65. package/dist/core/JobManager.js +68 -0
  66. package/dist/core/JobManager.js.map +1 -0
  67. package/dist/core/RankTracker.d.ts +25 -0
  68. package/dist/core/RankTracker.d.ts.map +1 -0
  69. package/dist/core/RankTracker.js +78 -0
  70. package/dist/core/RankTracker.js.map +1 -0
  71. package/dist/core/Refresh.d.ts +32 -0
  72. package/dist/core/Refresh.d.ts.map +1 -0
  73. package/dist/core/Refresh.js +73 -0
  74. package/dist/core/Refresh.js.map +1 -0
  75. package/dist/core/UrlInspector.d.ts +22 -0
  76. package/dist/core/UrlInspector.d.ts.map +1 -0
  77. package/dist/core/UrlInspector.js +92 -0
  78. package/dist/core/UrlInspector.js.map +1 -0
  79. package/dist/core/WikidataClient.d.ts +19 -0
  80. package/dist/core/WikidataClient.d.ts.map +1 -0
  81. package/dist/core/WikidataClient.js +59 -0
  82. package/dist/core/WikidataClient.js.map +1 -0
  83. package/dist/core/agentReadiness.d.ts +34 -0
  84. package/dist/core/agentReadiness.d.ts.map +1 -0
  85. package/dist/core/agentReadiness.js +119 -0
  86. package/dist/core/agentReadiness.js.map +1 -0
  87. package/dist/core/ctrModel.d.ts +2 -0
  88. package/dist/core/ctrModel.d.ts.map +1 -0
  89. package/dist/core/ctrModel.js +6 -0
  90. package/dist/core/ctrModel.js.map +1 -0
  91. package/dist/core/dashboardData.d.ts +312 -0
  92. package/dist/core/dashboardData.d.ts.map +1 -0
  93. package/dist/core/dashboardData.js +550 -0
  94. package/dist/core/dashboardData.js.map +1 -0
  95. package/dist/core/dataStorage.d.ts +42 -0
  96. package/dist/core/dataStorage.d.ts.map +1 -0
  97. package/dist/core/dataStorage.js +193 -0
  98. package/dist/core/dataStorage.js.map +1 -0
  99. package/dist/core/draftBrief.d.ts +27 -0
  100. package/dist/core/draftBrief.d.ts.map +1 -0
  101. package/dist/core/draftBrief.js +69 -0
  102. package/dist/core/draftBrief.js.map +1 -0
  103. package/dist/core/extract.d.ts +67 -0
  104. package/dist/core/extract.d.ts.map +1 -0
  105. package/dist/core/extract.js +262 -0
  106. package/dist/core/extract.js.map +1 -0
  107. package/dist/core/gscFreshness.d.ts +18 -0
  108. package/dist/core/gscFreshness.d.ts.map +1 -0
  109. package/dist/core/gscFreshness.js +32 -0
  110. package/dist/core/gscFreshness.js.map +1 -0
  111. package/dist/core/linkGraph.d.ts +19 -0
  112. package/dist/core/linkGraph.d.ts.map +1 -0
  113. package/dist/core/linkGraph.js +125 -0
  114. package/dist/core/linkGraph.js.map +1 -0
  115. package/dist/core/passageScore.d.ts +19 -0
  116. package/dist/core/passageScore.d.ts.map +1 -0
  117. package/dist/core/passageScore.js +59 -0
  118. package/dist/core/passageScore.js.map +1 -0
  119. package/dist/core/paths.d.ts +5 -0
  120. package/dist/core/paths.d.ts.map +1 -0
  121. package/dist/core/paths.js +15 -0
  122. package/dist/core/paths.js.map +1 -0
  123. package/dist/core/queryData.d.ts +35 -0
  124. package/dist/core/queryData.d.ts.map +1 -0
  125. package/dist/core/queryData.js +200 -0
  126. package/dist/core/queryData.js.map +1 -0
  127. package/dist/core/reranker.d.ts +8 -0
  128. package/dist/core/reranker.d.ts.map +1 -0
  129. package/dist/core/reranker.js +68 -0
  130. package/dist/core/reranker.js.map +1 -0
  131. package/dist/core/robots.d.ts +11 -0
  132. package/dist/core/robots.d.ts.map +1 -0
  133. package/dist/core/robots.js +76 -0
  134. package/dist/core/robots.js.map +1 -0
  135. package/dist/core/sitemap.d.ts +15 -0
  136. package/dist/core/sitemap.d.ts.map +1 -0
  137. package/dist/core/sitemap.js +100 -0
  138. package/dist/core/sitemap.js.map +1 -0
  139. package/dist/core/sql.d.ts +6 -0
  140. package/dist/core/sql.d.ts.map +1 -0
  141. package/dist/core/sql.js +6 -0
  142. package/dist/core/sql.js.map +1 -0
  143. package/dist/core/types.d.ts +22 -0
  144. package/dist/core/types.d.ts.map +1 -0
  145. package/dist/core/types.js +2 -0
  146. package/dist/core/types.js.map +1 -0
  147. package/dist/core/url-key.d.ts +39 -0
  148. package/dist/core/url-key.d.ts.map +1 -0
  149. package/dist/core/url-key.js +106 -0
  150. package/dist/core/url-key.js.map +1 -0
  151. package/dist/generators/index.d.ts +45 -0
  152. package/dist/generators/index.d.ts.map +1 -0
  153. package/dist/generators/index.js +184 -0
  154. package/dist/generators/index.js.map +1 -0
  155. package/dist/index.d.ts +3 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +10 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/server.d.ts +7 -0
  160. package/dist/server.d.ts.map +1 -0
  161. package/dist/server.js +1387 -0
  162. package/dist/server.js.map +1 -0
  163. package/dist/src/ui/dashboard.html +347 -0
  164. package/dist/src/ui/sync-progress.html +104 -0
  165. package/package.json +101 -0
  166. package/server.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UrlInspector.js","sourceRoot":"","sources":["../../src/core/UrlInspector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export declare class WikidataClient {
2
+ private readonly cache;
3
+ private readonly ttlMs;
4
+ constructor(cacheDbPath: string, ttlDays?: number);
5
+ private getJson;
6
+ /** Best entity match for free text (e.g. an H1). Returns null if nothing matches. */
7
+ searchEntity(query: string, language?: string): Promise<{
8
+ id: string;
9
+ label: string;
10
+ description?: string;
11
+ } | null>;
12
+ /** Parent/whole entities of a QID: P279 (subclass of) + P361 (part of). */
13
+ relatedEntities(qid: string): Promise<{
14
+ related: string;
15
+ relation: string;
16
+ }[]>;
17
+ close(): void;
18
+ }
19
+ //# sourceMappingURL=WikidataClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WikidataClient.d.ts","sourceRoot":"","sources":["../../src/core/WikidataClient.ts"],"names":[],"mappings":"AAYA,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,WAAW,EAAE,MAAM,EAAE,OAAO,SAAK;YAQ/B,OAAO;IAWrB,qFAAqF;IAC/E,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAO,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IASvH,2EAA2E;IACrE,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAapF,KAAK,IAAI,IAAI;CACd"}
@@ -0,0 +1,59 @@
1
+ import Database from 'better-sqlite3';
2
+ import { mkdirSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ /**
5
+ * Minimal Wikidata client over the PUBLIC API (no auth) — entity search + claims — with a
6
+ * long SQLite cache (entities are stable). Used by the 6d entity layer. Wikidata asks for a
7
+ * descriptive User-Agent.
8
+ */
9
+ const UA = 'seo-audit-console/0.1 (https://github.com/houtini-ai/seo-audit-console)';
10
+ const API = 'https://www.wikidata.org/w/api.php';
11
+ export class WikidataClient {
12
+ cache;
13
+ ttlMs;
14
+ constructor(cacheDbPath, ttlDays = 45) {
15
+ this.ttlMs = ttlDays * 86400000;
16
+ mkdirSync(dirname(cacheDbPath), { recursive: true });
17
+ this.cache = new Database(cacheDbPath);
18
+ this.cache.pragma('journal_mode = WAL');
19
+ this.cache.exec(`CREATE TABLE IF NOT EXISTS wd_cache (url TEXT PRIMARY KEY, body TEXT NOT NULL, fetched_at TEXT NOT NULL)`);
20
+ }
21
+ async getJson(url) {
22
+ const row = this.cache.prepare('SELECT body, fetched_at FROM wd_cache WHERE url = ?').get(url);
23
+ if (row && Date.now() - Date.parse(row.fetched_at) < this.ttlMs)
24
+ return JSON.parse(row.body);
25
+ const res = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' }, signal: AbortSignal.timeout(15000) });
26
+ if (!res.ok)
27
+ throw new Error(`Wikidata ${res.status} for ${url}`);
28
+ const json = await res.json();
29
+ this.cache.prepare(`INSERT INTO wd_cache (url, body, fetched_at) VALUES (?,?,datetime('now'))
30
+ ON CONFLICT(url) DO UPDATE SET body=excluded.body, fetched_at=datetime('now')`).run(url, JSON.stringify(json));
31
+ return json;
32
+ }
33
+ /** Best entity match for free text (e.g. an H1). Returns null if nothing matches. */
34
+ async searchEntity(query, language = 'en') {
35
+ const q = query.trim();
36
+ if (!q)
37
+ return null;
38
+ const url = `${API}?action=wbsearchentities&format=json&type=item&limit=1&language=${encodeURIComponent(language)}&uselang=${encodeURIComponent(language)}&search=${encodeURIComponent(q)}`;
39
+ const j = await this.getJson(url);
40
+ const hit = j?.search?.[0];
41
+ return hit?.id ? { id: hit.id, label: hit.label ?? q, description: hit.description } : null;
42
+ }
43
+ /** Parent/whole entities of a QID: P279 (subclass of) + P361 (part of). */
44
+ async relatedEntities(qid) {
45
+ const out = [];
46
+ for (const [prop, relation] of [['P279', 'subclass_of'], ['P361', 'part_of']]) {
47
+ const url = `${API}?action=wbgetclaims&format=json&entity=${qid}&property=${prop}`;
48
+ const j = await this.getJson(url);
49
+ for (const cl of j?.claims?.[prop] ?? []) {
50
+ const id = cl?.mainsnak?.datavalue?.value?.id;
51
+ if (id)
52
+ out.push({ related: id, relation });
53
+ }
54
+ }
55
+ return out;
56
+ }
57
+ close() { this.cache.close(); }
58
+ }
59
+ //# sourceMappingURL=WikidataClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WikidataClient.js","sourceRoot":"","sources":["../../src/core/WikidataClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Agent-readiness checker — is a site ready for AI agents to discover and use it? Models the
3
+ * signals from Cloudflare's "Is Your Site Agent-Ready?" (isitagentready.com): Discoverability,
4
+ * Content, Bot-Access-Control, Capabilities. Each check is a cheap HTTP probe of a fixed path or
5
+ * header (deterministic — cite the bytes). Returns a 0–100 score, a level, and a per-check
6
+ * checklist with copy-paste-ready fixes. The agentic-SEO/GEO frontier — almost no audit tool
7
+ * does this. (Reference impl of the SERVING side: c:\dev\yubnub.)
8
+ */
9
+ export type AgentCategory = 'Discoverability' | 'Content' | 'Bot access control' | 'Capabilities';
10
+ export interface AgentCheck {
11
+ id: string;
12
+ category: AgentCategory;
13
+ label: string;
14
+ present: boolean;
15
+ detail: string;
16
+ fix: string;
17
+ }
18
+ export interface AgentReadiness {
19
+ siteUrl: string;
20
+ origin: string;
21
+ score: number;
22
+ level: string;
23
+ byCategory: {
24
+ category: AgentCategory;
25
+ passed: number;
26
+ total: number;
27
+ }[];
28
+ checks: AgentCheck[];
29
+ commerceNote: string;
30
+ }
31
+ export declare function checkAgentReadiness(siteUrl: string): Promise<AgentReadiness>;
32
+ /** Human-readable markdown report (for the tool result). */
33
+ export declare function buildAgentReadinessMarkdown(r: AgentReadiness): string;
34
+ //# sourceMappingURL=agentReadiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentReadiness.d.ts","sourceRoot":"","sources":["../../src/core/agentReadiness.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,SAAS,GAAG,oBAAoB,GAAG,cAAc,CAAC;AAClG,MAAM,WAAW,UAAU;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE;AACjI,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAC9D,UAAU,EAAE;QAAE,QAAQ,EAAE,aAAa,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzE,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAiCD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAmDlF;AAED,4DAA4D;AAC5D,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAerE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Agent-readiness checker — is a site ready for AI agents to discover and use it? Models the
3
+ * signals from Cloudflare's "Is Your Site Agent-Ready?" (isitagentready.com): Discoverability,
4
+ * Content, Bot-Access-Control, Capabilities. Each check is a cheap HTTP probe of a fixed path or
5
+ * header (deterministic — cite the bytes). Returns a 0–100 score, a level, and a per-check
6
+ * checklist with copy-paste-ready fixes. The agentic-SEO/GEO frontier — almost no audit tool
7
+ * does this. (Reference impl of the SERVING side: c:\dev\yubnub.)
8
+ */
9
+ const UA = 'Mozilla/5.0 (compatible; SEOAuditConsole/1.0; +https://houtini.com)';
10
+ // The AI crawlers a site would name in robots.txt if it had AI-specific rules.
11
+ const AI_BOTS = /(GPTBot|OAI-SearchBot|ChatGPT-User|ClaudeBot|Claude-Web|anthropic-ai|Google-Extended|PerplexityBot|CCBot|Bytespider|Amazonbot|Applebot-Extended|cohere-ai|Meta-ExternalAgent|DuckAssistBot)/i;
12
+ async function probe(url, accept = '*/*') {
13
+ try {
14
+ const res = await fetch(url, { headers: { 'user-agent': UA, accept }, redirect: 'follow', signal: AbortSignal.timeout(8000) });
15
+ const ct = (res.headers.get('content-type') ?? '').toLowerCase();
16
+ const text = res.ok ? (await res.text()).slice(0, 20000) : '';
17
+ return { ok: res.ok, status: res.status, ct, text, link: res.headers.get('link') };
18
+ }
19
+ catch {
20
+ return { ok: false, status: 0, ct: '', text: '', link: null };
21
+ }
22
+ }
23
+ // `res.ok` alone is not "present": a SPA/CDN with a catch-all 200 route serves its HTML
24
+ // shell for /llms.txt, /agents.md and every /.well-known/* probe — the exact soft-404
25
+ // pattern the audit's own soft-404-shell check exists to catch. Validate the body shape.
26
+ const looksHtml = (p) => /text\/html/.test(p.ct) || /^\s*(<!doctype\s|<html[\s>])/i.test(p.text);
27
+ const textReal = (p) => p.ok && p.text.trim().length > 0 && !looksHtml(p);
28
+ const jsonReal = (p) => {
29
+ if (!p.ok || looksHtml(p))
30
+ return false;
31
+ if (/json/.test(p.ct))
32
+ return true;
33
+ try {
34
+ JSON.parse(p.text);
35
+ return true;
36
+ }
37
+ catch {
38
+ return false;
39
+ }
40
+ };
41
+ const xmlReal = (p) => p.ok && (/xml/.test(p.ct) || /<\?xml|<(urlset|sitemapindex)[\s>]/i.test(p.text));
42
+ function originOf(siteUrl) {
43
+ const bare = siteUrl.replace(/^sc-domain:/, '');
44
+ try {
45
+ return new URL(/^https?:\/\//.test(bare) ? bare : `https://${bare}`).origin;
46
+ }
47
+ catch {
48
+ return `https://${bare.replace(/\/.*$/, '')}`;
49
+ }
50
+ }
51
+ export async function checkAgentReadiness(siteUrl) {
52
+ const origin = originOf(siteUrl);
53
+ const u = (p) => origin + p;
54
+ const [robots, sitemap, home, homeMd, llms, agentsMd, mcpCard, skills, apiCatalog, oauthPR, oauthAS, webBotAuth] = await Promise.all([
55
+ probe(u('/robots.txt')), probe(u('/sitemap.xml')), probe(u('/')), probe(u('/'), 'text/markdown'),
56
+ probe(u('/llms.txt')), probe(u('/agents.md')), probe(u('/.well-known/mcp/server-card.json')),
57
+ probe(u('/.well-known/agent-skills/index.json')), probe(u('/.well-known/api-catalog')),
58
+ probe(u('/.well-known/oauth-protected-resource')), probe(u('/.well-known/oauth-authorization-server')),
59
+ probe(u('/.well-known/http-message-signatures-directory')),
60
+ ]);
61
+ const robotsReal = textReal(robots);
62
+ const robotsTxt = robotsReal ? robots.text : '';
63
+ const hasAiRules = robotsReal && AI_BOTS.test(robotsTxt);
64
+ const hasContentSignals = robotsReal && /content-signal\s*:/i.test(robotsTxt);
65
+ const hasSitemapDirective = robotsReal && /^\s*sitemap\s*:/im.test(robotsTxt);
66
+ const mdNegotiated = homeMd.ok && /text\/markdown/.test(homeMd.ct);
67
+ const sitemapReal = xmlReal(sitemap);
68
+ const llmsReal = textReal(llms);
69
+ const agentsMdReal = textReal(agentsMd);
70
+ const checks = [
71
+ { id: 'robots-txt', category: 'Discoverability', present: robotsReal, label: 'robots.txt present', detail: robotsReal ? `200 (${robotsTxt.length} bytes)` : robots.ok ? 'returns HTML (catch-all route, not a real robots.txt)' : `not found (${robots.status})`, fix: 'Serve a /robots.txt — the base discovery file every crawler and agent checks first.' },
72
+ { id: 'sitemap', category: 'Discoverability', present: sitemapReal || hasSitemapDirective, label: 'XML sitemap', detail: sitemapReal ? 'sitemap.xml found' : hasSitemapDirective ? 'declared in robots.txt' : sitemap.ok ? 'returns non-XML (catch-all route)' : 'none found', fix: 'Publish /sitemap.xml and reference it with a `Sitemap:` line in robots.txt.' },
73
+ { id: 'link-headers', category: 'Discoverability', present: !!home.link, label: 'Link response headers (RFC 8288)', detail: home.link ? home.link.slice(0, 120) : 'no Link header on the homepage', fix: 'Emit Link: headers pointing agents to your API/docs/llms.txt (rel="describedby" etc.).' },
74
+ { id: 'llms-txt', category: 'Content', present: llmsReal, label: 'llms.txt', detail: llmsReal ? `200 (${llms.text.length} bytes)` : llms.ok ? 'returns HTML (catch-all route, not a real llms.txt)' : `not found (${llms.status})`, fix: 'Add /llms.txt — a plain-text reading list pointing agents at your most useful pages/docs.' },
75
+ { id: 'agents-md', category: 'Content', present: agentsMdReal, label: 'agents.md', detail: agentsMdReal ? `200 (${agentsMd.text.length} bytes)` : agentsMd.ok ? 'returns HTML (catch-all route, not a real agents.md)' : `not found (${agentsMd.status})`, fix: 'Add /agents.md describing how agents should use your site (allowed actions, endpoints, etiquette).' },
76
+ { id: 'markdown-negotiation', category: 'Content', present: mdNegotiated, label: 'Markdown content negotiation', detail: mdNegotiated ? 'serves text/markdown on Accept' : 'returns HTML only', fix: 'Honour `Accept: text/markdown` (or an index.md fallback) so agents read clean content without parsing HTML.' },
77
+ { id: 'ai-bot-rules', category: 'Bot access control', present: hasAiRules, label: 'AI-bot rules in robots.txt', detail: hasAiRules ? 'names AI crawlers (GPTBot/ClaudeBot/…)' : 'no AI-specific user-agents', fix: 'Add explicit allow/disallow rules for AI user-agents (GPTBot, ClaudeBot, Google-Extended, PerplexityBot, CCBot…).' },
78
+ { id: 'content-signals', category: 'Bot access control', present: hasContentSignals, label: 'Content Signals', detail: hasContentSignals ? 'Content-Signal directives present' : 'none', fix: 'Add Cloudflare Content-Signal directives (ai-train / ai-input / search) to robots.txt to state how your content may be used.' },
79
+ { id: 'web-bot-auth', category: 'Bot access control', present: jsonReal(webBotAuth), label: 'Web Bot Auth', detail: jsonReal(webBotAuth) ? 'signature directory present' : 'not found', fix: 'Publish /.well-known/http-message-signatures-directory so well-behaved agents can authenticate.' },
80
+ { id: 'mcp-server-card', category: 'Capabilities', present: jsonReal(mcpCard), label: 'MCP server card', detail: jsonReal(mcpCard) ? 'server-card.json present' : 'not found', fix: 'Expose /.well-known/mcp/server-card.json so agents can discover your MCP server + tools.' },
81
+ { id: 'agent-skills', category: 'Capabilities', present: jsonReal(skills), label: 'Agent Skills', detail: jsonReal(skills) ? 'agent-skills index present' : 'not found', fix: 'Declare capabilities at /.well-known/agent-skills/index.json (agentskills.io).' },
82
+ { id: 'api-catalog', category: 'Capabilities', present: jsonReal(apiCatalog), label: 'API Catalog (RFC 9727)', detail: jsonReal(apiCatalog) ? 'api-catalog present' : 'not found', fix: 'Publish /.well-known/api-catalog listing your machine-usable APIs.' },
83
+ { id: 'oauth-discovery', category: 'Capabilities', present: jsonReal(oauthPR) || jsonReal(oauthAS), label: 'OAuth discovery (RFC 8414/9728)', detail: (jsonReal(oauthPR) || jsonReal(oauthAS)) ? 'oauth metadata present' : 'not found', fix: 'If agents need authenticated actions, expose OAuth metadata at /.well-known/oauth-protected-resource (RFC 9728).' },
84
+ ];
85
+ const cats = ['Discoverability', 'Content', 'Bot access control', 'Capabilities'];
86
+ const byCategory = cats.map(category => {
87
+ const cc = checks.filter(c => c.category === category);
88
+ return { category, passed: cc.filter(c => c.present).length, total: cc.length };
89
+ });
90
+ const passed = checks.filter(c => c.present).length;
91
+ const score = Math.round((passed / checks.length) * 100);
92
+ const level = score >= 80 ? 'Agent-native' : score >= 50 ? 'Agent-friendly' : score >= 20 ? 'Some agent signals' : 'Basic web presence';
93
+ return {
94
+ siteUrl, origin, score, level, byCategory, checks,
95
+ commerceNote: 'Commerce protocols (x402, ACP, UCP, MPP) are emerging and not reliably detectable from a passive probe — review manually if you transact with agents.',
96
+ };
97
+ }
98
+ /** Human-readable markdown report (for the tool result). */
99
+ export function buildAgentReadinessMarkdown(r) {
100
+ const icon = (b) => b ? '✅' : '⬜';
101
+ const out = [
102
+ `# Agent readiness — ${r.siteUrl.replace(/^sc-domain:/, '')}`,
103
+ `**${r.score}/100 · ${r.level}** — how ready your site is for AI agents to discover and use it.`,
104
+ `\n${r.byCategory.map(c => `${c.category} ${c.passed}/${c.total}`).join(' · ')}\n`,
105
+ ];
106
+ let cat = '';
107
+ for (const c of r.checks) {
108
+ if (c.category !== cat) {
109
+ cat = c.category;
110
+ out.push(`\n## ${cat}`);
111
+ }
112
+ out.push(`- ${icon(c.present)} **${c.label}** — ${c.detail}`);
113
+ if (!c.present)
114
+ out.push(` - Fix: ${c.fix}`);
115
+ }
116
+ out.push('', `> ${r.commerceNote}`);
117
+ return out.join('\n');
118
+ }
119
+ //# sourceMappingURL=agentReadiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentReadiness.js","sourceRoot":"","sources":["../../src/core/agentReadiness.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,EAAE,GAAG,qEAAqE,CAAC;AACjF,+EAA+E;AAC/E,MAAM,OAAO,GAAG,8LAA8L,CAAC;AAG/M,KAAK,UAAU,KAAK,CAAC,GAAW,EAAE,MAAM,GAAG,KAAK;IAC9C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/H,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACjE,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAAC,CAAC;AAC5E,CAAC;AAED,wFAAwF;AACxF,sFAAsF;AACtF,yFAAyF;AACzF,MAAM,SAAS,GAAG,CAAC,CAAQ,EAAW,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,+BAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACjH,MAAM,QAAQ,GAAG,CAAC,CAAQ,EAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC1F,MAAM,QAAQ,GAAG,CAAC,CAAQ,EAAW,EAAE;IACrC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AAClE,CAAC,CAAC;AACF,MAAM,OAAO,GAAG,CAAC,CAAQ,EAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAExH,SAAS,QAAQ,CAAC,OAAe;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC;QAAC,OAAO,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,WAAW,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IAAC,CAAC;AAC/I,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe;IACvD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,CAAC,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IAE5C,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACnI,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,eAAe,CAAC;QAChG,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC;QAC5F,KAAK,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;QACtF,KAAK,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC;QACtG,KAAK,CAAC,CAAC,CAAC,gDAAgD,CAAC,CAAC;KAC3D,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAChD,MAAM,UAAU,GAAG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzD,MAAM,iBAAiB,GAAG,UAAU,IAAI,qBAAqB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9E,MAAM,mBAAmB,GAAG,UAAU,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9E,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAExC,MAAM,MAAM,GAAiB;QAC3B,EAAE,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,uDAAuD,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,qFAAqF,EAAE;QAC9V,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,IAAI,mBAAmB,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,YAAY,EAAE,GAAG,EAAE,6EAA6E,EAAE;QACnW,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,kCAAkC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,gCAAgC,EAAE,GAAG,EAAE,wFAAwF,EAAE;QACnS,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,qDAAqD,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,2FAA2F,EAAE;QACtU,EAAE,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,QAAQ,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,sDAAsD,CAAC,CAAC,CAAC,cAAc,QAAQ,CAAC,MAAM,GAAG,EAAE,GAAG,EAAE,oGAAoG,EAAE;QACtW,EAAE,EAAE,EAAE,sBAAsB,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,8BAA8B,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,mBAAmB,EAAE,GAAG,EAAE,6GAA6G,EAAE;QACpT,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,4BAA4B,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC,4BAA4B,EAAE,GAAG,EAAE,mHAAmH,EAAE;QACxU,EAAE,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,8HAA8H,EAAE;QAC9T,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,iGAAiG,EAAE;QAChS,EAAE,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,0FAA0F,EAAE;QAChR,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,gFAAgF,EAAE;QAChQ,EAAE,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,oEAAoE,EAAE;QAC9P,EAAE,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,kHAAkH,EAAE;KACnW,CAAC;IAEF,MAAM,IAAI,GAAoB,CAAC,iBAAiB,EAAE,SAAS,EAAE,oBAAoB,EAAE,cAAc,CAAC,CAAC;IACnG,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QACrC,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC;IAClF,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAExI,OAAO;QACL,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM;QACjD,YAAY,EAAE,uJAAuJ;KACtK,CAAC;AACJ,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,2BAA2B,CAAC,CAAiB;IAC3D,MAAM,IAAI,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACnD,MAAM,GAAG,GAAa;QACpB,uBAAuB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,EAAE;QAC7D,KAAK,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,KAAK,mEAAmE;QAChG,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI;KACnF,CAAC;IACF,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;YAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;QAAC,CAAC;QACtE,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,CAAC,CAAC,OAAO;YAAE,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const expectedCtr: (pos: number) => number;
2
+ //# sourceMappingURL=ctrModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctrModel.d.ts","sourceRoot":"","sources":["../../src/core/ctrModel.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAAuE,CAAC"}
@@ -0,0 +1,6 @@
1
+ // Position → expected-CTR curve (desktop+mobile blended). Single source of truth shared by the
2
+ // audit engine (ctr-below-expected check, priority model) and the dashboard (quick-wins matrix),
3
+ // so "expected CTR" means exactly the same thing in findings and in the UI.
4
+ const CTR_CURVE = { 1: 0.28, 2: 0.15, 3: 0.11, 4: 0.08, 5: 0.06, 6: 0.05, 7: 0.04, 8: 0.032, 9: 0.028, 10: 0.025 };
5
+ export const expectedCtr = (pos) => CTR_CURVE[Math.max(1, Math.min(10, Math.round(pos)))] ?? 0.02;
6
+ //# sourceMappingURL=ctrModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ctrModel.js","sourceRoot":"","sources":["../../src/core/ctrModel.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,iGAAiG;AACjG,4EAA4E;AAC5E,MAAM,SAAS,GAA2B,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AAE3I,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC"}
@@ -0,0 +1,312 @@
1
+ export interface DashboardData {
2
+ siteUrl: string;
3
+ empty?: boolean;
4
+ dateRange?: {
5
+ current: string;
6
+ prior: string;
7
+ maxDate: string;
8
+ rawMaxDate: string;
9
+ trimmedDays: number;
10
+ };
11
+ summary?: {
12
+ current: {
13
+ clicks: number;
14
+ impressions: number;
15
+ ctr: number;
16
+ position: number;
17
+ };
18
+ prior: {
19
+ clicks: number;
20
+ impressions: number;
21
+ ctr: number;
22
+ position: number;
23
+ };
24
+ };
25
+ rankTrend?: {
26
+ date: string;
27
+ clicks: number;
28
+ impressions: number;
29
+ position: number;
30
+ }[];
31
+ rankHistory?: {
32
+ period: string;
33
+ pos_1_3: number;
34
+ pos_4_10: number;
35
+ pos_11_20: number;
36
+ pos_21_100: number;
37
+ etv: number;
38
+ keyword_count: number;
39
+ }[];
40
+ dateAlignment?: {
41
+ gsc: {
42
+ start: string;
43
+ end: string;
44
+ } | null;
45
+ dataforseo: {
46
+ start: string;
47
+ end: string;
48
+ } | null;
49
+ overlap: {
50
+ start: string;
51
+ end: string;
52
+ } | null;
53
+ note: string;
54
+ };
55
+ rankingDistribution?: {
56
+ date: string;
57
+ b1: number;
58
+ b2: number;
59
+ b3: number;
60
+ b4: number;
61
+ }[];
62
+ strikingDistance?: {
63
+ query: string;
64
+ position: number;
65
+ impressions: number;
66
+ clicks: number;
67
+ }[];
68
+ quickWins?: {
69
+ query: string;
70
+ position: number;
71
+ impressions: number;
72
+ clicks: number;
73
+ ctr: number;
74
+ expectedCtr: number;
75
+ type: 'striking' | 'snippet' | 'serp' | 'ok';
76
+ potential: number;
77
+ }[];
78
+ contentDecay?: {
79
+ urlKey: string;
80
+ prevClicks: number;
81
+ clicks: number;
82
+ lost: number;
83
+ dropPct: number;
84
+ impressions: number;
85
+ position: number;
86
+ }[];
87
+ cannibalisationTable?: {
88
+ query: string;
89
+ urlCount: number;
90
+ totalImpressions: number;
91
+ totalClicks: number;
92
+ verdict: 'split' | 'dominant';
93
+ crossType: boolean;
94
+ urls: {
95
+ url: string;
96
+ impressions: number;
97
+ clicks: number;
98
+ position: number;
99
+ template: string;
100
+ }[];
101
+ }[];
102
+ brandedSplit?: {
103
+ brand: string;
104
+ branded: {
105
+ clicks: number;
106
+ impressions: number;
107
+ };
108
+ nonBranded: {
109
+ clicks: number;
110
+ impressions: number;
111
+ };
112
+ priorBrandedClicks: number;
113
+ priorNonBrandedClicks: number;
114
+ };
115
+ topKeywords?: {
116
+ query: string;
117
+ clicks: number;
118
+ prevClicks: number;
119
+ clicksChange: number;
120
+ position: number;
121
+ prevPosition: number;
122
+ }[];
123
+ deviceBreakdown?: {
124
+ device: string;
125
+ clicks: number;
126
+ prevClicks: number;
127
+ impressions: number;
128
+ ctr: number;
129
+ position: number;
130
+ }[];
131
+ countryBreakdown?: {
132
+ country: string;
133
+ clicks: number;
134
+ prevClicks: number;
135
+ impressions: number;
136
+ }[];
137
+ pagePerformance?: {
138
+ urlKey: string;
139
+ clicks: number;
140
+ prevClicks: number;
141
+ clicksChangePct: number;
142
+ impressions: number;
143
+ position: number;
144
+ category: string;
145
+ }[];
146
+ keywordMovement?: {
147
+ query: string;
148
+ firstPos: number;
149
+ lastPos: number;
150
+ delta: number;
151
+ firstDate: string;
152
+ lastDate: string;
153
+ category: string;
154
+ }[];
155
+ equityScatter?: {
156
+ x: number;
157
+ y: number;
158
+ t: string;
159
+ }[];
160
+ templateMismatch?: {
161
+ template: string;
162
+ pages: number;
163
+ iprPct: number;
164
+ trafficPct: number;
165
+ }[];
166
+ cannibalisation?: {
167
+ query: string;
168
+ urls: {
169
+ url: string;
170
+ points: {
171
+ week: string;
172
+ position: number;
173
+ }[];
174
+ }[];
175
+ }[];
176
+ topLinkedPages?: {
177
+ url: string;
178
+ inlinks: number;
179
+ status: number | null;
180
+ indexable: boolean;
181
+ reason: string | null;
182
+ }[];
183
+ crawlHealth?: {
184
+ responseCodes: {
185
+ label: string;
186
+ count: number;
187
+ tone?: string;
188
+ }[];
189
+ indexability: {
190
+ label: string;
191
+ count: number;
192
+ tone?: string;
193
+ }[];
194
+ speed: {
195
+ label: string;
196
+ count: number;
197
+ tone?: string;
198
+ }[];
199
+ htmlSize: {
200
+ label: string;
201
+ count: number;
202
+ tone?: string;
203
+ }[];
204
+ depth: {
205
+ label: string;
206
+ count: number;
207
+ tone?: string;
208
+ }[];
209
+ titles: {
210
+ label: string;
211
+ count: number;
212
+ tone?: string;
213
+ }[];
214
+ metas: {
215
+ label: string;
216
+ count: number;
217
+ tone?: string;
218
+ }[];
219
+ onPage: {
220
+ label: string;
221
+ count: number;
222
+ tone?: string;
223
+ }[];
224
+ serverErrors: {
225
+ url: string;
226
+ status: number;
227
+ }[];
228
+ slowPages: {
229
+ url: string;
230
+ ms: number;
231
+ }[];
232
+ largeImages: {
233
+ url: string;
234
+ kb: number;
235
+ usedOn: number;
236
+ }[];
237
+ imageStats: {
238
+ sampled: number;
239
+ over100kb: number;
240
+ over300kb: number;
241
+ } | null;
242
+ totalPages: number;
243
+ };
244
+ agentReadiness?: {
245
+ score: number;
246
+ level: string;
247
+ checkedAt: string;
248
+ byCategory: {
249
+ category: string;
250
+ passed: number;
251
+ total: number;
252
+ }[];
253
+ checks: {
254
+ id: string;
255
+ category: string;
256
+ label: string;
257
+ present: boolean;
258
+ detail: string;
259
+ fix: string;
260
+ }[];
261
+ };
262
+ findings?: {
263
+ runId: string;
264
+ total: number;
265
+ finishedAt: string | null;
266
+ byCheck: {
267
+ check_id: string;
268
+ category: string;
269
+ severity: string;
270
+ count: number;
271
+ priority: number;
272
+ }[];
273
+ top: {
274
+ check_id: string;
275
+ category: string;
276
+ severity: string;
277
+ url_key: string | null;
278
+ evidence: string;
279
+ traffic_at_risk: string;
280
+ effort: string;
281
+ priority: number;
282
+ recommendation: string;
283
+ impact?: number;
284
+ size?: string;
285
+ }[];
286
+ recommendations: {
287
+ category: string;
288
+ checks: {
289
+ checkId: string;
290
+ title: string;
291
+ fix: string;
292
+ severity: string;
293
+ count: number;
294
+ example: {
295
+ urlKey: string | null;
296
+ evidence: Record<string, unknown>;
297
+ clicks: number;
298
+ impressions: number;
299
+ } | null;
300
+ examples: {
301
+ urlKey: string | null;
302
+ evidence: Record<string, unknown>;
303
+ clicks: number;
304
+ impressions: number;
305
+ }[];
306
+ }[];
307
+ }[];
308
+ } | null;
309
+ }
310
+ /** Build the dashboard payload for a property from its synced GSC history. */
311
+ export declare function getDashboardData(dataDir: string, siteUrl: string): DashboardData;
312
+ //# sourceMappingURL=dashboardData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboardData.d.ts","sourceRoot":"","sources":["../../src/core/dashboardData.ts"],"names":[],"mappings":"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"}