@rankcli/agent-runtime 0.0.29 → 0.0.30
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/dist/index.d.mts +190 -163
- package/dist/index.d.ts +190 -163
- package/dist/index.js +177 -13
- package/dist/index.mjs +174 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3352,7 +3352,9 @@ __export(index_exports, {
|
|
|
3352
3352
|
analyzeUrlSafety: () => analyzeUrlSafety,
|
|
3353
3353
|
analyzers: () => analyzers_exports,
|
|
3354
3354
|
applyFixes: () => applyFixes,
|
|
3355
|
+
assessReplacement: () => assessReplacement,
|
|
3355
3356
|
buildDeterministicFixes: () => buildDeterministicFixes,
|
|
3357
|
+
buildFrameworkGuidance: () => buildFrameworkGuidance,
|
|
3356
3358
|
buildGSCApiRequest: () => buildGSCApiRequest,
|
|
3357
3359
|
buildGSCRequest: () => buildGSCRequest,
|
|
3358
3360
|
calculateAIVisibilityScore: () => calculateAIVisibilityScore,
|
|
@@ -3393,6 +3395,7 @@ __export(index_exports, {
|
|
|
3393
3395
|
createPullRequest: () => createPullRequest,
|
|
3394
3396
|
createSEOCommit: () => createSEOCommit,
|
|
3395
3397
|
createSEOCommits: () => createSEOCommits,
|
|
3398
|
+
describeConcerns: () => describeConcerns,
|
|
3396
3399
|
detectDuplicates: () => detectDuplicates,
|
|
3397
3400
|
detectFramework: () => detectFramework4,
|
|
3398
3401
|
detectGitHubPages: () => detectGitHubPages,
|
|
@@ -12740,20 +12743,20 @@ function findMissingPreconnects(thirdPartyDomains, existingHints) {
|
|
|
12740
12743
|
}
|
|
12741
12744
|
})
|
|
12742
12745
|
);
|
|
12743
|
-
const
|
|
12746
|
+
const missing2 = [];
|
|
12744
12747
|
for (const domain of thirdPartyDomains) {
|
|
12745
12748
|
try {
|
|
12746
12749
|
const hostname = new URL(domain).hostname;
|
|
12747
12750
|
const recommended = CRITICAL_THIRD_PARTIES[hostname] || [domain];
|
|
12748
12751
|
for (const rec of recommended) {
|
|
12749
12752
|
if (!preconnected.has(rec)) {
|
|
12750
|
-
|
|
12753
|
+
missing2.push(rec);
|
|
12751
12754
|
}
|
|
12752
12755
|
}
|
|
12753
12756
|
} catch {
|
|
12754
12757
|
}
|
|
12755
12758
|
}
|
|
12756
|
-
return [...new Set(
|
|
12759
|
+
return [...new Set(missing2)];
|
|
12757
12760
|
}
|
|
12758
12761
|
function analyzeResourceHints(html, url) {
|
|
12759
12762
|
const issues = [];
|
|
@@ -33049,6 +33052,167 @@ function findAppRoot(files) {
|
|
|
33049
33052
|
return `${nonRoot[0]}/`;
|
|
33050
33053
|
}
|
|
33051
33054
|
|
|
33055
|
+
// src/fixer/safety.ts
|
|
33056
|
+
var HTML_EXT = /\.html?$/i;
|
|
33057
|
+
var SOURCE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|vue|svelte|astro)$/i;
|
|
33058
|
+
function attributeValues(html, pattern) {
|
|
33059
|
+
const found = /* @__PURE__ */ new Set();
|
|
33060
|
+
for (const match of html.matchAll(pattern)) {
|
|
33061
|
+
const value = match[1]?.trim();
|
|
33062
|
+
if (value) found.add(value);
|
|
33063
|
+
}
|
|
33064
|
+
return found;
|
|
33065
|
+
}
|
|
33066
|
+
function scriptSources(html) {
|
|
33067
|
+
return attributeValues(html, /<script[^>]+src=["']([^"']+)["']/gi);
|
|
33068
|
+
}
|
|
33069
|
+
function stylesheetHrefs(html) {
|
|
33070
|
+
return attributeValues(html, /<link[^>]+href=["']([^"']+)["'][^>]*>/gi);
|
|
33071
|
+
}
|
|
33072
|
+
function verificationTokens(html) {
|
|
33073
|
+
const found = /* @__PURE__ */ new Set();
|
|
33074
|
+
for (const match of html.matchAll(/<meta[^>]+name=["']([^"']*(?:site-verification|verify|verification)[^"']*)["'][^>]*>/gi)) {
|
|
33075
|
+
found.add(match[1].toLowerCase());
|
|
33076
|
+
}
|
|
33077
|
+
return found;
|
|
33078
|
+
}
|
|
33079
|
+
function importSpecifiers(source) {
|
|
33080
|
+
const found = /* @__PURE__ */ new Set();
|
|
33081
|
+
for (const match of source.matchAll(/\bfrom\s+["']([^"']+)["']/g)) found.add(match[1]);
|
|
33082
|
+
for (const match of source.matchAll(/\brequire\(\s*["']([^"']+)["']\s*\)/g)) found.add(match[1]);
|
|
33083
|
+
return found;
|
|
33084
|
+
}
|
|
33085
|
+
function missing(before, after) {
|
|
33086
|
+
return [...before].filter((value) => !after.has(value));
|
|
33087
|
+
}
|
|
33088
|
+
function xmlConcern(xml) {
|
|
33089
|
+
const stack = [];
|
|
33090
|
+
for (const match of xml.matchAll(/<\/?([A-Za-z_][\w:.-]*)[^>]*?(\/?)>/g)) {
|
|
33091
|
+
const [tag, name, selfClosing] = match;
|
|
33092
|
+
if (tag.startsWith("<?") || tag.startsWith("<!")) continue;
|
|
33093
|
+
if (tag.startsWith("</")) {
|
|
33094
|
+
if (stack.pop() !== name) return `unbalanced </${name}>`;
|
|
33095
|
+
} else if (!selfClosing) {
|
|
33096
|
+
stack.push(name);
|
|
33097
|
+
}
|
|
33098
|
+
}
|
|
33099
|
+
return stack.length ? `unclosed <${stack[stack.length - 1]}>` : null;
|
|
33100
|
+
}
|
|
33101
|
+
function sitemapUrlCount(xml) {
|
|
33102
|
+
return [...xml.matchAll(/<loc>/gi)].length;
|
|
33103
|
+
}
|
|
33104
|
+
function newestLastmod(xml) {
|
|
33105
|
+
const dates = [...xml.matchAll(/<lastmod>([^<]+)<\/lastmod>/gi)].map((m) => Date.parse(m[1].trim())).filter((t) => !Number.isNaN(t));
|
|
33106
|
+
return dates.length ? Math.max(...dates) : null;
|
|
33107
|
+
}
|
|
33108
|
+
function jsonLdConcerns(html) {
|
|
33109
|
+
const bad = [];
|
|
33110
|
+
for (const match of html.matchAll(/<script[^>]+type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi)) {
|
|
33111
|
+
try {
|
|
33112
|
+
JSON.parse(match[1]);
|
|
33113
|
+
} catch (error) {
|
|
33114
|
+
bad.push(error.message);
|
|
33115
|
+
}
|
|
33116
|
+
}
|
|
33117
|
+
return bad;
|
|
33118
|
+
}
|
|
33119
|
+
function assessReplacement(path3, original, replacement) {
|
|
33120
|
+
const concerns = [];
|
|
33121
|
+
const add = (code, detail) => concerns.push({ code, detail });
|
|
33122
|
+
if (/\.json$/i.test(path3) || /\.webmanifest$/i.test(path3)) {
|
|
33123
|
+
try {
|
|
33124
|
+
JSON.parse(replacement);
|
|
33125
|
+
} catch (error) {
|
|
33126
|
+
add("invalid_json", error.message);
|
|
33127
|
+
}
|
|
33128
|
+
}
|
|
33129
|
+
if (/\.xml$/i.test(path3)) {
|
|
33130
|
+
const problem = xmlConcern(replacement);
|
|
33131
|
+
if (problem) add("invalid_xml", problem);
|
|
33132
|
+
}
|
|
33133
|
+
if (HTML_EXT.test(path3)) {
|
|
33134
|
+
for (const problem of jsonLdConcerns(replacement)) add("invalid_json_ld", problem);
|
|
33135
|
+
}
|
|
33136
|
+
if (original === null) return concerns;
|
|
33137
|
+
if (replacement.length < original.length * 0.6) {
|
|
33138
|
+
add("shrunk", `${Math.round(replacement.length / original.length * 100)}% of the original length`);
|
|
33139
|
+
}
|
|
33140
|
+
if (HTML_EXT.test(path3)) {
|
|
33141
|
+
for (const tag of ["</head>", "</body>", "</html>"]) {
|
|
33142
|
+
if (original.includes(tag) && !replacement.includes(tag)) add("lost_closing_tag", tag);
|
|
33143
|
+
}
|
|
33144
|
+
const lostScripts = missing(scriptSources(original), scriptSources(replacement));
|
|
33145
|
+
if (lostScripts.length) add("lost_script", lostScripts.join(", "));
|
|
33146
|
+
const lostStyles = missing(stylesheetHrefs(original), stylesheetHrefs(replacement));
|
|
33147
|
+
if (lostStyles.length) add("lost_stylesheet", lostStyles.join(", "));
|
|
33148
|
+
const lostVerification = missing(verificationTokens(original), verificationTokens(replacement));
|
|
33149
|
+
if (lostVerification.length) add("lost_verification", lostVerification.join(", "));
|
|
33150
|
+
}
|
|
33151
|
+
if (SOURCE_EXT.test(path3)) {
|
|
33152
|
+
const lostImports = missing(importSpecifiers(original), importSpecifiers(replacement));
|
|
33153
|
+
if (lostImports.length) add("lost_import", lostImports.join(", "));
|
|
33154
|
+
}
|
|
33155
|
+
if (/sitemap[^/]*\.xml$/i.test(path3)) {
|
|
33156
|
+
const before = sitemapUrlCount(original);
|
|
33157
|
+
const after = sitemapUrlCount(replacement);
|
|
33158
|
+
if (after < before) add("fewer_sitemap_urls", `${before} -> ${after}`);
|
|
33159
|
+
const newestBefore = newestLastmod(original);
|
|
33160
|
+
const newestAfter = newestLastmod(replacement);
|
|
33161
|
+
if (newestBefore !== null && newestAfter !== null && newestAfter < newestBefore) {
|
|
33162
|
+
add(
|
|
33163
|
+
"lastmod_moved_backwards",
|
|
33164
|
+
`${new Date(newestBefore).toISOString().slice(0, 10)} -> ${new Date(newestAfter).toISOString().slice(0, 10)}`
|
|
33165
|
+
);
|
|
33166
|
+
}
|
|
33167
|
+
}
|
|
33168
|
+
return concerns;
|
|
33169
|
+
}
|
|
33170
|
+
function describeConcerns(concerns) {
|
|
33171
|
+
return concerns.map((c) => `${c.code} (${c.detail})`).join("; ");
|
|
33172
|
+
}
|
|
33173
|
+
|
|
33174
|
+
// src/fixer/framework-guidance.ts
|
|
33175
|
+
var DEFAULT_MAX_CHARS = 4e3;
|
|
33176
|
+
function checkBlock(check) {
|
|
33177
|
+
const fix = check.howToFix?.trim();
|
|
33178
|
+
return [
|
|
33179
|
+
`### ${check.title}${check.code ? ` (${check.code})` : ""}`,
|
|
33180
|
+
check.description?.trim(),
|
|
33181
|
+
fix ? `How this framework wants it fixed:
|
|
33182
|
+
${fix}` : null
|
|
33183
|
+
].filter(Boolean).join("\n");
|
|
33184
|
+
}
|
|
33185
|
+
function buildFrameworkGuidance(recipe, options = {}) {
|
|
33186
|
+
if (!recipe) return "";
|
|
33187
|
+
const budget = options.maxChars ?? DEFAULT_MAX_CHARS;
|
|
33188
|
+
const reported = new Set(options.issueCodes ?? []);
|
|
33189
|
+
const header = [
|
|
33190
|
+
`## ${recipe.display_name} conventions`,
|
|
33191
|
+
`Renders on the server by default: ${recipe.ssr_default ? "yes" : "no"}.`,
|
|
33192
|
+
recipe.seo_challenges?.length ? `Known traps in this framework:
|
|
33193
|
+
${recipe.seo_challenges.map((c) => `- ${c}`).join("\n")}` : null
|
|
33194
|
+
].filter(Boolean).join("\n");
|
|
33195
|
+
const checks = recipe.checks ?? [];
|
|
33196
|
+
const relevant = checks.filter((c) => c.code && reported.has(c.code));
|
|
33197
|
+
const rest = checks.filter((c) => !relevant.includes(c));
|
|
33198
|
+
let out = header;
|
|
33199
|
+
let included = 0;
|
|
33200
|
+
for (const check of [...relevant, ...rest]) {
|
|
33201
|
+
const block = checkBlock(check);
|
|
33202
|
+
if (out.length + block.length + 2 > budget) break;
|
|
33203
|
+
out += `
|
|
33204
|
+
|
|
33205
|
+
${block}`;
|
|
33206
|
+
included++;
|
|
33207
|
+
}
|
|
33208
|
+
if (included < checks.length) {
|
|
33209
|
+
out += `
|
|
33210
|
+
|
|
33211
|
+
_(${checks.length - included} more ${recipe.display_name} checks omitted.)_`;
|
|
33212
|
+
}
|
|
33213
|
+
return out;
|
|
33214
|
+
}
|
|
33215
|
+
|
|
33052
33216
|
// src/git/commit-helper.ts
|
|
33053
33217
|
var import_child_process2 = require("child_process");
|
|
33054
33218
|
var import_util2 = require("util");
|
|
@@ -35594,19 +35758,16 @@ __export(frameworks_exports, {
|
|
|
35594
35758
|
loadRecipe: () => loadRecipe
|
|
35595
35759
|
});
|
|
35596
35760
|
var SUPPORTED_FRAMEWORKS = [
|
|
35597
|
-
"react",
|
|
35598
|
-
"nextjs",
|
|
35599
|
-
"vue",
|
|
35600
|
-
"nuxt",
|
|
35601
35761
|
"angular",
|
|
35602
|
-
"svelte",
|
|
35603
|
-
"sveltekit",
|
|
35604
35762
|
"astro",
|
|
35605
|
-
"remix",
|
|
35606
|
-
"gatsby",
|
|
35607
|
-
"rails",
|
|
35608
|
-
"laravel",
|
|
35609
35763
|
"django",
|
|
35764
|
+
"laravel",
|
|
35765
|
+
"nextjs",
|
|
35766
|
+
"nuxt",
|
|
35767
|
+
"rails",
|
|
35768
|
+
"react",
|
|
35769
|
+
"sveltekit",
|
|
35770
|
+
"vue",
|
|
35610
35771
|
"wordpress"
|
|
35611
35772
|
];
|
|
35612
35773
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -35656,7 +35817,9 @@ var SUPPORTED_FRAMEWORKS = [
|
|
|
35656
35817
|
analyzeUrlSafety,
|
|
35657
35818
|
analyzers,
|
|
35658
35819
|
applyFixes,
|
|
35820
|
+
assessReplacement,
|
|
35659
35821
|
buildDeterministicFixes,
|
|
35822
|
+
buildFrameworkGuidance,
|
|
35660
35823
|
buildGSCApiRequest,
|
|
35661
35824
|
buildGSCRequest,
|
|
35662
35825
|
calculateAIVisibilityScore,
|
|
@@ -35697,6 +35860,7 @@ var SUPPORTED_FRAMEWORKS = [
|
|
|
35697
35860
|
createPullRequest,
|
|
35698
35861
|
createSEOCommit,
|
|
35699
35862
|
createSEOCommits,
|
|
35863
|
+
describeConcerns,
|
|
35700
35864
|
detectDuplicates,
|
|
35701
35865
|
detectFramework,
|
|
35702
35866
|
detectGitHubPages,
|
package/dist/index.mjs
CHANGED
|
@@ -9199,20 +9199,20 @@ function findMissingPreconnects(thirdPartyDomains, existingHints) {
|
|
|
9199
9199
|
}
|
|
9200
9200
|
})
|
|
9201
9201
|
);
|
|
9202
|
-
const
|
|
9202
|
+
const missing2 = [];
|
|
9203
9203
|
for (const domain of thirdPartyDomains) {
|
|
9204
9204
|
try {
|
|
9205
9205
|
const hostname = new URL(domain).hostname;
|
|
9206
9206
|
const recommended = CRITICAL_THIRD_PARTIES[hostname] || [domain];
|
|
9207
9207
|
for (const rec of recommended) {
|
|
9208
9208
|
if (!preconnected.has(rec)) {
|
|
9209
|
-
|
|
9209
|
+
missing2.push(rec);
|
|
9210
9210
|
}
|
|
9211
9211
|
}
|
|
9212
9212
|
} catch {
|
|
9213
9213
|
}
|
|
9214
9214
|
}
|
|
9215
|
-
return [...new Set(
|
|
9215
|
+
return [...new Set(missing2)];
|
|
9216
9216
|
}
|
|
9217
9217
|
function analyzeResourceHints(html, url) {
|
|
9218
9218
|
const issues = [];
|
|
@@ -29481,6 +29481,167 @@ function findAppRoot(files) {
|
|
|
29481
29481
|
return `${nonRoot[0]}/`;
|
|
29482
29482
|
}
|
|
29483
29483
|
|
|
29484
|
+
// src/fixer/safety.ts
|
|
29485
|
+
var HTML_EXT = /\.html?$/i;
|
|
29486
|
+
var SOURCE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|vue|svelte|astro)$/i;
|
|
29487
|
+
function attributeValues(html, pattern) {
|
|
29488
|
+
const found = /* @__PURE__ */ new Set();
|
|
29489
|
+
for (const match of html.matchAll(pattern)) {
|
|
29490
|
+
const value = match[1]?.trim();
|
|
29491
|
+
if (value) found.add(value);
|
|
29492
|
+
}
|
|
29493
|
+
return found;
|
|
29494
|
+
}
|
|
29495
|
+
function scriptSources(html) {
|
|
29496
|
+
return attributeValues(html, /<script[^>]+src=["']([^"']+)["']/gi);
|
|
29497
|
+
}
|
|
29498
|
+
function stylesheetHrefs(html) {
|
|
29499
|
+
return attributeValues(html, /<link[^>]+href=["']([^"']+)["'][^>]*>/gi);
|
|
29500
|
+
}
|
|
29501
|
+
function verificationTokens(html) {
|
|
29502
|
+
const found = /* @__PURE__ */ new Set();
|
|
29503
|
+
for (const match of html.matchAll(/<meta[^>]+name=["']([^"']*(?:site-verification|verify|verification)[^"']*)["'][^>]*>/gi)) {
|
|
29504
|
+
found.add(match[1].toLowerCase());
|
|
29505
|
+
}
|
|
29506
|
+
return found;
|
|
29507
|
+
}
|
|
29508
|
+
function importSpecifiers(source) {
|
|
29509
|
+
const found = /* @__PURE__ */ new Set();
|
|
29510
|
+
for (const match of source.matchAll(/\bfrom\s+["']([^"']+)["']/g)) found.add(match[1]);
|
|
29511
|
+
for (const match of source.matchAll(/\brequire\(\s*["']([^"']+)["']\s*\)/g)) found.add(match[1]);
|
|
29512
|
+
return found;
|
|
29513
|
+
}
|
|
29514
|
+
function missing(before, after) {
|
|
29515
|
+
return [...before].filter((value) => !after.has(value));
|
|
29516
|
+
}
|
|
29517
|
+
function xmlConcern(xml) {
|
|
29518
|
+
const stack = [];
|
|
29519
|
+
for (const match of xml.matchAll(/<\/?([A-Za-z_][\w:.-]*)[^>]*?(\/?)>/g)) {
|
|
29520
|
+
const [tag, name, selfClosing] = match;
|
|
29521
|
+
if (tag.startsWith("<?") || tag.startsWith("<!")) continue;
|
|
29522
|
+
if (tag.startsWith("</")) {
|
|
29523
|
+
if (stack.pop() !== name) return `unbalanced </${name}>`;
|
|
29524
|
+
} else if (!selfClosing) {
|
|
29525
|
+
stack.push(name);
|
|
29526
|
+
}
|
|
29527
|
+
}
|
|
29528
|
+
return stack.length ? `unclosed <${stack[stack.length - 1]}>` : null;
|
|
29529
|
+
}
|
|
29530
|
+
function sitemapUrlCount(xml) {
|
|
29531
|
+
return [...xml.matchAll(/<loc>/gi)].length;
|
|
29532
|
+
}
|
|
29533
|
+
function newestLastmod(xml) {
|
|
29534
|
+
const dates = [...xml.matchAll(/<lastmod>([^<]+)<\/lastmod>/gi)].map((m) => Date.parse(m[1].trim())).filter((t) => !Number.isNaN(t));
|
|
29535
|
+
return dates.length ? Math.max(...dates) : null;
|
|
29536
|
+
}
|
|
29537
|
+
function jsonLdConcerns(html) {
|
|
29538
|
+
const bad = [];
|
|
29539
|
+
for (const match of html.matchAll(/<script[^>]+type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi)) {
|
|
29540
|
+
try {
|
|
29541
|
+
JSON.parse(match[1]);
|
|
29542
|
+
} catch (error) {
|
|
29543
|
+
bad.push(error.message);
|
|
29544
|
+
}
|
|
29545
|
+
}
|
|
29546
|
+
return bad;
|
|
29547
|
+
}
|
|
29548
|
+
function assessReplacement(path3, original, replacement) {
|
|
29549
|
+
const concerns = [];
|
|
29550
|
+
const add = (code, detail) => concerns.push({ code, detail });
|
|
29551
|
+
if (/\.json$/i.test(path3) || /\.webmanifest$/i.test(path3)) {
|
|
29552
|
+
try {
|
|
29553
|
+
JSON.parse(replacement);
|
|
29554
|
+
} catch (error) {
|
|
29555
|
+
add("invalid_json", error.message);
|
|
29556
|
+
}
|
|
29557
|
+
}
|
|
29558
|
+
if (/\.xml$/i.test(path3)) {
|
|
29559
|
+
const problem = xmlConcern(replacement);
|
|
29560
|
+
if (problem) add("invalid_xml", problem);
|
|
29561
|
+
}
|
|
29562
|
+
if (HTML_EXT.test(path3)) {
|
|
29563
|
+
for (const problem of jsonLdConcerns(replacement)) add("invalid_json_ld", problem);
|
|
29564
|
+
}
|
|
29565
|
+
if (original === null) return concerns;
|
|
29566
|
+
if (replacement.length < original.length * 0.6) {
|
|
29567
|
+
add("shrunk", `${Math.round(replacement.length / original.length * 100)}% of the original length`);
|
|
29568
|
+
}
|
|
29569
|
+
if (HTML_EXT.test(path3)) {
|
|
29570
|
+
for (const tag of ["</head>", "</body>", "</html>"]) {
|
|
29571
|
+
if (original.includes(tag) && !replacement.includes(tag)) add("lost_closing_tag", tag);
|
|
29572
|
+
}
|
|
29573
|
+
const lostScripts = missing(scriptSources(original), scriptSources(replacement));
|
|
29574
|
+
if (lostScripts.length) add("lost_script", lostScripts.join(", "));
|
|
29575
|
+
const lostStyles = missing(stylesheetHrefs(original), stylesheetHrefs(replacement));
|
|
29576
|
+
if (lostStyles.length) add("lost_stylesheet", lostStyles.join(", "));
|
|
29577
|
+
const lostVerification = missing(verificationTokens(original), verificationTokens(replacement));
|
|
29578
|
+
if (lostVerification.length) add("lost_verification", lostVerification.join(", "));
|
|
29579
|
+
}
|
|
29580
|
+
if (SOURCE_EXT.test(path3)) {
|
|
29581
|
+
const lostImports = missing(importSpecifiers(original), importSpecifiers(replacement));
|
|
29582
|
+
if (lostImports.length) add("lost_import", lostImports.join(", "));
|
|
29583
|
+
}
|
|
29584
|
+
if (/sitemap[^/]*\.xml$/i.test(path3)) {
|
|
29585
|
+
const before = sitemapUrlCount(original);
|
|
29586
|
+
const after = sitemapUrlCount(replacement);
|
|
29587
|
+
if (after < before) add("fewer_sitemap_urls", `${before} -> ${after}`);
|
|
29588
|
+
const newestBefore = newestLastmod(original);
|
|
29589
|
+
const newestAfter = newestLastmod(replacement);
|
|
29590
|
+
if (newestBefore !== null && newestAfter !== null && newestAfter < newestBefore) {
|
|
29591
|
+
add(
|
|
29592
|
+
"lastmod_moved_backwards",
|
|
29593
|
+
`${new Date(newestBefore).toISOString().slice(0, 10)} -> ${new Date(newestAfter).toISOString().slice(0, 10)}`
|
|
29594
|
+
);
|
|
29595
|
+
}
|
|
29596
|
+
}
|
|
29597
|
+
return concerns;
|
|
29598
|
+
}
|
|
29599
|
+
function describeConcerns(concerns) {
|
|
29600
|
+
return concerns.map((c) => `${c.code} (${c.detail})`).join("; ");
|
|
29601
|
+
}
|
|
29602
|
+
|
|
29603
|
+
// src/fixer/framework-guidance.ts
|
|
29604
|
+
var DEFAULT_MAX_CHARS = 4e3;
|
|
29605
|
+
function checkBlock(check) {
|
|
29606
|
+
const fix = check.howToFix?.trim();
|
|
29607
|
+
return [
|
|
29608
|
+
`### ${check.title}${check.code ? ` (${check.code})` : ""}`,
|
|
29609
|
+
check.description?.trim(),
|
|
29610
|
+
fix ? `How this framework wants it fixed:
|
|
29611
|
+
${fix}` : null
|
|
29612
|
+
].filter(Boolean).join("\n");
|
|
29613
|
+
}
|
|
29614
|
+
function buildFrameworkGuidance(recipe, options = {}) {
|
|
29615
|
+
if (!recipe) return "";
|
|
29616
|
+
const budget = options.maxChars ?? DEFAULT_MAX_CHARS;
|
|
29617
|
+
const reported = new Set(options.issueCodes ?? []);
|
|
29618
|
+
const header = [
|
|
29619
|
+
`## ${recipe.display_name} conventions`,
|
|
29620
|
+
`Renders on the server by default: ${recipe.ssr_default ? "yes" : "no"}.`,
|
|
29621
|
+
recipe.seo_challenges?.length ? `Known traps in this framework:
|
|
29622
|
+
${recipe.seo_challenges.map((c) => `- ${c}`).join("\n")}` : null
|
|
29623
|
+
].filter(Boolean).join("\n");
|
|
29624
|
+
const checks = recipe.checks ?? [];
|
|
29625
|
+
const relevant = checks.filter((c) => c.code && reported.has(c.code));
|
|
29626
|
+
const rest = checks.filter((c) => !relevant.includes(c));
|
|
29627
|
+
let out = header;
|
|
29628
|
+
let included = 0;
|
|
29629
|
+
for (const check of [...relevant, ...rest]) {
|
|
29630
|
+
const block = checkBlock(check);
|
|
29631
|
+
if (out.length + block.length + 2 > budget) break;
|
|
29632
|
+
out += `
|
|
29633
|
+
|
|
29634
|
+
${block}`;
|
|
29635
|
+
included++;
|
|
29636
|
+
}
|
|
29637
|
+
if (included < checks.length) {
|
|
29638
|
+
out += `
|
|
29639
|
+
|
|
29640
|
+
_(${checks.length - included} more ${recipe.display_name} checks omitted.)_`;
|
|
29641
|
+
}
|
|
29642
|
+
return out;
|
|
29643
|
+
}
|
|
29644
|
+
|
|
29484
29645
|
// src/git/commit-helper.ts
|
|
29485
29646
|
import { execSync, exec as exec2 } from "child_process";
|
|
29486
29647
|
import { promisify as promisify2 } from "util";
|
|
@@ -32019,19 +32180,16 @@ __export(frameworks_exports, {
|
|
|
32019
32180
|
loadRecipe: () => loadRecipe
|
|
32020
32181
|
});
|
|
32021
32182
|
var SUPPORTED_FRAMEWORKS = [
|
|
32022
|
-
"react",
|
|
32023
|
-
"nextjs",
|
|
32024
|
-
"vue",
|
|
32025
|
-
"nuxt",
|
|
32026
32183
|
"angular",
|
|
32027
|
-
"svelte",
|
|
32028
|
-
"sveltekit",
|
|
32029
32184
|
"astro",
|
|
32030
|
-
"remix",
|
|
32031
|
-
"gatsby",
|
|
32032
|
-
"rails",
|
|
32033
|
-
"laravel",
|
|
32034
32185
|
"django",
|
|
32186
|
+
"laravel",
|
|
32187
|
+
"nextjs",
|
|
32188
|
+
"nuxt",
|
|
32189
|
+
"rails",
|
|
32190
|
+
"react",
|
|
32191
|
+
"sveltekit",
|
|
32192
|
+
"vue",
|
|
32035
32193
|
"wordpress"
|
|
32036
32194
|
];
|
|
32037
32195
|
export {
|
|
@@ -32080,7 +32238,9 @@ export {
|
|
|
32080
32238
|
analyzeUrlSafety,
|
|
32081
32239
|
analyzers_exports as analyzers,
|
|
32082
32240
|
applyFixes,
|
|
32241
|
+
assessReplacement,
|
|
32083
32242
|
buildDeterministicFixes,
|
|
32243
|
+
buildFrameworkGuidance,
|
|
32084
32244
|
buildGSCApiRequest,
|
|
32085
32245
|
buildGSCRequest,
|
|
32086
32246
|
calculateAIVisibilityScore,
|
|
@@ -32121,6 +32281,7 @@ export {
|
|
|
32121
32281
|
createPullRequest,
|
|
32122
32282
|
createSEOCommit,
|
|
32123
32283
|
createSEOCommits,
|
|
32284
|
+
describeConcerns,
|
|
32124
32285
|
detectDuplicates,
|
|
32125
32286
|
detectFramework4 as detectFramework,
|
|
32126
32287
|
detectGitHubPages,
|