@pseolint/core 0.4.3 → 0.5.3
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 +264 -169
- package/dist/ai/manifest/diff.d.ts +78 -0
- package/dist/ai/manifest/diff.d.ts.map +1 -0
- package/dist/ai/manifest/diff.js +139 -0
- package/dist/ai/manifest/diff.js.map +1 -0
- package/dist/ai/manifest/index.d.ts +18 -0
- package/dist/ai/manifest/index.d.ts.map +1 -0
- package/dist/ai/manifest/index.js +15 -0
- package/dist/ai/manifest/index.js.map +1 -0
- package/dist/ai/manifest/validate-manifest.d.ts +37 -0
- package/dist/ai/manifest/validate-manifest.d.ts.map +1 -0
- package/dist/ai/manifest/validate-manifest.js +67 -0
- package/dist/ai/manifest/validate-manifest.js.map +1 -0
- package/dist/ai/manifest/validators/domain-patches.d.ts +15 -0
- package/dist/ai/manifest/validators/domain-patches.d.ts.map +1 -0
- package/dist/ai/manifest/validators/domain-patches.js +110 -0
- package/dist/ai/manifest/validators/domain-patches.js.map +1 -0
- package/dist/ai/manifest/validators/index.d.ts +5 -0
- package/dist/ai/manifest/validators/index.d.ts.map +1 -0
- package/dist/ai/manifest/validators/index.js +4 -0
- package/dist/ai/manifest/validators/index.js.map +1 -0
- package/dist/ai/manifest/validators/page-changes.d.ts +36 -0
- package/dist/ai/manifest/validators/page-changes.d.ts.map +1 -0
- package/dist/ai/manifest/validators/page-changes.js +221 -0
- package/dist/ai/manifest/validators/page-changes.js.map +1 -0
- package/dist/ai/manifest/validators/types.d.ts +17 -0
- package/dist/ai/manifest/validators/types.d.ts.map +1 -0
- package/dist/ai/manifest/validators/types.js +5 -0
- package/dist/ai/manifest/validators/types.js.map +1 -0
- package/dist/ai/orchestrate.d.ts +74 -0
- package/dist/ai/orchestrate.d.ts.map +1 -0
- package/dist/ai/orchestrate.js +54 -0
- package/dist/ai/orchestrate.js.map +1 -0
- package/dist/ai/orchestrator/budget.d.ts +57 -0
- package/dist/ai/orchestrator/budget.d.ts.map +1 -0
- package/dist/ai/orchestrator/budget.js +114 -0
- package/dist/ai/orchestrator/budget.js.map +1 -0
- package/dist/ai/orchestrator/finish-tool.d.ts +568 -0
- package/dist/ai/orchestrator/finish-tool.d.ts.map +1 -0
- package/dist/ai/orchestrator/finish-tool.js +114 -0
- package/dist/ai/orchestrator/finish-tool.js.map +1 -0
- package/dist/ai/orchestrator/index.d.ts +25 -0
- package/dist/ai/orchestrator/index.d.ts.map +1 -0
- package/dist/ai/orchestrator/index.js +21 -0
- package/dist/ai/orchestrator/index.js.map +1 -0
- package/dist/ai/orchestrator/log.d.ts +24 -0
- package/dist/ai/orchestrator/log.d.ts.map +1 -0
- package/dist/ai/orchestrator/log.js +48 -0
- package/dist/ai/orchestrator/log.js.map +1 -0
- package/dist/ai/orchestrator/page-cache.d.ts +64 -0
- package/dist/ai/orchestrator/page-cache.d.ts.map +1 -0
- package/dist/ai/orchestrator/page-cache.js +127 -0
- package/dist/ai/orchestrator/page-cache.js.map +1 -0
- package/dist/ai/orchestrator/prompt.d.ts +16 -0
- package/dist/ai/orchestrator/prompt.d.ts.map +1 -0
- package/dist/ai/orchestrator/prompt.js +52 -0
- package/dist/ai/orchestrator/prompt.js.map +1 -0
- package/dist/ai/orchestrator/runner.d.ts +65 -0
- package/dist/ai/orchestrator/runner.d.ts.map +1 -0
- package/dist/ai/orchestrator/runner.js +223 -0
- package/dist/ai/orchestrator/runner.js.map +1 -0
- package/dist/ai/orchestrator/session.d.ts +44 -0
- package/dist/ai/orchestrator/session.d.ts.map +1 -0
- package/dist/ai/orchestrator/session.js +64 -0
- package/dist/ai/orchestrator/session.js.map +1 -0
- package/dist/ai/orchestrator/types.d.ts +99 -0
- package/dist/ai/orchestrator/types.d.ts.map +1 -0
- package/dist/ai/orchestrator/types.js +8 -0
- package/dist/ai/orchestrator/types.js.map +1 -0
- package/dist/ai/probes/cache.d.ts +12 -0
- package/dist/ai/probes/cache.d.ts.map +1 -0
- package/dist/ai/probes/cache.js +46 -0
- package/dist/ai/probes/cache.js.map +1 -0
- package/dist/ai/tools/ask-ai-engine.d.ts +77 -0
- package/dist/ai/tools/ask-ai-engine.d.ts.map +1 -0
- package/dist/ai/tools/ask-ai-engine.js +253 -0
- package/dist/ai/tools/ask-ai-engine.js.map +1 -0
- package/dist/ai/tools/check-domain-crawler-access.d.ts +71 -0
- package/dist/ai/tools/check-domain-crawler-access.d.ts.map +1 -0
- package/dist/ai/tools/check-domain-crawler-access.js +76 -0
- package/dist/ai/tools/check-domain-crawler-access.js.map +1 -0
- package/dist/ai/tools/check-domain-llms-txt.d.ts +70 -0
- package/dist/ai/tools/check-domain-llms-txt.d.ts.map +1 -0
- package/dist/ai/tools/check-domain-llms-txt.js +75 -0
- package/dist/ai/tools/check-domain-llms-txt.js.map +1 -0
- package/dist/ai/tools/check-indexability.d.ts +58 -0
- package/dist/ai/tools/check-indexability.d.ts.map +1 -0
- package/dist/ai/tools/check-indexability.js +64 -0
- package/dist/ai/tools/check-indexability.js.map +1 -0
- package/dist/ai/tools/check-robots.d.ts +68 -0
- package/dist/ai/tools/check-robots.d.ts.map +1 -0
- package/dist/ai/tools/check-robots.js +90 -0
- package/dist/ai/tools/check-robots.js.map +1 -0
- package/dist/ai/tools/check-rule-answer-first.d.ts +54 -0
- package/dist/ai/tools/check-rule-answer-first.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-answer-first.js +50 -0
- package/dist/ai/tools/check-rule-answer-first.js.map +1 -0
- package/dist/ai/tools/check-rule-canonical-consistency.d.ts +66 -0
- package/dist/ai/tools/check-rule-canonical-consistency.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-canonical-consistency.js +51 -0
- package/dist/ai/tools/check-rule-canonical-consistency.js.map +1 -0
- package/dist/ai/tools/check-rule-citable-facts.d.ts +58 -0
- package/dist/ai/tools/check-rule-citable-facts.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-citable-facts.js +41 -0
- package/dist/ai/tools/check-rule-citable-facts.js.map +1 -0
- package/dist/ai/tools/check-rule-content-modularity.d.ts +58 -0
- package/dist/ai/tools/check-rule-content-modularity.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-content-modularity.js +45 -0
- package/dist/ai/tools/check-rule-content-modularity.js.map +1 -0
- package/dist/ai/tools/check-rule-faq-coverage.d.ts +54 -0
- package/dist/ai/tools/check-rule-faq-coverage.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-faq-coverage.js +39 -0
- package/dist/ai/tools/check-rule-faq-coverage.js.map +1 -0
- package/dist/ai/tools/check-rule-freshness-signals.d.ts +54 -0
- package/dist/ai/tools/check-rule-freshness-signals.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-freshness-signals.js +45 -0
- package/dist/ai/tools/check-rule-freshness-signals.js.map +1 -0
- package/dist/ai/tools/check-rule-json-ld-valid.d.ts +54 -0
- package/dist/ai/tools/check-rule-json-ld-valid.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-json-ld-valid.js +44 -0
- package/dist/ai/tools/check-rule-json-ld-valid.js.map +1 -0
- package/dist/ai/tools/check-rule-missing-author.d.ts +54 -0
- package/dist/ai/tools/check-rule-missing-author.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-missing-author.js +45 -0
- package/dist/ai/tools/check-rule-missing-author.js.map +1 -0
- package/dist/ai/tools/check-rule-near-duplicate.d.ts +82 -0
- package/dist/ai/tools/check-rule-near-duplicate.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-near-duplicate.js +63 -0
- package/dist/ai/tools/check-rule-near-duplicate.js.map +1 -0
- package/dist/ai/tools/check-rule-required-fields.d.ts +50 -0
- package/dist/ai/tools/check-rule-required-fields.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-required-fields.js +38 -0
- package/dist/ai/tools/check-rule-required-fields.js.map +1 -0
- package/dist/ai/tools/check-rule-schema-consistency.d.ts +54 -0
- package/dist/ai/tools/check-rule-schema-consistency.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-schema-consistency.js +44 -0
- package/dist/ai/tools/check-rule-schema-consistency.js.map +1 -0
- package/dist/ai/tools/check-rule-summary-bait.d.ts +54 -0
- package/dist/ai/tools/check-rule-summary-bait.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-summary-bait.js +39 -0
- package/dist/ai/tools/check-rule-summary-bait.js.map +1 -0
- package/dist/ai/tools/check-rule-thin-content.d.ts +66 -0
- package/dist/ai/tools/check-rule-thin-content.d.ts.map +1 -0
- package/dist/ai/tools/check-rule-thin-content.js +58 -0
- package/dist/ai/tools/check-rule-thin-content.js.map +1 -0
- package/dist/ai/tools/detect-templates.d.ts +60 -0
- package/dist/ai/tools/detect-templates.d.ts.map +1 -0
- package/dist/ai/tools/detect-templates.js +43 -0
- package/dist/ai/tools/detect-templates.js.map +1 -0
- package/dist/ai/tools/fetch-page.d.ts +70 -0
- package/dist/ai/tools/fetch-page.d.ts.map +1 -0
- package/dist/ai/tools/fetch-page.js +93 -0
- package/dist/ai/tools/fetch-page.js.map +1 -0
- package/dist/ai/tools/fetch-sitemap.d.ts +60 -0
- package/dist/ai/tools/fetch-sitemap.d.ts.map +1 -0
- package/dist/ai/tools/fetch-sitemap.js +116 -0
- package/dist/ai/tools/fetch-sitemap.js.map +1 -0
- package/dist/ai/tools/index.d.ts +1555 -0
- package/dist/ai/tools/index.d.ts.map +1 -0
- package/dist/ai/tools/index.js +119 -0
- package/dist/ai/tools/index.js.map +1 -0
- package/dist/ai/tools/parse-page.d.ts +94 -0
- package/dist/ai/tools/parse-page.d.ts.map +1 -0
- package/dist/ai/tools/parse-page.js +108 -0
- package/dist/ai/tools/parse-page.js.map +1 -0
- package/dist/ai/tools/query-serp.d.ts +113 -0
- package/dist/ai/tools/query-serp.d.ts.map +1 -0
- package/dist/ai/tools/query-serp.js +131 -0
- package/dist/ai/tools/query-serp.js.map +1 -0
- package/dist/ai/tools/sample-template.d.ts +67 -0
- package/dist/ai/tools/sample-template.d.ts.map +1 -0
- package/dist/ai/tools/sample-template.js +75 -0
- package/dist/ai/tools/sample-template.js.map +1 -0
- package/dist/ai/tools/types.d.ts +73 -0
- package/dist/ai/tools/types.d.ts.map +1 -0
- package/dist/ai/tools/types.js +64 -0
- package/dist/ai/tools/types.js.map +1 -0
- package/dist/ai/tools/validate-jsonld.d.ts +62 -0
- package/dist/ai/tools/validate-jsonld.d.ts.map +1 -0
- package/dist/ai/tools/validate-jsonld.js +84 -0
- package/dist/ai/tools/validate-jsonld.js.map +1 -0
- package/dist/auditor.d.ts +4 -0
- package/dist/auditor.d.ts.map +1 -1
- package/dist/auditor.js +629 -64
- package/dist/auditor.js.map +1 -1
- package/dist/backpressure.d.ts.map +1 -1
- package/dist/backpressure.js +10 -3
- package/dist/backpressure.js.map +1 -1
- package/dist/enrich-findings.d.ts.map +1 -1
- package/dist/enrich-findings.js +15 -1
- package/dist/enrich-findings.js.map +1 -1
- package/dist/formatters/console.d.ts.map +1 -1
- package/dist/formatters/console.js +13 -0
- package/dist/formatters/console.js.map +1 -1
- package/dist/formatters/markdown.d.ts.map +1 -1
- package/dist/formatters/markdown.js +20 -2
- package/dist/formatters/markdown.js.map +1 -1
- package/dist/index.d.ts +12 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/rule-references.d.ts.map +1 -1
- package/dist/rule-references.js +5 -0
- package/dist/rule-references.js.map +1 -1
- package/dist/rules/content/heading-structure.d.ts +21 -0
- package/dist/rules/content/heading-structure.d.ts.map +1 -0
- package/dist/rules/content/heading-structure.js +56 -0
- package/dist/rules/content/heading-structure.js.map +1 -0
- package/dist/rules/content/image-alt-text.d.ts +18 -0
- package/dist/rules/content/image-alt-text.d.ts.map +1 -0
- package/dist/rules/content/image-alt-text.js +77 -0
- package/dist/rules/content/image-alt-text.js.map +1 -0
- package/dist/rules/content/title-uniqueness.d.ts +18 -0
- package/dist/rules/content/title-uniqueness.d.ts.map +1 -0
- package/dist/rules/content/title-uniqueness.js +70 -0
- package/dist/rules/content/title-uniqueness.js.map +1 -0
- package/dist/rules/links/host-section-divergence.d.ts +3 -0
- package/dist/rules/links/host-section-divergence.d.ts.map +1 -0
- package/dist/rules/links/host-section-divergence.js +158 -0
- package/dist/rules/links/host-section-divergence.js.map +1 -0
- package/dist/rules/links/link-depth.d.ts +12 -1
- package/dist/rules/links/link-depth.d.ts.map +1 -1
- package/dist/rules/links/link-depth.js +25 -12
- package/dist/rules/links/link-depth.js.map +1 -1
- package/dist/rules/scope.d.ts.map +1 -1
- package/dist/rules/scope.js +5 -0
- package/dist/rules/scope.js.map +1 -1
- package/dist/rules/spam/doorway-pattern.d.ts.map +1 -1
- package/dist/rules/spam/doorway-pattern.js +27 -4
- package/dist/rules/spam/doorway-pattern.js.map +1 -1
- package/dist/rules/spam/publication-velocity.d.ts +1 -1
- package/dist/rules/spam/publication-velocity.d.ts.map +1 -1
- package/dist/rules/spam/publication-velocity.js +9 -4
- package/dist/rules/spam/publication-velocity.js.map +1 -1
- package/dist/rules/spam/template-coverage.js +1 -1
- package/dist/rules/spam/template-coverage.js.map +1 -1
- package/dist/rules/spam/template-diversity.js +1 -1
- package/dist/rules/spam/template-diversity.js.map +1 -1
- package/dist/rules/tech/hreflang-consistency.d.ts.map +1 -1
- package/dist/rules/tech/hreflang-consistency.js +33 -4
- package/dist/rules/tech/hreflang-consistency.js.map +1 -1
- package/dist/rules/tech/og-completeness.d.ts +11 -0
- package/dist/rules/tech/og-completeness.d.ts.map +1 -1
- package/dist/rules/tech/og-completeness.js +22 -23
- package/dist/rules/tech/og-completeness.js.map +1 -1
- package/dist/ruleset-version.d.ts +8 -0
- package/dist/ruleset-version.d.ts.map +1 -0
- package/dist/ruleset-version.js +8 -0
- package/dist/ruleset-version.js.map +1 -0
- package/dist/scrape-strategy.d.ts +42 -0
- package/dist/scrape-strategy.d.ts.map +1 -0
- package/dist/scrape-strategy.js +101 -0
- package/dist/scrape-strategy.js.map +1 -0
- package/dist/site-classifier.d.ts.map +1 -1
- package/dist/site-classifier.js +1 -0
- package/dist/site-classifier.js.map +1 -1
- package/dist/state.d.ts +36 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +3 -1
- package/dist/state.js.map +1 -1
- package/dist/stratified-sample.d.ts +9 -1
- package/dist/stratified-sample.d.ts.map +1 -1
- package/dist/stratified-sample.js +23 -6
- package/dist/stratified-sample.js.map +1 -1
- package/dist/types.d.ts +135 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/url-normalize.d.ts.map +1 -1
- package/dist/url-normalize.js +13 -1
- package/dist/url-normalize.js.map +1 -1
- package/package.json +90 -90
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** HTML-escape a string for safe interpolation into attribute or text content. */
|
|
2
|
+
function escapeHtml(s) {
|
|
3
|
+
return s
|
|
4
|
+
.replace(/&/g, "&")
|
|
5
|
+
.replace(/</g, "<")
|
|
6
|
+
.replace(/>/g, ">")
|
|
7
|
+
.replace(/"/g, """)
|
|
8
|
+
.replace(/'/g, "'");
|
|
9
|
+
}
|
|
10
|
+
function serializeJsonLd(block) {
|
|
11
|
+
return `<script type="application/ld+json">\n${JSON.stringify(block, null, 2)}\n</script>`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Convert a single page-change into a `PatchDiff`. Pure transformation —
|
|
15
|
+
* does not validate (use `validatePageChange` for that). The two should
|
|
16
|
+
* be called in sequence at manifest finalization: validate first, drop
|
|
17
|
+
* failures, then diff the survivors.
|
|
18
|
+
*/
|
|
19
|
+
export function diffPageChange(c) {
|
|
20
|
+
switch (c.type) {
|
|
21
|
+
case "replace_h1":
|
|
22
|
+
return {
|
|
23
|
+
kind: "text_replace",
|
|
24
|
+
field: "h1",
|
|
25
|
+
before: c.before,
|
|
26
|
+
after: c.after,
|
|
27
|
+
reason: c.reason,
|
|
28
|
+
};
|
|
29
|
+
case "rewrite_meta":
|
|
30
|
+
return {
|
|
31
|
+
kind: "text_replace",
|
|
32
|
+
field: c.field === "title" ? "title" : "meta_description",
|
|
33
|
+
before: c.before,
|
|
34
|
+
after: c.after,
|
|
35
|
+
reason: c.reason,
|
|
36
|
+
};
|
|
37
|
+
case "add_jsonld":
|
|
38
|
+
return {
|
|
39
|
+
kind: "html_insert",
|
|
40
|
+
target: "head",
|
|
41
|
+
description: `JSON-LD block (@type: ${(() => {
|
|
42
|
+
const t = c.block["@type"];
|
|
43
|
+
if (typeof t === "string")
|
|
44
|
+
return t;
|
|
45
|
+
if (Array.isArray(t))
|
|
46
|
+
return t.filter((x) => typeof x === "string").join(", ");
|
|
47
|
+
return "unknown";
|
|
48
|
+
})()})`,
|
|
49
|
+
html: serializeJsonLd(c.block),
|
|
50
|
+
reason: c.reason,
|
|
51
|
+
};
|
|
52
|
+
case "add_faq_block":
|
|
53
|
+
return {
|
|
54
|
+
kind: "html_insert",
|
|
55
|
+
target: "body",
|
|
56
|
+
description: "FAQ block",
|
|
57
|
+
html: c.html,
|
|
58
|
+
reason: c.reason,
|
|
59
|
+
};
|
|
60
|
+
case "rewrite_intro":
|
|
61
|
+
return {
|
|
62
|
+
kind: "text_replace",
|
|
63
|
+
field: "intro",
|
|
64
|
+
before: c.before,
|
|
65
|
+
after: c.after,
|
|
66
|
+
reason: c.reason,
|
|
67
|
+
};
|
|
68
|
+
case "add_internal_link":
|
|
69
|
+
// Escape both anchor text and href to prevent XSS in the rendered
|
|
70
|
+
// snippet. The validator already enforces same-host + non-empty
|
|
71
|
+
// anchor; this is defense in depth at the diff layer.
|
|
72
|
+
return {
|
|
73
|
+
kind: "html_insert",
|
|
74
|
+
target: "after_h1",
|
|
75
|
+
description: `Internal link → ${c.to}`,
|
|
76
|
+
html: `<a href="${escapeHtml(c.to)}">${escapeHtml(c.anchor)}</a>`,
|
|
77
|
+
reason: c.reason,
|
|
78
|
+
};
|
|
79
|
+
case "remove_thin_block":
|
|
80
|
+
return {
|
|
81
|
+
kind: "html_remove",
|
|
82
|
+
selector: c.selector,
|
|
83
|
+
reason: c.reason,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Convert a single domain patch into a `PatchDiff`. */
|
|
88
|
+
export function diffDomainPatch(p) {
|
|
89
|
+
switch (p.type) {
|
|
90
|
+
case "robots_txt":
|
|
91
|
+
return {
|
|
92
|
+
kind: "file_replace",
|
|
93
|
+
path: "/robots.txt",
|
|
94
|
+
before: p.before,
|
|
95
|
+
after: p.after,
|
|
96
|
+
reason: p.reason,
|
|
97
|
+
};
|
|
98
|
+
case "sitemap_xml":
|
|
99
|
+
return {
|
|
100
|
+
kind: "file_replace",
|
|
101
|
+
path: "/sitemap.xml",
|
|
102
|
+
before: p.before,
|
|
103
|
+
after: p.after,
|
|
104
|
+
reason: p.reason,
|
|
105
|
+
};
|
|
106
|
+
case "canonical_strategy":
|
|
107
|
+
return {
|
|
108
|
+
kind: "guidance",
|
|
109
|
+
topic: "canonical_strategy",
|
|
110
|
+
text: p.after,
|
|
111
|
+
reason: p.reason,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Walk every patch in a manifest and produce a structured-diff projection.
|
|
117
|
+
* Mirrors the manifest's tree structure so the UI can render side-by-side
|
|
118
|
+
* (page list / template clusters / domain-level), each populated with
|
|
119
|
+
* already-typed patch diffs.
|
|
120
|
+
*/
|
|
121
|
+
export function diffManifest(manifest) {
|
|
122
|
+
return {
|
|
123
|
+
pages: manifest.pages.map((p) => ({
|
|
124
|
+
url: p.url,
|
|
125
|
+
diffs: p.changes.map(diffPageChange),
|
|
126
|
+
})),
|
|
127
|
+
templates: manifest.templates.map((t) => ({
|
|
128
|
+
templateId: t.templateId,
|
|
129
|
+
affectedUrlCount: t.affectedUrlCount,
|
|
130
|
+
recommendation: t.recommendation,
|
|
131
|
+
examples: t.examples.map((e) => ({
|
|
132
|
+
url: e.url,
|
|
133
|
+
diffs: e.changes.map(diffPageChange),
|
|
134
|
+
})),
|
|
135
|
+
})),
|
|
136
|
+
domainLevel: manifest.domainLevel.map(diffDomainPatch),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/ai/manifest/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validation layer. Patches proposed by the LLM via `finish_audit`
|
|
3
|
+
* pass through these validators before the manifest is persisted to R2.
|
|
4
|
+
* Failures are not silently dropped — the caller (web app's session
|
|
5
|
+
* finalization) decides whether to retry the LLM, drop the failed patches,
|
|
6
|
+
* or surface them as a "needs human review" subset.
|
|
7
|
+
*
|
|
8
|
+
* Phase 4 batch 1 = validators only. Diff generation + ZIP bundle export
|
|
9
|
+
* land in batch 2.
|
|
10
|
+
*/
|
|
11
|
+
export { validateAddJsonLd, validateReplaceH1, validateRewriteMeta, validateAddFaqBlock, validateRewriteIntro, validateAddInternalLink, validateRemoveThinBlock, validatePageChange, validateRobotsTxt, validateSitemapXml, validateCanonicalStrategy, validateDomainPatch, } from "./validators/index.js";
|
|
12
|
+
export type { ValidationOk, ValidationErr, ValidationResult } from "./validators/index.js";
|
|
13
|
+
export { VALID, fail } from "./validators/index.js";
|
|
14
|
+
export { validateManifest, } from "./validate-manifest.js";
|
|
15
|
+
export type { ManifestValidationReport, PatchValidationFailure, } from "./validate-manifest.js";
|
|
16
|
+
export { diffPageChange, diffDomainPatch, diffManifest, } from "./diff.js";
|
|
17
|
+
export type { PatchDiff, ManifestDiff } from "./diff.js";
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai/manifest/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3F,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validation layer. Patches proposed by the LLM via `finish_audit`
|
|
3
|
+
* pass through these validators before the manifest is persisted to R2.
|
|
4
|
+
* Failures are not silently dropped — the caller (web app's session
|
|
5
|
+
* finalization) decides whether to retry the LLM, drop the failed patches,
|
|
6
|
+
* or surface them as a "needs human review" subset.
|
|
7
|
+
*
|
|
8
|
+
* Phase 4 batch 1 = validators only. Diff generation + ZIP bundle export
|
|
9
|
+
* land in batch 2.
|
|
10
|
+
*/
|
|
11
|
+
export { validateAddJsonLd, validateReplaceH1, validateRewriteMeta, validateAddFaqBlock, validateRewriteIntro, validateAddInternalLink, validateRemoveThinBlock, validatePageChange, validateRobotsTxt, validateSitemapXml, validateCanonicalStrategy, validateDomainPatch, } from "./validators/index.js";
|
|
12
|
+
export { VALID, fail } from "./validators/index.js";
|
|
13
|
+
export { validateManifest, } from "./validate-manifest.js";
|
|
14
|
+
export { diffPageChange, diffDomainPatch, diffManifest, } from "./diff.js";
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ai/manifest/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,gBAAgB,GACjB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,GACb,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FixManifest } from "../orchestrator/finish-tool.js";
|
|
2
|
+
export interface PatchValidationFailure {
|
|
3
|
+
/** Where in the manifest the failed patch lives. Used by the manifest UI to highlight + drop. */
|
|
4
|
+
location: {
|
|
5
|
+
kind: "page_patch";
|
|
6
|
+
pageIndex: number;
|
|
7
|
+
changeIndex: number;
|
|
8
|
+
pageUrl: string;
|
|
9
|
+
patchType: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "template_patch";
|
|
12
|
+
templateIndex: number;
|
|
13
|
+
exampleIndex: number;
|
|
14
|
+
changeIndex: number;
|
|
15
|
+
templateId: string;
|
|
16
|
+
patchType: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: "domain_patch";
|
|
19
|
+
index: number;
|
|
20
|
+
patchType: string;
|
|
21
|
+
};
|
|
22
|
+
reason: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ManifestValidationReport {
|
|
25
|
+
totalPatches: number;
|
|
26
|
+
validPatches: number;
|
|
27
|
+
failures: PatchValidationFailure[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Walk every patch in the manifest and return a per-failure report. Does
|
|
31
|
+
* NOT mutate the manifest — the caller decides what to do (drop failed
|
|
32
|
+
* patches, surface them in a "rejected" section, retry the LLM with
|
|
33
|
+
* feedback). Phase 4's manifest-finalization step will use this to filter
|
|
34
|
+
* the manifest before persistence.
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateManifest(manifest: FixManifest): ManifestValidationReport;
|
|
37
|
+
//# sourceMappingURL=validate-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-manifest.d.ts","sourceRoot":"","sources":["../../../src/ai/manifest/validate-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAGlE,MAAM,WAAW,sBAAsB;IACrC,iGAAiG;IACjG,QAAQ,EACJ;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAClG;QAAE,IAAI,EAAE,gBAAgB,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GACnI;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,sBAAsB,EAAE,CAAC;CACpC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,wBAAwB,CA6DhF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { validatePageChange, validateDomainPatch } from "./validators/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Walk every patch in the manifest and return a per-failure report. Does
|
|
4
|
+
* NOT mutate the manifest — the caller decides what to do (drop failed
|
|
5
|
+
* patches, surface them in a "rejected" section, retry the LLM with
|
|
6
|
+
* feedback). Phase 4's manifest-finalization step will use this to filter
|
|
7
|
+
* the manifest before persistence.
|
|
8
|
+
*/
|
|
9
|
+
export function validateManifest(manifest) {
|
|
10
|
+
const failures = [];
|
|
11
|
+
let total = 0;
|
|
12
|
+
manifest.pages.forEach((page, pageIndex) => {
|
|
13
|
+
page.changes.forEach((change, changeIndex) => {
|
|
14
|
+
total += 1;
|
|
15
|
+
const result = validatePageChange(change);
|
|
16
|
+
if (!result.valid) {
|
|
17
|
+
failures.push({
|
|
18
|
+
location: {
|
|
19
|
+
kind: "page_patch",
|
|
20
|
+
pageIndex,
|
|
21
|
+
changeIndex,
|
|
22
|
+
pageUrl: page.url,
|
|
23
|
+
patchType: change.type,
|
|
24
|
+
},
|
|
25
|
+
reason: result.reason,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
manifest.templates.forEach((template, templateIndex) => {
|
|
31
|
+
template.examples.forEach((example, exampleIndex) => {
|
|
32
|
+
example.changes.forEach((change, changeIndex) => {
|
|
33
|
+
total += 1;
|
|
34
|
+
const result = validatePageChange(change);
|
|
35
|
+
if (!result.valid) {
|
|
36
|
+
failures.push({
|
|
37
|
+
location: {
|
|
38
|
+
kind: "template_patch",
|
|
39
|
+
templateIndex,
|
|
40
|
+
exampleIndex,
|
|
41
|
+
changeIndex,
|
|
42
|
+
templateId: template.templateId,
|
|
43
|
+
patchType: change.type,
|
|
44
|
+
},
|
|
45
|
+
reason: result.reason,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
manifest.domainLevel.forEach((patch, index) => {
|
|
52
|
+
total += 1;
|
|
53
|
+
const result = validateDomainPatch(patch);
|
|
54
|
+
if (!result.valid) {
|
|
55
|
+
failures.push({
|
|
56
|
+
location: { kind: "domain_patch", index, patchType: patch.type },
|
|
57
|
+
reason: result.reason,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return {
|
|
62
|
+
totalPatches: total,
|
|
63
|
+
validPatches: total - failures.length,
|
|
64
|
+
failures,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=validate-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-manifest.js","sourceRoot":"","sources":["../../../src/ai/manifest/validate-manifest.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAiBhF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAqB;IACpD,MAAM,QAAQ,GAA6B,EAAE,CAAC;IAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE;QACzC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;YAC3C,KAAK,IAAI,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC;oBACZ,QAAQ,EAAE;wBACR,IAAI,EAAE,YAAY;wBAClB,SAAS;wBACT,WAAW;wBACX,OAAO,EAAE,IAAI,CAAC,GAAG;wBACjB,SAAS,EAAE,MAAM,CAAC,IAAI;qBACvB;oBACD,MAAM,EAAE,MAAM,CAAC,MAAM;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE;QACrD,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE;YAClD,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE;gBAC9C,KAAK,IAAI,CAAC,CAAC;gBACX,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAClB,QAAQ,CAAC,IAAI,CAAC;wBACZ,QAAQ,EAAE;4BACR,IAAI,EAAE,gBAAgB;4BACtB,aAAa;4BACb,YAAY;4BACZ,WAAW;4BACX,UAAU,EAAE,QAAQ,CAAC,UAAU;4BAC/B,SAAS,EAAE,MAAM,CAAC,IAAI;yBACvB;wBACD,MAAM,EAAE,MAAM,CAAC,MAAM;qBACtB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC5C,KAAK,IAAI,CAAC,CAAC;QACX,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE;gBAChE,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,YAAY,EAAE,KAAK;QACnB,YAAY,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM;QACrC,QAAQ;KACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { FixManifest } from "../../orchestrator/finish-tool.js";
|
|
2
|
+
import { type ValidationResult } from "./types.js";
|
|
3
|
+
type DomainPatch = FixManifest["domainLevel"][number];
|
|
4
|
+
export declare function validateRobotsTxt(p: DomainPatch): ValidationResult;
|
|
5
|
+
export declare function validateSitemapXml(p: DomainPatch): ValidationResult;
|
|
6
|
+
/**
|
|
7
|
+
* canonical_strategy is freeform guidance text describing how the site
|
|
8
|
+
* should structure its canonicals (e.g. "always self-canonical except for
|
|
9
|
+
* paginated views which point to page 1"). Validation just rejects empty
|
|
10
|
+
* or trivially-short text — content quality is the LLM's call.
|
|
11
|
+
*/
|
|
12
|
+
export declare function validateCanonicalStrategy(p: DomainPatch): ValidationResult;
|
|
13
|
+
export declare function validateDomainPatch(p: DomainPatch): ValidationResult;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=domain-patches.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-patches.d.ts","sourceRoot":"","sources":["../../../../src/ai/manifest/validators/domain-patches.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhE,KAAK,WAAW,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AActD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,WAAW,GAAG,gBAAgB,CAqBlE;AAgBD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,WAAW,GAAG,gBAAgB,CAoCnE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,WAAW,GAAG,gBAAgB,CAM1E;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,WAAW,GAAG,gBAAgB,CASpE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { fail, VALID } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* robots.txt validation: parse line-by-line, require at least one
|
|
4
|
+
* `User-agent:` directive, reject lines that aren't either a comment, blank,
|
|
5
|
+
* or a recognized directive (User-agent, Disallow, Allow, Sitemap,
|
|
6
|
+
* Crawl-delay).
|
|
7
|
+
*
|
|
8
|
+
* Not as strict as a real robots-parser library — but catches the failure
|
|
9
|
+
* modes the LLM is most likely to produce (bad directive names, missing
|
|
10
|
+
* User-agent block, accidental markdown).
|
|
11
|
+
*/
|
|
12
|
+
const RECOGNIZED_DIRECTIVE_RE = /^(user-agent|disallow|allow|sitemap|crawl-delay|host)\s*:/i;
|
|
13
|
+
export function validateRobotsTxt(p) {
|
|
14
|
+
const text = p.after.trim();
|
|
15
|
+
if (!text)
|
|
16
|
+
return fail("robots_txt: after-text is empty");
|
|
17
|
+
const lines = text.split(/\r?\n/);
|
|
18
|
+
let sawUserAgent = false;
|
|
19
|
+
let lineNo = 0;
|
|
20
|
+
for (const raw of lines) {
|
|
21
|
+
lineNo += 1;
|
|
22
|
+
const line = raw.trim();
|
|
23
|
+
if (!line)
|
|
24
|
+
continue;
|
|
25
|
+
if (line.startsWith("#"))
|
|
26
|
+
continue;
|
|
27
|
+
if (!RECOGNIZED_DIRECTIVE_RE.test(line)) {
|
|
28
|
+
return fail(`robots_txt: unrecognized directive on line ${lineNo}: ${line.slice(0, 60)}`);
|
|
29
|
+
}
|
|
30
|
+
if (/^user-agent\s*:/i.test(line))
|
|
31
|
+
sawUserAgent = true;
|
|
32
|
+
}
|
|
33
|
+
if (!sawUserAgent) {
|
|
34
|
+
return fail("robots_txt: no User-agent directive present");
|
|
35
|
+
}
|
|
36
|
+
return VALID;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* sitemap.xml validation: require a recognizable root element (`<urlset>` or
|
|
40
|
+
* `<sitemapindex>`), require well-formed XML structure (matching open/close
|
|
41
|
+
* tags), require each `<url>` to carry a `<loc>` child.
|
|
42
|
+
*
|
|
43
|
+
* Skips full XSD validation — pulling in a libxml binding for one patch
|
|
44
|
+
* type isn't worth the deploy weight. The structural checks catch the
|
|
45
|
+
* common LLM failure modes.
|
|
46
|
+
*/
|
|
47
|
+
const URLSET_RE = /<urlset[\s>]/i;
|
|
48
|
+
const SITEMAPINDEX_RE = /<sitemapindex[\s>]/i;
|
|
49
|
+
const URL_BLOCK_RE = /<url[\s>][\s\S]*?<\/url>/gi;
|
|
50
|
+
const LOC_RE = /<loc>[\s\S]*?<\/loc>/i;
|
|
51
|
+
export function validateSitemapXml(p) {
|
|
52
|
+
const xml = p.after.trim();
|
|
53
|
+
if (!xml)
|
|
54
|
+
return fail("sitemap_xml: after-text is empty");
|
|
55
|
+
const isUrlset = URLSET_RE.test(xml);
|
|
56
|
+
const isIndex = SITEMAPINDEX_RE.test(xml);
|
|
57
|
+
if (!isUrlset && !isIndex) {
|
|
58
|
+
return fail("sitemap_xml: missing <urlset> or <sitemapindex> root element");
|
|
59
|
+
}
|
|
60
|
+
// Cheap well-formed-ness check: count opening vs closing tags for the
|
|
61
|
+
// root element and `<url>` blocks. Mismatch indicates malformed XML.
|
|
62
|
+
if (isUrlset) {
|
|
63
|
+
const opens = (xml.match(/<urlset[\s>]/gi) ?? []).length;
|
|
64
|
+
const closes = (xml.match(/<\/urlset>/gi) ?? []).length;
|
|
65
|
+
if (opens !== closes) {
|
|
66
|
+
return fail("sitemap_xml: <urlset> open/close tag count mismatch");
|
|
67
|
+
}
|
|
68
|
+
const urlBlocks = xml.match(URL_BLOCK_RE) ?? [];
|
|
69
|
+
if (urlBlocks.length === 0) {
|
|
70
|
+
return fail("sitemap_xml: <urlset> has no <url> children");
|
|
71
|
+
}
|
|
72
|
+
for (const block of urlBlocks) {
|
|
73
|
+
if (!LOC_RE.test(block)) {
|
|
74
|
+
return fail("sitemap_xml: <url> block missing <loc>");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const opens = (xml.match(/<sitemapindex[\s>]/gi) ?? []).length;
|
|
80
|
+
const closes = (xml.match(/<\/sitemapindex>/gi) ?? []).length;
|
|
81
|
+
if (opens !== closes) {
|
|
82
|
+
return fail("sitemap_xml: <sitemapindex> open/close tag count mismatch");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return VALID;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* canonical_strategy is freeform guidance text describing how the site
|
|
89
|
+
* should structure its canonicals (e.g. "always self-canonical except for
|
|
90
|
+
* paginated views which point to page 1"). Validation just rejects empty
|
|
91
|
+
* or trivially-short text — content quality is the LLM's call.
|
|
92
|
+
*/
|
|
93
|
+
export function validateCanonicalStrategy(p) {
|
|
94
|
+
const after = p.after.trim();
|
|
95
|
+
if (after.length < 30) {
|
|
96
|
+
return fail(`canonical_strategy: too short (${after.length} < 30 chars) — needs concrete guidance`);
|
|
97
|
+
}
|
|
98
|
+
return VALID;
|
|
99
|
+
}
|
|
100
|
+
export function validateDomainPatch(p) {
|
|
101
|
+
switch (p.type) {
|
|
102
|
+
case "robots_txt":
|
|
103
|
+
return validateRobotsTxt(p);
|
|
104
|
+
case "sitemap_xml":
|
|
105
|
+
return validateSitemapXml(p);
|
|
106
|
+
case "canonical_strategy":
|
|
107
|
+
return validateCanonicalStrategy(p);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=domain-patches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-patches.js","sourceRoot":"","sources":["../../../../src/ai/manifest/validators/domain-patches.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { VALID, fail } from "./types.js";
|
|
2
|
+
export type { ValidationOk, ValidationErr, ValidationResult } from "./types.js";
|
|
3
|
+
export { validateAddJsonLd, validateReplaceH1, validateRewriteMeta, validateAddFaqBlock, validateRewriteIntro, validateAddInternalLink, validateRemoveThinBlock, validatePageChange, } from "./page-changes.js";
|
|
4
|
+
export { validateRobotsTxt, validateSitemapXml, validateCanonicalStrategy, validateDomainPatch, } from "./domain-patches.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ai/manifest/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { VALID, fail } from "./types.js";
|
|
2
|
+
export { validateAddJsonLd, validateReplaceH1, validateRewriteMeta, validateAddFaqBlock, validateRewriteIntro, validateAddInternalLink, validateRemoveThinBlock, validatePageChange, } from "./page-changes.js";
|
|
3
|
+
export { validateRobotsTxt, validateSitemapXml, validateCanonicalStrategy, validateDomainPatch, } from "./domain-patches.js";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ai/manifest/validators/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { FixManifest } from "../../orchestrator/finish-tool.js";
|
|
2
|
+
import { type ValidationResult } from "./types.js";
|
|
3
|
+
type PageChange = FixManifest["pages"][number]["changes"][number];
|
|
4
|
+
/** Schema.org required-property check for proposed JSON-LD blocks. */
|
|
5
|
+
export declare function validateAddJsonLd(c: Extract<PageChange, {
|
|
6
|
+
type: "add_jsonld";
|
|
7
|
+
}>): ValidationResult;
|
|
8
|
+
export declare function validateReplaceH1(c: Extract<PageChange, {
|
|
9
|
+
type: "replace_h1";
|
|
10
|
+
}>): ValidationResult;
|
|
11
|
+
export declare function validateRewriteMeta(c: Extract<PageChange, {
|
|
12
|
+
type: "rewrite_meta";
|
|
13
|
+
}>): ValidationResult;
|
|
14
|
+
/**
|
|
15
|
+
* HTML-safety check using a cheerio-based allowlist. Rejects script/iframe/
|
|
16
|
+
* object/embed/form/style elements and any href/src that uses
|
|
17
|
+
* javascript:/data:/vbscript: schemes. Defense in depth — the LLM-generated
|
|
18
|
+
* patch is being prepared for paste into a CMS, not auto-applied, but a
|
|
19
|
+
* malicious patch in a public manifest is still a footgun.
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateAddFaqBlock(c: Extract<PageChange, {
|
|
22
|
+
type: "add_faq_block";
|
|
23
|
+
}>): ValidationResult;
|
|
24
|
+
export declare function validateRewriteIntro(c: Extract<PageChange, {
|
|
25
|
+
type: "rewrite_intro";
|
|
26
|
+
}>): ValidationResult;
|
|
27
|
+
export declare function validateAddInternalLink(c: Extract<PageChange, {
|
|
28
|
+
type: "add_internal_link";
|
|
29
|
+
}>): ValidationResult;
|
|
30
|
+
export declare function validateRemoveThinBlock(c: Extract<PageChange, {
|
|
31
|
+
type: "remove_thin_block";
|
|
32
|
+
}>): ValidationResult;
|
|
33
|
+
/** Dispatcher: routes a `PageChange` to its specific validator. */
|
|
34
|
+
export declare function validatePageChange(c: PageChange): ValidationResult;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=page-changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-changes.d.ts","sourceRoot":"","sources":["../../../../src/ai/manifest/validators/page-changes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhE,KAAK,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AA6ClE,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,GAAG,gBAAgB,CAqBlG;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,GAAG,gBAAgB,CAMlG;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC,GAAG,gBAAgB,CAWtG;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,GAAG,gBAAgB,CAuCvG;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC,GAAG,gBAAgB,CAOxG;AAED,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,GACpD,gBAAgB,CA0BlB;AAED,wBAAgB,uBAAuB,CACrC,CAAC,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC,GACpD,gBAAgB,CAYlB;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAiBlE"}
|