seo 0.2.7 → 0.2.8
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 +1 -1
- package/dist/cli.js +2 -2
- package/dist/{dist-C0LWlNAw.js → dist-B8eKKp3B.js} +3 -3
- package/dist/{dist-C0LWlNAw.js.map → dist-B8eKKp3B.js.map} +1 -1
- package/dist/{dist-B6UxI6sc.js → dist-DkWLBABR.js} +1 -1
- package/dist/index.js +51 -35
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +51 -35
- package/dist/mcp.js.map +1 -1
- package/dist/{package-BI-bLeV4.js → package-BDez60C3.js} +2 -2
- package/dist/{package-BI-bLeV4.js.map → package-BDez60C3.js.map} +1 -1
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __seoCreateRequire } from 'node:module'; const require = __seoCreateRequire(import.meta.url);
|
|
2
|
-
import { n as load, t as version } from "./package-
|
|
2
|
+
import { n as load, t as version } from "./package-BDez60C3.js";
|
|
3
3
|
import { Headers, fetch as fetch$1 } from "undici";
|
|
4
4
|
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { arch, homedir, platform } from "node:os";
|
|
@@ -6291,16 +6291,15 @@ async function inspectMarkdownPage(input) {
|
|
|
6291
6291
|
repeatedHashStable: null,
|
|
6292
6292
|
markdownCanonicalMatchesHtml: null
|
|
6293
6293
|
};
|
|
6294
|
-
|
|
6295
|
-
const explicitUrl = advertisedUrls[0];
|
|
6294
|
+
const explicitUrl = advertisedUrls.length === 1 ? advertisedUrls[0] : void 0;
|
|
6296
6295
|
const [explicit, negotiated, repeated] = await Promise.all([
|
|
6297
|
-
fetchRepresentation({
|
|
6296
|
+
explicitUrl ? fetchRepresentation({
|
|
6298
6297
|
url: explicitUrl,
|
|
6299
6298
|
accept: "text/markdown",
|
|
6300
6299
|
timeoutMs: input.timeoutMs,
|
|
6301
6300
|
fetch: input.fetch,
|
|
6302
6301
|
signal: input.signal
|
|
6303
|
-
}),
|
|
6302
|
+
}) : Promise.resolve(void 0),
|
|
6304
6303
|
fetchRepresentation({
|
|
6305
6304
|
url: input.page.finalUrl,
|
|
6306
6305
|
accept: "text/markdown",
|
|
@@ -6309,20 +6308,21 @@ async function inspectMarkdownPage(input) {
|
|
|
6309
6308
|
signal: input.signal
|
|
6310
6309
|
}),
|
|
6311
6310
|
fetchRepresentation({
|
|
6312
|
-
url: explicitUrl,
|
|
6311
|
+
url: explicitUrl ?? input.page.finalUrl,
|
|
6313
6312
|
accept: "text/markdown",
|
|
6314
6313
|
timeoutMs: input.timeoutMs,
|
|
6315
6314
|
fetch: input.fetch,
|
|
6316
6315
|
signal: input.signal
|
|
6317
6316
|
})
|
|
6318
6317
|
]);
|
|
6319
|
-
observation.explicit = explicit.observation;
|
|
6318
|
+
if (explicit) observation.explicit = explicit.observation;
|
|
6320
6319
|
observation.negotiated = negotiated.observation;
|
|
6321
6320
|
observation.repeated = repeated.observation;
|
|
6322
|
-
observation.explicitMatchesNegotiated = explicit
|
|
6323
|
-
|
|
6324
|
-
observation.
|
|
6325
|
-
|
|
6321
|
+
observation.explicitMatchesNegotiated = explicit?.observation.sha256 && negotiated.observation.sha256 ? explicit.observation.sha256 === negotiated.observation.sha256 : null;
|
|
6322
|
+
const primary = explicit ?? negotiated;
|
|
6323
|
+
observation.repeatedHashStable = primary.observation.sha256 && repeated.observation.sha256 ? primary.observation.sha256 === repeated.observation.sha256 : null;
|
|
6324
|
+
observation.markdownCanonicalMatchesHtml = sameDocument(primary.observation.canonicalUrl, input.page.finalUrl);
|
|
6325
|
+
if (primary.body) observation.quality = markdownQuality(primary.body, input.page);
|
|
6326
6326
|
return observation;
|
|
6327
6327
|
}
|
|
6328
6328
|
async function fetchText(input) {
|
|
@@ -6658,10 +6658,13 @@ async function collectAgentDiscovery(input) {
|
|
|
6658
6658
|
const wwwLocation = www.location ? new URL(www.location, wwwUrl).toString() : void 0;
|
|
6659
6659
|
const qZeroContentType = qZero.observation.contentType;
|
|
6660
6660
|
const advertisedPages = observations.filter((observation) => observation.htmlAlternateUnique).length;
|
|
6661
|
-
const evaluatedPages = observations.filter((observation) =>
|
|
6661
|
+
const evaluatedPages = observations.filter((observation) => {
|
|
6662
|
+
const representation = observation.explicit ?? observation.negotiated;
|
|
6663
|
+
return representation?.status !== void 0 && representation.status >= 200 && representation.status < 300 && /^\s*text\/markdown\b/iu.test(representation.contentType ?? "");
|
|
6664
|
+
}).length;
|
|
6662
6665
|
const warnings = [...pages.length !== input.pages.length ? [`Agent representations were evaluated for ${pages.length} successful HTML pages from ${input.pages.length} retained documents.`] : [], ...routeManifest.valid ? [] : ["No valid public agent route manifest was available for orphan checks."]].sort();
|
|
6663
6666
|
const htmlContentSignals = pages.map((page) => headerValue$1(page.responseHeaders, "content-signal")).filter((value) => Boolean(value));
|
|
6664
|
-
const markdownContentSignals = observations.map((observation) => observation.explicit?.contentSignal).filter((value) => Boolean(value));
|
|
6667
|
+
const markdownContentSignals = observations.map((observation) => observation.explicit?.contentSignal ?? observation.negotiated?.contentSignal).filter((value) => Boolean(value));
|
|
6665
6668
|
const contentSignalValues = [.../* @__PURE__ */ new Set([...htmlContentSignals, ...markdownContentSignals])].sort();
|
|
6666
6669
|
return {
|
|
6667
6670
|
profile: "content",
|
|
@@ -6744,7 +6747,11 @@ function section$1(id, title, checks) {
|
|
|
6744
6747
|
};
|
|
6745
6748
|
}
|
|
6746
6749
|
function failedMarkdownUrls(discovery) {
|
|
6747
|
-
return discovery.markdownAlternates.pages.filter((page) =>
|
|
6750
|
+
return discovery.markdownAlternates.pages.filter((page) => {
|
|
6751
|
+
const negotiatedOk = page.negotiated?.status === 200 && /^\s*text\/markdown\b/iu.test(page.negotiated.contentType ?? "") && page.negotiated.varyAccept;
|
|
6752
|
+
const explicitOk = !page.htmlAlternateUnique ? true : page.httpAlternateUrls.length === 1 && page.explicit?.status === 200 && /^\s*text\/markdown\b/iu.test(page.explicit.contentType ?? "") && page.explicitMatchesNegotiated === true && page.markdownCanonicalMatchesHtml === true;
|
|
6753
|
+
return !negotiatedOk || !explicitOk || page.repeatedHashStable !== true;
|
|
6754
|
+
}).map((page) => page.htmlUrl);
|
|
6748
6755
|
}
|
|
6749
6756
|
function qualityFailureUrls(discovery) {
|
|
6750
6757
|
return discovery.markdownAlternates.pages.filter((page) => {
|
|
@@ -6786,20 +6793,25 @@ function markdownChecks(discovery) {
|
|
|
6786
6793
|
const markdown = discovery.markdownAlternates;
|
|
6787
6794
|
const failedUrls = failedMarkdownUrls(discovery);
|
|
6788
6795
|
const qualityUrls = qualityFailureUrls(discovery);
|
|
6789
|
-
const
|
|
6790
|
-
const
|
|
6796
|
+
const negotiatedPages = markdown.pages.filter((page) => page.negotiated?.status === 200 && /^\s*text\/markdown\b/iu.test(page.negotiated.contentType ?? "")).length;
|
|
6797
|
+
const explicitPages = markdown.pages.filter((page) => page.htmlAlternateUnique).length;
|
|
6798
|
+
const coverageComplete = markdown.eligibleHtmlPages > 0 && markdown.evaluatedPages === markdown.eligibleHtmlPages;
|
|
6799
|
+
const negotiationComplete = markdown.eligibleHtmlPages > 0 && negotiatedPages === markdown.eligibleHtmlPages && markdown.pages.every((page) => page.negotiated?.varyAccept) && markdown.pages.every((page) => !page.htmlAlternateUnique || page.explicitMatchesNegotiated === true);
|
|
6791
6800
|
const stable = markdown.eligibleHtmlPages > 0 && markdown.stableResponses === markdown.eligibleHtmlPages;
|
|
6792
|
-
const tokenHeaders = markdown.pages.filter((page) =>
|
|
6801
|
+
const tokenHeaders = markdown.pages.filter((page) => {
|
|
6802
|
+
return (page.explicit ?? page.negotiated)?.markdownTokens !== void 0 && (!page.explicit || !page.negotiated || page.explicit.markdownTokens === page.negotiated.markdownTokens);
|
|
6803
|
+
}).length;
|
|
6793
6804
|
return [
|
|
6794
6805
|
check$1("representations", {
|
|
6795
6806
|
id: "markdown-coverage",
|
|
6796
6807
|
status: markdown.eligibleHtmlPages === 0 ? "unknown" : coverageComplete ? "pass" : "fail",
|
|
6797
|
-
title: coverageComplete ? "Every successful HTML page
|
|
6798
|
-
plainEnglish: `${markdown.
|
|
6799
|
-
action: coverageComplete ? "Keep
|
|
6808
|
+
title: coverageComplete ? "Every successful HTML page has a Markdown representation" : "Markdown representation coverage is incomplete",
|
|
6809
|
+
plainEnglish: `${markdown.evaluatedPages} of ${markdown.eligibleHtmlPages} successful HTML pages returned Markdown. ${explicitPages} advertised an explicit alternative and ${negotiatedPages} supported content negotiation.`,
|
|
6810
|
+
action: coverageComplete ? "Keep the negotiated or explicit Markdown response stable as routes change." : "Return text/markdown through content negotiation or advertise one working Markdown alternative for each public HTML page.",
|
|
6800
6811
|
evidence: {
|
|
6801
6812
|
eligibleHtmlPages: markdown.eligibleHtmlPages,
|
|
6802
6813
|
advertisedPages: markdown.advertisedPages,
|
|
6814
|
+
negotiatedPages,
|
|
6803
6815
|
evaluatedPages: markdown.evaluatedPages
|
|
6804
6816
|
},
|
|
6805
6817
|
urls: failedUrls.slice(0, 25)
|
|
@@ -6807,18 +6819,22 @@ function markdownChecks(discovery) {
|
|
|
6807
6819
|
check$1("representations", {
|
|
6808
6820
|
id: "markdown-token-estimates",
|
|
6809
6821
|
status: markdown.evaluatedPages === 0 ? "unknown" : tokenHeaders === markdown.evaluatedPages ? "pass" : "warning",
|
|
6810
|
-
title: tokenHeaders === markdown.evaluatedPages ? "Every Markdown response includes
|
|
6811
|
-
plainEnglish: `${tokenHeaders} of ${markdown.evaluatedPages} evaluated pages returned
|
|
6812
|
-
action: "
|
|
6813
|
-
urls: markdown.pages.filter((page) =>
|
|
6822
|
+
title: tokenHeaders === markdown.evaluatedPages ? "Every Markdown response includes a token estimate" : "Some Markdown responses are missing a stable token estimate",
|
|
6823
|
+
plainEnglish: `${tokenHeaders} of ${markdown.evaluatedPages} evaluated pages returned X-Markdown-Tokens. Paired explicit and negotiated responses agreed where both existed. The value is an estimate, not an exact model-specific token count.`,
|
|
6824
|
+
action: "Return a stable token estimate and keep it consistent when both explicit and negotiated responses exist.",
|
|
6825
|
+
urls: markdown.pages.filter((page) => {
|
|
6826
|
+
return (page.explicit ?? page.negotiated)?.markdownTokens === void 0 || page.explicit !== void 0 && page.negotiated !== void 0 && page.explicit.markdownTokens !== page.negotiated.markdownTokens;
|
|
6827
|
+
}).map((page) => page.htmlUrl).slice(0, 25)
|
|
6814
6828
|
}),
|
|
6815
6829
|
check$1("representations", {
|
|
6816
6830
|
id: "markdown-negotiation",
|
|
6817
|
-
status: markdown.eligibleHtmlPages === 0 ? "unknown" :
|
|
6818
|
-
title:
|
|
6819
|
-
plainEnglish: `${
|
|
6820
|
-
action: "
|
|
6831
|
+
status: markdown.eligibleHtmlPages === 0 ? "unknown" : negotiationComplete && discovery.contentNegotiation.qZeroHonoured ? "pass" : "fail",
|
|
6832
|
+
title: negotiationComplete && discovery.contentNegotiation.qZeroHonoured ? "Markdown content negotiation works across the site" : "Markdown content negotiation needs attention",
|
|
6833
|
+
plainEnglish: `${negotiatedPages} of ${markdown.eligibleHtmlPages} pages returned negotiated Markdown. ${markdown.exactByteMatches} of ${explicitPages} paired explicit responses matched byte for byte. A request that refuses Markdown ${discovery.contentNegotiation.qZeroHonoured ? "received HTML" : "did not produce confirmed HTML evidence"}.`,
|
|
6834
|
+
action: "Honour Accept q-values, send Vary: Accept, and keep paired explicit and negotiated responses identical when both exist.",
|
|
6821
6835
|
evidence: {
|
|
6836
|
+
negotiatedPages,
|
|
6837
|
+
explicitPages,
|
|
6822
6838
|
exactByteMatches: markdown.exactByteMatches,
|
|
6823
6839
|
qZero: discovery.contentNegotiation
|
|
6824
6840
|
},
|
|
@@ -6828,8 +6844,8 @@ function markdownChecks(discovery) {
|
|
|
6828
6844
|
id: "markdown-determinism",
|
|
6829
6845
|
status: markdown.eligibleHtmlPages === 0 ? "unknown" : stable ? "pass" : "fail",
|
|
6830
6846
|
title: stable ? "Repeated Markdown responses are stable" : "Repeated Markdown responses changed during the audit",
|
|
6831
|
-
plainEnglish: `${markdown.stableResponses} of ${markdown.eligibleHtmlPages} repeated
|
|
6832
|
-
action: "
|
|
6847
|
+
plainEnglish: `${markdown.stableResponses} of ${markdown.eligibleHtmlPages} repeated Markdown responses kept the same SHA-256 digest.`,
|
|
6848
|
+
action: "Remove timestamps, random output, or other runtime rewriting that changes the same Markdown response between requests.",
|
|
6833
6849
|
evidence: { stableResponses: markdown.stableResponses },
|
|
6834
6850
|
urls: failedUrls.slice(0, 25)
|
|
6835
6851
|
}),
|
|
@@ -6943,10 +6959,10 @@ function identityChecks(report) {
|
|
|
6943
6959
|
const officialProfiles = [...new Set(report.pages.flatMap((page) => [...page.schemaSameAs ?? [], ...page.socialProfileLinks ?? []]))];
|
|
6944
6960
|
return [check$1("identity", {
|
|
6945
6961
|
id: "identity-graph",
|
|
6946
|
-
status:
|
|
6947
|
-
title:
|
|
6948
|
-
plainEnglish: `
|
|
6949
|
-
action: "Connect truthful
|
|
6962
|
+
status: hasWebsite && hasCreator && pageTypes.length > 0 ? "pass" : "warning",
|
|
6963
|
+
title: hasWebsite && hasCreator && pageTypes.length > 0 ? "Structured identity covers the website, creator, and pages" : "The structured identity graph is missing a useful entity layer",
|
|
6964
|
+
plainEnglish: `Website identity: ${hasWebsite ? "present" : "missing"}. Creator or publisher identity: ${hasCreator ? "present" : "missing"}. Page-level types: ${pageTypes.length ? pageTypes.join(", ") : "missing"}. Software identity: ${hasSoftware ? "present" : "not observed and not required for a content site"}.`,
|
|
6965
|
+
action: "Connect truthful WebSite, creator or publisher, and page nodes. Add SoftwareApplication only when the site actually represents software. Use sameAs only for official profiles that identify the same entity.",
|
|
6950
6966
|
evidence: {
|
|
6951
6967
|
schemaTypes: [...types].sort(),
|
|
6952
6968
|
officialProfiles: officialProfiles.sort()
|
|
@@ -7434,7 +7450,7 @@ function aiReadiness(report) {
|
|
|
7434
7450
|
score: 0,
|
|
7435
7451
|
evaluated: Boolean(agentDiscovery),
|
|
7436
7452
|
title: agentDiscovery ? "Markdown alternatives were checked" : "Markdown alternatives were not evaluated",
|
|
7437
|
-
plainEnglish: agentDiscovery ? `${agentDiscovery.markdownAlternates.
|
|
7453
|
+
plainEnglish: agentDiscovery ? `${agentDiscovery.markdownAlternates.evaluatedPages} of ${agentDiscovery.markdownAlternates.eligibleHtmlPages} successful HTML pages returned Markdown through an explicit alternative or content negotiation. ${agentDiscovery.markdownAlternates.exactByteMatches} paired explicit responses matched content negotiation byte for byte.` : "This crawl does not include the focused representation checks, so it cannot say whether HTML pages publish stable Markdown alternatives.",
|
|
7438
7454
|
action: "Use the focused agent-readiness report when you need route coverage, content negotiation, byte stability, or extraction-quality evidence.",
|
|
7439
7455
|
evidence: agentDiscovery ? {
|
|
7440
7456
|
eligibleHtmlPages: agentDiscovery.markdownAlternates.eligibleHtmlPages,
|