seo 0.12.1 → 0.13.1
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/PRIVACY.md +1 -1
- package/README.md +1 -1
- package/dist/cli.js +85 -85
- package/dist/cli.js.map +1 -1
- package/dist/{dist-GOZ_hkEB.js → dist-3A3Vzp7r.js} +1 -1
- package/dist/dist-rmavn5h6.js +420 -0
- package/dist/dist-rmavn5h6.js.map +1 -0
- package/dist/{esm-Cyusbw2J.js → esm-BIXGSxFJ.js} +140 -176
- package/dist/esm-BIXGSxFJ.js.map +1 -0
- package/dist/index.d.ts +916 -875
- package/dist/index.js +458 -212
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +11 -11
- package/dist/mcp.js +724 -395
- package/dist/mcp.js.map +1 -1
- package/dist/provider-sdk.d.ts +26 -27
- package/package.json +17 -17
- package/skills/seo/SKILL.md +4 -3
- package/dist/dist-U5Io-lSG.js +0 -393
- package/dist/dist-U5Io-lSG.js.map +0 -1
- package/dist/esm-Cyusbw2J.js.map +0 -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 { i as __toESM, n as version, r as __commonJSMin, t as load } from "./esm-
|
|
2
|
+
import { i as __toESM, n as version, r as __commonJSMin, t as load } from "./esm-BIXGSxFJ.js";
|
|
3
3
|
import { createHash, randomUUID, sign } from "node:crypto";
|
|
4
4
|
import { ZodOptional, z } from "zod";
|
|
5
5
|
import { arch, homedir, platform, tmpdir, totalmem } from "node:os";
|
|
@@ -32,7 +32,7 @@ import { ZodFirstPartyTypeKind } from "zod/v3";
|
|
|
32
32
|
import * as z4mini from "zod/v4-mini";
|
|
33
33
|
import * as z$1 from "zod/v4";
|
|
34
34
|
import process$1 from "node:process";
|
|
35
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
35
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
36
36
|
function isZ4Schema(s) {
|
|
37
37
|
return !!s._zod;
|
|
38
38
|
}
|
|
@@ -155,7 +155,7 @@ function getLiteralValue(schema) {
|
|
|
155
155
|
if (directValue !== void 0) return directValue;
|
|
156
156
|
}
|
|
157
157
|
//#endregion
|
|
158
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
158
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
159
159
|
const LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
160
160
|
const SUPPORTED_PROTOCOL_VERSIONS = [
|
|
161
161
|
LATEST_PROTOCOL_VERSION,
|
|
@@ -2101,7 +2101,7 @@ var UrlElicitationRequiredError = class extends McpError {
|
|
|
2101
2101
|
}
|
|
2102
2102
|
};
|
|
2103
2103
|
//#endregion
|
|
2104
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
2104
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
2105
2105
|
/**
|
|
2106
2106
|
* Experimental task interfaces for MCP SDK.
|
|
2107
2107
|
* WARNING: These APIs are experimental and may change without notice.
|
|
@@ -2118,7 +2118,7 @@ function isTerminal(status) {
|
|
|
2118
2118
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
2119
2119
|
}
|
|
2120
2120
|
//#endregion
|
|
2121
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2121
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
2122
2122
|
const ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
|
|
2123
2123
|
const defaultOptions = {
|
|
2124
2124
|
name: void 0,
|
|
@@ -2152,7 +2152,7 @@ const getDefaultOptions = (options) => typeof options === "string" ? {
|
|
|
2152
2152
|
...options
|
|
2153
2153
|
};
|
|
2154
2154
|
//#endregion
|
|
2155
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2155
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/Refs.js
|
|
2156
2156
|
const getRefs = (options) => {
|
|
2157
2157
|
const _options = getDefaultOptions(options);
|
|
2158
2158
|
const currentPath = _options.name !== void 0 ? [
|
|
@@ -2177,7 +2177,7 @@ const getRefs = (options) => {
|
|
|
2177
2177
|
};
|
|
2178
2178
|
};
|
|
2179
2179
|
//#endregion
|
|
2180
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2180
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/errorMessages.js
|
|
2181
2181
|
function addErrorMessage(res, key, errorMessage, refs) {
|
|
2182
2182
|
if (!refs?.errorMessages) return;
|
|
2183
2183
|
if (errorMessage) res.errorMessage = {
|
|
@@ -2190,14 +2190,14 @@ function setResponseValueAndErrors(res, key, value, errorMessage, refs) {
|
|
|
2190
2190
|
addErrorMessage(res, key, errorMessage, refs);
|
|
2191
2191
|
}
|
|
2192
2192
|
//#endregion
|
|
2193
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2193
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js
|
|
2194
2194
|
const getRelativePath = (pathA, pathB) => {
|
|
2195
2195
|
let i = 0;
|
|
2196
2196
|
for (; i < pathA.length && i < pathB.length; i++) if (pathA[i] !== pathB[i]) break;
|
|
2197
2197
|
return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
|
|
2198
2198
|
};
|
|
2199
2199
|
//#endregion
|
|
2200
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2200
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/any.js
|
|
2201
2201
|
function parseAnyDef(refs) {
|
|
2202
2202
|
if (refs.target !== "openAi") return {};
|
|
2203
2203
|
const anyDefinitionPath = [
|
|
@@ -2209,7 +2209,7 @@ function parseAnyDef(refs) {
|
|
|
2209
2209
|
return { $ref: refs.$refStrategy === "relative" ? getRelativePath(anyDefinitionPath, refs.currentPath) : anyDefinitionPath.join("/") };
|
|
2210
2210
|
}
|
|
2211
2211
|
//#endregion
|
|
2212
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2212
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/array.js
|
|
2213
2213
|
function parseArrayDef(def, refs) {
|
|
2214
2214
|
const res = { type: "array" };
|
|
2215
2215
|
if (def.type?._def && def.type?._def?.typeName !== ZodFirstPartyTypeKind.ZodAny) res.items = parseDef(def.type._def, {
|
|
@@ -2225,7 +2225,7 @@ function parseArrayDef(def, refs) {
|
|
|
2225
2225
|
return res;
|
|
2226
2226
|
}
|
|
2227
2227
|
//#endregion
|
|
2228
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2228
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js
|
|
2229
2229
|
function parseBigintDef(def, refs) {
|
|
2230
2230
|
const res = {
|
|
2231
2231
|
type: "integer",
|
|
@@ -2234,44 +2234,44 @@ function parseBigintDef(def, refs) {
|
|
|
2234
2234
|
if (!def.checks) return res;
|
|
2235
2235
|
for (const check of def.checks) switch (check.kind) {
|
|
2236
2236
|
case "min":
|
|
2237
|
-
if (refs.target === "jsonSchema7")
|
|
2238
|
-
|
|
2239
|
-
|
|
2237
|
+
if (refs.target === "jsonSchema7") {
|
|
2238
|
+
if (check.inclusive) setResponseValueAndErrors(res, "minimum", check.value, check.message, refs);
|
|
2239
|
+
else setResponseValueAndErrors(res, "exclusiveMinimum", check.value, check.message, refs);
|
|
2240
|
+
} else {
|
|
2240
2241
|
if (!check.inclusive) res.exclusiveMinimum = true;
|
|
2241
2242
|
setResponseValueAndErrors(res, "minimum", check.value, check.message, refs);
|
|
2242
2243
|
}
|
|
2243
2244
|
break;
|
|
2244
2245
|
case "max":
|
|
2245
|
-
if (refs.target === "jsonSchema7")
|
|
2246
|
-
|
|
2247
|
-
|
|
2246
|
+
if (refs.target === "jsonSchema7") {
|
|
2247
|
+
if (check.inclusive) setResponseValueAndErrors(res, "maximum", check.value, check.message, refs);
|
|
2248
|
+
else setResponseValueAndErrors(res, "exclusiveMaximum", check.value, check.message, refs);
|
|
2249
|
+
} else {
|
|
2248
2250
|
if (!check.inclusive) res.exclusiveMaximum = true;
|
|
2249
2251
|
setResponseValueAndErrors(res, "maximum", check.value, check.message, refs);
|
|
2250
2252
|
}
|
|
2251
2253
|
break;
|
|
2252
|
-
case "multipleOf":
|
|
2253
|
-
setResponseValueAndErrors(res, "multipleOf", check.value, check.message, refs);
|
|
2254
|
-
break;
|
|
2254
|
+
case "multipleOf": setResponseValueAndErrors(res, "multipleOf", check.value, check.message, refs);
|
|
2255
2255
|
}
|
|
2256
2256
|
return res;
|
|
2257
2257
|
}
|
|
2258
2258
|
//#endregion
|
|
2259
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2259
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js
|
|
2260
2260
|
function parseBooleanDef() {
|
|
2261
2261
|
return { type: "boolean" };
|
|
2262
2262
|
}
|
|
2263
2263
|
//#endregion
|
|
2264
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2264
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js
|
|
2265
2265
|
function parseBrandedDef(_def, refs) {
|
|
2266
2266
|
return parseDef(_def.type._def, refs);
|
|
2267
2267
|
}
|
|
2268
2268
|
//#endregion
|
|
2269
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2269
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js
|
|
2270
2270
|
const parseCatchDef = (def, refs) => {
|
|
2271
2271
|
return parseDef(def.innerType._def, refs);
|
|
2272
2272
|
};
|
|
2273
2273
|
//#endregion
|
|
2274
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2274
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/date.js
|
|
2275
2275
|
function parseDateDef(def, refs, overrideDateStrategy) {
|
|
2276
2276
|
const strategy = overrideDateStrategy ?? refs.dateStrategy;
|
|
2277
2277
|
if (Array.isArray(strategy)) return { anyOf: strategy.map((item, i) => parseDateDef(def, refs, item)) };
|
|
@@ -2298,14 +2298,12 @@ const integerDateParser = (def, refs) => {
|
|
|
2298
2298
|
case "min":
|
|
2299
2299
|
setResponseValueAndErrors(res, "minimum", check.value, check.message, refs);
|
|
2300
2300
|
break;
|
|
2301
|
-
case "max":
|
|
2302
|
-
setResponseValueAndErrors(res, "maximum", check.value, check.message, refs);
|
|
2303
|
-
break;
|
|
2301
|
+
case "max": setResponseValueAndErrors(res, "maximum", check.value, check.message, refs);
|
|
2304
2302
|
}
|
|
2305
2303
|
return res;
|
|
2306
2304
|
};
|
|
2307
2305
|
//#endregion
|
|
2308
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2306
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/default.js
|
|
2309
2307
|
function parseDefaultDef(_def, refs) {
|
|
2310
2308
|
return {
|
|
2311
2309
|
...parseDef(_def.innerType._def, refs),
|
|
@@ -2313,12 +2311,12 @@ function parseDefaultDef(_def, refs) {
|
|
|
2313
2311
|
};
|
|
2314
2312
|
}
|
|
2315
2313
|
//#endregion
|
|
2316
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2314
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js
|
|
2317
2315
|
function parseEffectsDef(_def, refs) {
|
|
2318
2316
|
return refs.effectStrategy === "input" ? parseDef(_def.schema._def, refs) : parseAnyDef(refs);
|
|
2319
2317
|
}
|
|
2320
2318
|
//#endregion
|
|
2321
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2319
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js
|
|
2322
2320
|
function parseEnumDef(def) {
|
|
2323
2321
|
return {
|
|
2324
2322
|
type: "string",
|
|
@@ -2326,7 +2324,7 @@ function parseEnumDef(def) {
|
|
|
2326
2324
|
};
|
|
2327
2325
|
}
|
|
2328
2326
|
//#endregion
|
|
2329
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2327
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js
|
|
2330
2328
|
const isJsonSchema7AllOfType = (type) => {
|
|
2331
2329
|
if ("type" in type && type.type === "string") return false;
|
|
2332
2330
|
return "allOf" in type;
|
|
@@ -2368,7 +2366,7 @@ function parseIntersectionDef(def, refs) {
|
|
|
2368
2366
|
} : void 0;
|
|
2369
2367
|
}
|
|
2370
2368
|
//#endregion
|
|
2371
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2369
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js
|
|
2372
2370
|
function parseLiteralDef(def, refs) {
|
|
2373
2371
|
const parsedType = typeof def.value;
|
|
2374
2372
|
if (parsedType !== "bigint" && parsedType !== "number" && parsedType !== "boolean" && parsedType !== "string") return { type: Array.isArray(def.value) ? "array" : "object" };
|
|
@@ -2382,7 +2380,7 @@ function parseLiteralDef(def, refs) {
|
|
|
2382
2380
|
};
|
|
2383
2381
|
}
|
|
2384
2382
|
//#endregion
|
|
2385
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2383
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/string.js
|
|
2386
2384
|
let emojiRegex = void 0;
|
|
2387
2385
|
/**
|
|
2388
2386
|
* Generated from the regular expressions found here as of 2024-05-22:
|
|
@@ -2452,9 +2450,7 @@ function parseStringDef(def, refs) {
|
|
|
2452
2450
|
case "format:idn-email":
|
|
2453
2451
|
addFormat(res, "idn-email", check.message, refs);
|
|
2454
2452
|
break;
|
|
2455
|
-
case "pattern:zod":
|
|
2456
|
-
addPattern(res, zodPatterns.email, check.message, refs);
|
|
2457
|
-
break;
|
|
2453
|
+
case "pattern:zod": addPattern(res, zodPatterns.email, check.message, refs);
|
|
2458
2454
|
}
|
|
2459
2455
|
break;
|
|
2460
2456
|
case "url":
|
|
@@ -2525,16 +2521,10 @@ function parseStringDef(def, refs) {
|
|
|
2525
2521
|
case "contentEncoding:base64":
|
|
2526
2522
|
setResponseValueAndErrors(res, "contentEncoding", "base64", check.message, refs);
|
|
2527
2523
|
break;
|
|
2528
|
-
case "pattern:zod":
|
|
2529
|
-
addPattern(res, zodPatterns.base64, check.message, refs);
|
|
2530
|
-
break;
|
|
2524
|
+
case "pattern:zod": addPattern(res, zodPatterns.base64, check.message, refs);
|
|
2531
2525
|
}
|
|
2532
2526
|
break;
|
|
2533
2527
|
case "nanoid": addPattern(res, zodPatterns.nanoid, check.message, refs);
|
|
2534
|
-
case "toLowerCase":
|
|
2535
|
-
case "toUpperCase":
|
|
2536
|
-
case "trim": break;
|
|
2537
|
-
default:
|
|
2538
2528
|
}
|
|
2539
2529
|
return res;
|
|
2540
2530
|
}
|
|
@@ -2653,7 +2643,7 @@ function stringifyRegExpWithFlags(regex, refs) {
|
|
|
2653
2643
|
return pattern;
|
|
2654
2644
|
}
|
|
2655
2645
|
//#endregion
|
|
2656
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2646
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/record.js
|
|
2657
2647
|
function parseRecordDef(def, refs) {
|
|
2658
2648
|
if (refs.target === "openAi") console.warn("Warning: OpenAI may not support records in schemas! Try an array of key-value pairs instead.");
|
|
2659
2649
|
if (refs.target === "openApi3" && def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodEnum) return {
|
|
@@ -2700,7 +2690,7 @@ function parseRecordDef(def, refs) {
|
|
|
2700
2690
|
return schema;
|
|
2701
2691
|
}
|
|
2702
2692
|
//#endregion
|
|
2703
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2693
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/map.js
|
|
2704
2694
|
function parseMapDef(def, refs) {
|
|
2705
2695
|
if (refs.mapStrategy === "record") return parseRecordDef(def, refs);
|
|
2706
2696
|
return {
|
|
@@ -2731,7 +2721,7 @@ function parseMapDef(def, refs) {
|
|
|
2731
2721
|
};
|
|
2732
2722
|
}
|
|
2733
2723
|
//#endregion
|
|
2734
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2724
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js
|
|
2735
2725
|
function parseNativeEnumDef(def) {
|
|
2736
2726
|
const object = def.values;
|
|
2737
2727
|
const actualValues = Object.keys(def.values).filter((key) => {
|
|
@@ -2744,7 +2734,7 @@ function parseNativeEnumDef(def) {
|
|
|
2744
2734
|
};
|
|
2745
2735
|
}
|
|
2746
2736
|
//#endregion
|
|
2747
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2737
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/never.js
|
|
2748
2738
|
function parseNeverDef(refs) {
|
|
2749
2739
|
return refs.target === "openAi" ? void 0 : { not: parseAnyDef({
|
|
2750
2740
|
...refs,
|
|
@@ -2752,7 +2742,7 @@ function parseNeverDef(refs) {
|
|
|
2752
2742
|
}) };
|
|
2753
2743
|
}
|
|
2754
2744
|
//#endregion
|
|
2755
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2745
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/null.js
|
|
2756
2746
|
function parseNullDef(refs) {
|
|
2757
2747
|
return refs.target === "openApi3" ? {
|
|
2758
2748
|
enum: ["null"],
|
|
@@ -2760,7 +2750,7 @@ function parseNullDef(refs) {
|
|
|
2760
2750
|
} : { type: "null" };
|
|
2761
2751
|
}
|
|
2762
2752
|
//#endregion
|
|
2763
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2753
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/union.js
|
|
2764
2754
|
const primitiveMappings = {
|
|
2765
2755
|
ZodString: "string",
|
|
2766
2756
|
ZodNumber: "number",
|
|
@@ -2816,7 +2806,7 @@ const asAnyOf = (def, refs) => {
|
|
|
2816
2806
|
return anyOf.length ? { anyOf } : void 0;
|
|
2817
2807
|
};
|
|
2818
2808
|
//#endregion
|
|
2819
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2809
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js
|
|
2820
2810
|
function parseNullableDef(def, refs) {
|
|
2821
2811
|
if ([
|
|
2822
2812
|
"ZodString",
|
|
@@ -2856,7 +2846,7 @@ function parseNullableDef(def, refs) {
|
|
|
2856
2846
|
return base && { anyOf: [base, { type: "null" }] };
|
|
2857
2847
|
}
|
|
2858
2848
|
//#endregion
|
|
2859
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2849
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/number.js
|
|
2860
2850
|
function parseNumberDef(def, refs) {
|
|
2861
2851
|
const res = { type: "number" };
|
|
2862
2852
|
if (!def.checks) return res;
|
|
@@ -2866,29 +2856,29 @@ function parseNumberDef(def, refs) {
|
|
|
2866
2856
|
addErrorMessage(res, "type", check.message, refs);
|
|
2867
2857
|
break;
|
|
2868
2858
|
case "min":
|
|
2869
|
-
if (refs.target === "jsonSchema7")
|
|
2870
|
-
|
|
2871
|
-
|
|
2859
|
+
if (refs.target === "jsonSchema7") {
|
|
2860
|
+
if (check.inclusive) setResponseValueAndErrors(res, "minimum", check.value, check.message, refs);
|
|
2861
|
+
else setResponseValueAndErrors(res, "exclusiveMinimum", check.value, check.message, refs);
|
|
2862
|
+
} else {
|
|
2872
2863
|
if (!check.inclusive) res.exclusiveMinimum = true;
|
|
2873
2864
|
setResponseValueAndErrors(res, "minimum", check.value, check.message, refs);
|
|
2874
2865
|
}
|
|
2875
2866
|
break;
|
|
2876
2867
|
case "max":
|
|
2877
|
-
if (refs.target === "jsonSchema7")
|
|
2878
|
-
|
|
2879
|
-
|
|
2868
|
+
if (refs.target === "jsonSchema7") {
|
|
2869
|
+
if (check.inclusive) setResponseValueAndErrors(res, "maximum", check.value, check.message, refs);
|
|
2870
|
+
else setResponseValueAndErrors(res, "exclusiveMaximum", check.value, check.message, refs);
|
|
2871
|
+
} else {
|
|
2880
2872
|
if (!check.inclusive) res.exclusiveMaximum = true;
|
|
2881
2873
|
setResponseValueAndErrors(res, "maximum", check.value, check.message, refs);
|
|
2882
2874
|
}
|
|
2883
2875
|
break;
|
|
2884
|
-
case "multipleOf":
|
|
2885
|
-
setResponseValueAndErrors(res, "multipleOf", check.value, check.message, refs);
|
|
2886
|
-
break;
|
|
2876
|
+
case "multipleOf": setResponseValueAndErrors(res, "multipleOf", check.value, check.message, refs);
|
|
2887
2877
|
}
|
|
2888
2878
|
return res;
|
|
2889
2879
|
}
|
|
2890
2880
|
//#endregion
|
|
2891
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2881
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/object.js
|
|
2892
2882
|
function parseObjectDef(def, refs) {
|
|
2893
2883
|
const forceOptionalIntoNullable = refs.target === "openAi";
|
|
2894
2884
|
const result = {
|
|
@@ -2947,7 +2937,7 @@ function safeIsOptional(schema) {
|
|
|
2947
2937
|
}
|
|
2948
2938
|
}
|
|
2949
2939
|
//#endregion
|
|
2950
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2940
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js
|
|
2951
2941
|
const parseOptionalDef = (def, refs) => {
|
|
2952
2942
|
if (refs.currentPath.toString() === refs.propertyPath?.toString()) return parseDef(def.innerType._def, refs);
|
|
2953
2943
|
const innerSchema = parseDef(def.innerType._def, {
|
|
@@ -2961,7 +2951,7 @@ const parseOptionalDef = (def, refs) => {
|
|
|
2961
2951
|
return innerSchema ? { anyOf: [{ not: parseAnyDef(refs) }, innerSchema] } : parseAnyDef(refs);
|
|
2962
2952
|
};
|
|
2963
2953
|
//#endregion
|
|
2964
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2954
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js
|
|
2965
2955
|
const parsePipelineDef = (def, refs) => {
|
|
2966
2956
|
if (refs.pipeStrategy === "input") return parseDef(def.in._def, refs);
|
|
2967
2957
|
else if (refs.pipeStrategy === "output") return parseDef(def.out._def, refs);
|
|
@@ -2983,12 +2973,12 @@ const parsePipelineDef = (def, refs) => {
|
|
|
2983
2973
|
})].filter((x) => x !== void 0) };
|
|
2984
2974
|
};
|
|
2985
2975
|
//#endregion
|
|
2986
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2976
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js
|
|
2987
2977
|
function parsePromiseDef(def, refs) {
|
|
2988
2978
|
return parseDef(def.type._def, refs);
|
|
2989
2979
|
}
|
|
2990
2980
|
//#endregion
|
|
2991
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2981
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/set.js
|
|
2992
2982
|
function parseSetDef(def, refs) {
|
|
2993
2983
|
const schema = {
|
|
2994
2984
|
type: "array",
|
|
@@ -3003,7 +2993,7 @@ function parseSetDef(def, refs) {
|
|
|
3003
2993
|
return schema;
|
|
3004
2994
|
}
|
|
3005
2995
|
//#endregion
|
|
3006
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
2996
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js
|
|
3007
2997
|
function parseTupleDef(def, refs) {
|
|
3008
2998
|
if (def.rest) return {
|
|
3009
2999
|
type: "array",
|
|
@@ -3036,22 +3026,22 @@ function parseTupleDef(def, refs) {
|
|
|
3036
3026
|
};
|
|
3037
3027
|
}
|
|
3038
3028
|
//#endregion
|
|
3039
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
3029
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js
|
|
3040
3030
|
function parseUndefinedDef(refs) {
|
|
3041
3031
|
return { not: parseAnyDef(refs) };
|
|
3042
3032
|
}
|
|
3043
3033
|
//#endregion
|
|
3044
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
3034
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js
|
|
3045
3035
|
function parseUnknownDef(refs) {
|
|
3046
3036
|
return parseAnyDef(refs);
|
|
3047
3037
|
}
|
|
3048
3038
|
//#endregion
|
|
3049
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
3039
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js
|
|
3050
3040
|
const parseReadonlyDef = (def, refs) => {
|
|
3051
3041
|
return parseDef(def.innerType._def, refs);
|
|
3052
3042
|
};
|
|
3053
3043
|
//#endregion
|
|
3054
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
3044
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/selectParser.js
|
|
3055
3045
|
const selectParser = (def, typeName, refs) => {
|
|
3056
3046
|
switch (typeName) {
|
|
3057
3047
|
case ZodFirstPartyTypeKind.ZodString: return parseStringDef(def, refs);
|
|
@@ -3094,7 +3084,7 @@ const selectParser = (def, typeName, refs) => {
|
|
|
3094
3084
|
}
|
|
3095
3085
|
};
|
|
3096
3086
|
//#endregion
|
|
3097
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
3087
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/parseDef.js
|
|
3098
3088
|
function parseDef(def, refs, forceResolution = false) {
|
|
3099
3089
|
const seenItem = refs.seen.get(def);
|
|
3100
3090
|
if (refs.override) {
|
|
@@ -3143,7 +3133,7 @@ const addMeta = (def, refs, jsonSchema) => {
|
|
|
3143
3133
|
return jsonSchema;
|
|
3144
3134
|
};
|
|
3145
3135
|
//#endregion
|
|
3146
|
-
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.
|
|
3136
|
+
//#region node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@4.6.7/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js
|
|
3147
3137
|
const zodToJsonSchema = (schema, options) => {
|
|
3148
3138
|
const refs = getRefs(options);
|
|
3149
3139
|
let definitions = typeof options === "object" && options.definitions ? Object.entries(options.definitions).reduce((acc, [name, schema]) => ({
|
|
@@ -3206,7 +3196,7 @@ const zodToJsonSchema = (schema, options) => {
|
|
|
3206
3196
|
return combined;
|
|
3207
3197
|
};
|
|
3208
3198
|
//#endregion
|
|
3209
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
3199
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
3210
3200
|
function mapMiniTarget(t) {
|
|
3211
3201
|
if (!t) return "draft-7";
|
|
3212
3202
|
if (t === "jsonSchema7" || t === "draft-7") return "draft-7";
|
|
@@ -6120,10 +6110,12 @@ var require_resolve = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
6120
6110
|
let schOrRef = this.refs[ref];
|
|
6121
6111
|
if (typeof schOrRef == "string") schOrRef = this.refs[schOrRef];
|
|
6122
6112
|
if (typeof schOrRef == "object") checkAmbiguosRef(sch, schOrRef.schema, ref);
|
|
6123
|
-
else if (ref !== normalizeId(fullPath))
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6113
|
+
else if (ref !== normalizeId(fullPath)) {
|
|
6114
|
+
if (ref[0] === "#") {
|
|
6115
|
+
checkAmbiguosRef(sch, localRefs[ref], ref);
|
|
6116
|
+
localRefs[ref] = sch;
|
|
6117
|
+
} else this.refs[ref] = fullPath;
|
|
6118
|
+
}
|
|
6127
6119
|
return ref;
|
|
6128
6120
|
}
|
|
6129
6121
|
function addAnchor(anchor) {
|
|
@@ -6819,7 +6811,7 @@ var require_data = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
6819
6811
|
};
|
|
6820
6812
|
}));
|
|
6821
6813
|
//#endregion
|
|
6822
|
-
//#region node_modules/.pnpm/fast-uri@3.1.
|
|
6814
|
+
//#region node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/utils.js
|
|
6823
6815
|
var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
6824
6816
|
/** @type {(value: string) => boolean} */
|
|
6825
6817
|
const isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
@@ -7049,15 +7041,16 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7049
7041
|
let nextSlash = -1;
|
|
7050
7042
|
let len = 0;
|
|
7051
7043
|
while (len = input.length) {
|
|
7052
|
-
if (len === 1)
|
|
7053
|
-
|
|
7054
|
-
|
|
7055
|
-
|
|
7056
|
-
|
|
7057
|
-
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7044
|
+
if (len === 1) {
|
|
7045
|
+
if (input === ".") break;
|
|
7046
|
+
else if (input === "/") {
|
|
7047
|
+
output.push("/");
|
|
7048
|
+
break;
|
|
7049
|
+
} else {
|
|
7050
|
+
output.push(input);
|
|
7051
|
+
break;
|
|
7052
|
+
}
|
|
7053
|
+
} else if (len === 2) {
|
|
7061
7054
|
if (input[0] === ".") {
|
|
7062
7055
|
if (input[1] === ".") break;
|
|
7063
7056
|
else if (input[1] === "/") {
|
|
@@ -7112,6 +7105,38 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7112
7105
|
return output.join("");
|
|
7113
7106
|
}
|
|
7114
7107
|
/**
|
|
7108
|
+
* Removes dot segments from the path of a relative reference (a path that does
|
|
7109
|
+
* not start with "/") without changing what it resolves to against any base.
|
|
7110
|
+
* Unlike `removeDotSegments`, leading ".." segments that cannot be collapsed
|
|
7111
|
+
* are kept, the result never becomes root-relative, and a result that would be
|
|
7112
|
+
* empty or start with an empty segment is prefixed with "." (an empty path
|
|
7113
|
+
* means "same document" and a leading "//" would introduce an authority).
|
|
7114
|
+
*
|
|
7115
|
+
* @param {string} path
|
|
7116
|
+
* @returns {string}
|
|
7117
|
+
*/
|
|
7118
|
+
function removeDotSegmentsRelative(path) {
|
|
7119
|
+
if (path === "" || path[0] === "/") return removeDotSegments(path);
|
|
7120
|
+
const segments = path.split("/");
|
|
7121
|
+
const last = segments.length - 1;
|
|
7122
|
+
/** @type {string[]} */
|
|
7123
|
+
const output = [];
|
|
7124
|
+
let trailingDirectory = false;
|
|
7125
|
+
for (let i = 0; i <= last; i++) {
|
|
7126
|
+
const segment = segments[i];
|
|
7127
|
+
if (segment === "." || segment === "..") {
|
|
7128
|
+
if (segment === "..") {
|
|
7129
|
+
if (output.length !== 0 && output[output.length - 1] !== "..") output.pop();
|
|
7130
|
+
else output.push("..");
|
|
7131
|
+
}
|
|
7132
|
+
trailingDirectory = i === last;
|
|
7133
|
+
} else output.push(segment);
|
|
7134
|
+
}
|
|
7135
|
+
if (trailingDirectory && output[output.length - 1] !== "..") output.push("");
|
|
7136
|
+
if (output.length === 0 || output[0] === "" || output[0].includes(":")) output.unshift(".");
|
|
7137
|
+
return output.join("/");
|
|
7138
|
+
}
|
|
7139
|
+
/**
|
|
7115
7140
|
* Re-escape RFC 3986 gen-delims that must not appear literally in the host.
|
|
7116
7141
|
* After the URI regex parses, these characters cannot be literal in the host
|
|
7117
7142
|
* field, so any that appear after decoding came from percent-encoding and
|
|
@@ -7415,6 +7440,7 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7415
7440
|
encodeFragment,
|
|
7416
7441
|
escapePreservingEscapes,
|
|
7417
7442
|
removeDotSegments,
|
|
7443
|
+
removeDotSegmentsRelative,
|
|
7418
7444
|
isIPv4,
|
|
7419
7445
|
isUUID,
|
|
7420
7446
|
normalizeIPv6,
|
|
@@ -7422,7 +7448,7 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7422
7448
|
};
|
|
7423
7449
|
}));
|
|
7424
7450
|
//#endregion
|
|
7425
|
-
//#region node_modules/.pnpm/fast-uri@3.1.
|
|
7451
|
+
//#region node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/schemes.js
|
|
7426
7452
|
var require_schemes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
7427
7453
|
const { isUUID } = require_utils();
|
|
7428
7454
|
const URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
@@ -7606,20 +7632,26 @@ var require_schemes = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7606
7632
|
};
|
|
7607
7633
|
}));
|
|
7608
7634
|
//#endregion
|
|
7609
|
-
//#region node_modules/.pnpm/fast-uri@3.1.
|
|
7635
|
+
//#region node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/index.js
|
|
7610
7636
|
var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
7611
|
-
const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
7637
|
+
const { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
7612
7638
|
const { SCHEMES, getSchemeHandler } = require_schemes();
|
|
7613
7639
|
const VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
7614
7640
|
const MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
7641
|
+
const MALFORMED_HOST_ERROR = "URI host is malformed.";
|
|
7642
|
+
const FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u;
|
|
7615
7643
|
/**
|
|
7644
|
+
* RFC 3986 section 3.1 does not allow percent-encoding in a scheme, so the
|
|
7645
|
+
* scheme is validated as-is and never decoded. Decoding would let inert input
|
|
7646
|
+
* such as `%6Aavascript:` become a live `javascript:` scheme.
|
|
7647
|
+
*
|
|
7616
7648
|
* @param {string} scheme
|
|
7617
7649
|
* @returns {string}
|
|
7618
7650
|
*/
|
|
7619
|
-
function
|
|
7620
|
-
const
|
|
7621
|
-
if (!VALID_SCHEME.test(
|
|
7622
|
-
return
|
|
7651
|
+
function validateScheme(scheme) {
|
|
7652
|
+
const stringScheme = String(scheme);
|
|
7653
|
+
if (!VALID_SCHEME.test(stringScheme)) throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
7654
|
+
return stringScheme;
|
|
7623
7655
|
}
|
|
7624
7656
|
/**
|
|
7625
7657
|
* @template {import('./types/index').URIComponent|string} T
|
|
@@ -7647,6 +7679,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7647
7679
|
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
7648
7680
|
const resolvedHost = resolved.host;
|
|
7649
7681
|
const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
7682
|
+
if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) throw new Error(MALFORMED_HOST_ERROR);
|
|
7650
7683
|
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
7651
7684
|
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
|
|
7652
7685
|
if (resolved.error && !encodedASCIIHost) throw new Error(resolved.error);
|
|
@@ -7690,10 +7723,11 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7690
7723
|
} else {
|
|
7691
7724
|
if (relative.path[0] === "/") target.path = removeDotSegments(relative.path);
|
|
7692
7725
|
else {
|
|
7693
|
-
|
|
7726
|
+
const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
|
|
7727
|
+
if (baseHasAuthority && !base.path) target.path = "/" + relative.path;
|
|
7694
7728
|
else if (!base.path) target.path = relative.path;
|
|
7695
7729
|
else target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
|
|
7696
|
-
target.path = removeDotSegments(target.path);
|
|
7730
|
+
target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
|
|
7697
7731
|
}
|
|
7698
7732
|
target.query = relative.query;
|
|
7699
7733
|
}
|
|
@@ -7741,15 +7775,18 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7741
7775
|
};
|
|
7742
7776
|
const options = Object.assign({}, opts);
|
|
7743
7777
|
const uriTokens = [];
|
|
7744
|
-
if (component.scheme) component.scheme =
|
|
7778
|
+
if (component.scheme) component.scheme = validateScheme(component.scheme);
|
|
7745
7779
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
7746
7780
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
7747
7781
|
const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
|
|
7748
|
-
const
|
|
7749
|
-
|
|
7750
|
-
|
|
7782
|
+
const schemelessReference = (component.scheme === void 0 || options.reference === "suffix") && !hasAuthority;
|
|
7783
|
+
const pathNoScheme = !options.skipEscape && schemelessReference;
|
|
7784
|
+
if (component.path !== void 0) {
|
|
7785
|
+
if (!options.skipEscape) component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
7786
|
+
else component.path = normalizePercentEncoding(component.path);
|
|
7787
|
+
}
|
|
7751
7788
|
if (options.reference !== "suffix" && component.scheme) {
|
|
7752
|
-
component.scheme =
|
|
7789
|
+
component.scheme = validateScheme(component.scheme);
|
|
7753
7790
|
uriTokens.push(component.scheme, ":");
|
|
7754
7791
|
}
|
|
7755
7792
|
const authority = recomposeAuthority(component);
|
|
@@ -7760,8 +7797,8 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7760
7797
|
}
|
|
7761
7798
|
if (component.path !== void 0) {
|
|
7762
7799
|
let s = component.path;
|
|
7763
|
-
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) s = removeDotSegments(s);
|
|
7764
|
-
if (
|
|
7800
|
+
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) s = schemelessReference && s[0] !== "/" ? removeDotSegmentsRelative(s) : removeDotSegments(s);
|
|
7801
|
+
if (schemelessReference) s = serializePathEncoding(s, true);
|
|
7765
7802
|
if (authority === void 0 && s[0] === "/" && s[1] === "/") s = "/%2F" + s.slice(2);
|
|
7766
7803
|
uriTokens.push(s);
|
|
7767
7804
|
}
|
|
@@ -7825,15 +7862,50 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7825
7862
|
* @returns {boolean} whether host conversion failed
|
|
7826
7863
|
*/
|
|
7827
7864
|
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
7828
|
-
if (
|
|
7829
|
-
parsed.
|
|
7830
|
-
} catch (e) {
|
|
7831
|
-
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
7865
|
+
if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
|
|
7866
|
+
parsed.error = parsed.error || MALFORMED_HOST_ERROR;
|
|
7832
7867
|
return true;
|
|
7833
7868
|
}
|
|
7869
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
7870
|
+
let url;
|
|
7871
|
+
try {
|
|
7872
|
+
url = new URL("http://" + parsed.host);
|
|
7873
|
+
} catch (e) {
|
|
7874
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
7875
|
+
return true;
|
|
7876
|
+
}
|
|
7877
|
+
if (!isHostOnlyURL(url)) {
|
|
7878
|
+
parsed.error = parsed.error || MALFORMED_HOST_ERROR;
|
|
7879
|
+
return true;
|
|
7880
|
+
}
|
|
7881
|
+
parsed.host = url.hostname;
|
|
7882
|
+
}
|
|
7834
7883
|
return false;
|
|
7835
7884
|
}
|
|
7836
7885
|
/**
|
|
7886
|
+
* Whether a domain host contains an ASCII character that RFC 3986 does not
|
|
7887
|
+
* allow in a reg-name (unreserved, sub-delims, or pct-encoded). Such a host is
|
|
7888
|
+
* rejected instead of being handed to the WHATWG URL parser, which would treat
|
|
7889
|
+
* "@" as a userinfo delimiter (silently dropping the data before it) and strip
|
|
7890
|
+
* TAB, LF, and CR. Non-ASCII characters remain allowed for IDNs.
|
|
7891
|
+
*
|
|
7892
|
+
* @param {import('./types/index').URIComponent} parsed
|
|
7893
|
+
* @param {import('./types/index').Options} options
|
|
7894
|
+
* @param {{ domainHost?: boolean }|undefined} schemeHandler
|
|
7895
|
+
* @param {boolean} isIP
|
|
7896
|
+
* @returns {boolean}
|
|
7897
|
+
*/
|
|
7898
|
+
function hasForbiddenDomainHost(parsed, options, schemeHandler, isIP) {
|
|
7899
|
+
return Boolean(parsed.host && isIP === false && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host));
|
|
7900
|
+
}
|
|
7901
|
+
/**
|
|
7902
|
+
* @param {URL} url
|
|
7903
|
+
* @returns {boolean}
|
|
7904
|
+
*/
|
|
7905
|
+
function isHostOnlyURL(url) {
|
|
7906
|
+
return url.username === "" && url.password === "" && url.port === "" && url.pathname === "/" && url.search === "" && url.hash === "" && url.hostname !== "";
|
|
7907
|
+
}
|
|
7908
|
+
/**
|
|
7837
7909
|
* @param {string} uri
|
|
7838
7910
|
* @param {import('./types/index').Options} [opts]
|
|
7839
7911
|
* @returns {{ parsed: import('./types/index').URIComponent, malformedAuthorityOrPort: boolean, malformedPercentEncoding: boolean, malformedSchemeSpecific: boolean, malformedHost: boolean, malformedScheme: boolean }}
|
|
@@ -7857,8 +7929,10 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7857
7929
|
let malformedIPLiteral = false;
|
|
7858
7930
|
let malformedScheme = false;
|
|
7859
7931
|
let isIP = false;
|
|
7860
|
-
if (options.reference === "suffix")
|
|
7861
|
-
|
|
7932
|
+
if (options.reference === "suffix") {
|
|
7933
|
+
if (options.scheme) uri = options.scheme + ":" + uri;
|
|
7934
|
+
else uri = "//" + uri;
|
|
7935
|
+
}
|
|
7862
7936
|
const authorityMatch = uri.match(AUTHORITY_PREFIX);
|
|
7863
7937
|
if (authorityMatch !== null && authorityMatch[1].indexOf("\\") !== -1) {
|
|
7864
7938
|
parsed.error = "URI authority must not contain a literal backslash.";
|
|
@@ -7888,8 +7962,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7888
7962
|
parsed.query = matches[7];
|
|
7889
7963
|
parsed.fragment = matches[8];
|
|
7890
7964
|
if (parsed.scheme !== void 0) {
|
|
7891
|
-
|
|
7892
|
-
if (VALID_SCHEME.test(decodedScheme)) parsed.scheme = decodedScheme.toLowerCase();
|
|
7965
|
+
if (VALID_SCHEME.test(parsed.scheme)) parsed.scheme = parsed.scheme.toLowerCase();
|
|
7893
7966
|
else {
|
|
7894
7967
|
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
7895
7968
|
malformedScheme = true;
|
|
@@ -7903,18 +7976,20 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7903
7976
|
parsed.error = parsed.error || parseError;
|
|
7904
7977
|
malformedAuthorityOrPort = true;
|
|
7905
7978
|
}
|
|
7906
|
-
if (parsed.host)
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7979
|
+
if (parsed.host) {
|
|
7980
|
+
if (isIPv4(parsed.host) === false) {
|
|
7981
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
7982
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
7983
|
+
const ipv6result = normalizeIPv6(parsed.host);
|
|
7984
|
+
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
7985
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
7986
|
+
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
7987
|
+
if (malformedIPLiteral) {
|
|
7988
|
+
parsed.error = parsed.error || MALFORMED_HOST_ERROR;
|
|
7989
|
+
malformedAuthorityOrPort = true;
|
|
7990
|
+
}
|
|
7991
|
+
} else isIP = true;
|
|
7992
|
+
}
|
|
7918
7993
|
if (parsed.scheme === void 0 && parsed.userinfo === void 0 && parsed.host === void 0 && parsed.port === void 0 && parsed.query === void 0 && !parsed.path) parsed.reference = "same-document";
|
|
7919
7994
|
else if (parsed.scheme === void 0) parsed.reference = "relative";
|
|
7920
7995
|
else if (parsed.fragment === void 0) parsed.reference = "absolute";
|
|
@@ -7925,7 +8000,7 @@ var require_fast_uri = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
7925
8000
|
if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
|
|
7926
8001
|
let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
7927
8002
|
if (!isIP) host = normalizePercentEncoding(host.toLowerCase());
|
|
7928
|
-
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
8003
|
+
parsed.host = isIP || options.scheme !== "null" ? reescapeHostDelimiters(host, isIP) : host;
|
|
7929
8004
|
}
|
|
7930
8005
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
7931
8006
|
if (parsed.path) parsed.path = normalizePathEncoding(parsed.path);
|
|
@@ -8681,17 +8756,21 @@ var require_ref = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
8681
8756
|
var _a;
|
|
8682
8757
|
if (!it.opts.unevaluated) return;
|
|
8683
8758
|
const schEvaluated = (_a = sch === null || sch === void 0 ? void 0 : sch.validate) === null || _a === void 0 ? void 0 : _a.evaluated;
|
|
8684
|
-
if (it.props !== true)
|
|
8685
|
-
if (schEvaluated
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8759
|
+
if (it.props !== true) {
|
|
8760
|
+
if (schEvaluated && !schEvaluated.dynamicProps) {
|
|
8761
|
+
if (schEvaluated.props !== void 0) it.props = util_1.mergeEvaluated.props(gen, schEvaluated.props, it.props);
|
|
8762
|
+
} else {
|
|
8763
|
+
const props = gen.var("props", (0, codegen_1._)`${source}.evaluated.props`);
|
|
8764
|
+
it.props = util_1.mergeEvaluated.props(gen, props, it.props, codegen_1.Name);
|
|
8765
|
+
}
|
|
8689
8766
|
}
|
|
8690
|
-
if (it.items !== true)
|
|
8691
|
-
if (schEvaluated
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8767
|
+
if (it.items !== true) {
|
|
8768
|
+
if (schEvaluated && !schEvaluated.dynamicItems) {
|
|
8769
|
+
if (schEvaluated.items !== void 0) it.items = util_1.mergeEvaluated.items(gen, schEvaluated.items, it.items);
|
|
8770
|
+
} else {
|
|
8771
|
+
const items = gen.var("items", (0, codegen_1._)`${source}.evaluated.items`);
|
|
8772
|
+
it.items = util_1.mergeEvaluated.items(gen, items, it.items, codegen_1.Name);
|
|
8773
|
+
}
|
|
8695
8774
|
}
|
|
8696
8775
|
}
|
|
8697
8776
|
}
|
|
@@ -10669,7 +10748,7 @@ var require_dist = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
10669
10748
|
exports.default = formatsPlugin;
|
|
10670
10749
|
}));
|
|
10671
10750
|
//#endregion
|
|
10672
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
10751
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
10673
10752
|
var import_ajv = /* @__PURE__ */ __toESM(require_ajv(), 1);
|
|
10674
10753
|
var import_dist = /* @__PURE__ */ __toESM(require_dist(), 1);
|
|
10675
10754
|
function createDefaultAjvInstance() {
|
|
@@ -10745,7 +10824,7 @@ var AjvJsonSchemaValidator = class {
|
|
|
10745
10824
|
}
|
|
10746
10825
|
};
|
|
10747
10826
|
//#endregion
|
|
10748
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
10827
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
10749
10828
|
/**
|
|
10750
10829
|
* Experimental server task features for MCP SDK.
|
|
10751
10830
|
* WARNING: These APIs are experimental and may change without notice.
|
|
@@ -10902,9 +10981,7 @@ var ExperimentalServerTasks = class {
|
|
|
10902
10981
|
case "url":
|
|
10903
10982
|
if (!clientCapabilities?.elicitation?.url) throw new Error("Client does not support url elicitation.");
|
|
10904
10983
|
break;
|
|
10905
|
-
case "form":
|
|
10906
|
-
if (!clientCapabilities?.elicitation?.form) throw new Error("Client does not support form elicitation.");
|
|
10907
|
-
break;
|
|
10984
|
+
case "form": if (!clientCapabilities?.elicitation?.form) throw new Error("Client does not support form elicitation.");
|
|
10908
10985
|
}
|
|
10909
10986
|
const normalizedParams = mode === "form" && params.mode === void 0 ? {
|
|
10910
10987
|
...params,
|
|
@@ -10965,7 +11042,7 @@ var ExperimentalServerTasks = class {
|
|
|
10965
11042
|
}
|
|
10966
11043
|
};
|
|
10967
11044
|
//#endregion
|
|
10968
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
11045
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
10969
11046
|
/**
|
|
10970
11047
|
* Experimental task capability assertion helpers.
|
|
10971
11048
|
* WARNING: These APIs are experimental and may change without notice.
|
|
@@ -10986,10 +11063,7 @@ var ExperimentalServerTasks = class {
|
|
|
10986
11063
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
10987
11064
|
if (!requests) throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
10988
11065
|
switch (method) {
|
|
10989
|
-
case "tools/call":
|
|
10990
|
-
if (!requests.tools?.call) throw new Error(`${entityName} does not support task creation for tools/call (required for ${method})`);
|
|
10991
|
-
break;
|
|
10992
|
-
default: break;
|
|
11066
|
+
case "tools/call": if (!requests.tools?.call) throw new Error(`${entityName} does not support task creation for tools/call (required for ${method})`);
|
|
10993
11067
|
}
|
|
10994
11068
|
}
|
|
10995
11069
|
/**
|
|
@@ -11009,14 +11083,11 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
11009
11083
|
case "sampling/createMessage":
|
|
11010
11084
|
if (!requests.sampling?.createMessage) throw new Error(`${entityName} does not support task creation for sampling/createMessage (required for ${method})`);
|
|
11011
11085
|
break;
|
|
11012
|
-
case "elicitation/create":
|
|
11013
|
-
if (!requests.elicitation?.create) throw new Error(`${entityName} does not support task creation for elicitation/create (required for ${method})`);
|
|
11014
|
-
break;
|
|
11015
|
-
default: break;
|
|
11086
|
+
case "elicitation/create": if (!requests.elicitation?.create) throw new Error(`${entityName} does not support task creation for elicitation/create (required for ${method})`);
|
|
11016
11087
|
}
|
|
11017
11088
|
}
|
|
11018
11089
|
//#endregion
|
|
11019
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
11090
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
11020
11091
|
/**
|
|
11021
11092
|
* An MCP server on top of a pluggable transport.
|
|
11022
11093
|
*
|
|
@@ -11133,10 +11204,7 @@ var Server = class extends Protocol {
|
|
|
11133
11204
|
case "elicitation/create":
|
|
11134
11205
|
if (!this._clientCapabilities?.elicitation) throw new Error(`Client does not support elicitation (required for ${method})`);
|
|
11135
11206
|
break;
|
|
11136
|
-
case "roots/list":
|
|
11137
|
-
if (!this._clientCapabilities?.roots) throw new Error(`Client does not support listing roots (required for ${method})`);
|
|
11138
|
-
break;
|
|
11139
|
-
case "ping": break;
|
|
11207
|
+
case "roots/list": if (!this._clientCapabilities?.roots) throw new Error(`Client does not support listing roots (required for ${method})`);
|
|
11140
11208
|
}
|
|
11141
11209
|
}
|
|
11142
11210
|
assertNotificationCapability(method) {
|
|
@@ -11154,11 +11222,7 @@ var Server = class extends Protocol {
|
|
|
11154
11222
|
case "notifications/prompts/list_changed":
|
|
11155
11223
|
if (!this._capabilities.prompts) throw new Error(`Server does not support notifying of prompt list changes (required for ${method})`);
|
|
11156
11224
|
break;
|
|
11157
|
-
case "notifications/elicitation/complete":
|
|
11158
|
-
if (!this._clientCapabilities?.elicitation?.url) throw new Error(`Client does not support URL elicitation (required for ${method})`);
|
|
11159
|
-
break;
|
|
11160
|
-
case "notifications/cancelled": break;
|
|
11161
|
-
case "notifications/progress": break;
|
|
11225
|
+
case "notifications/elicitation/complete": if (!this._clientCapabilities?.elicitation?.url) throw new Error(`Client does not support URL elicitation (required for ${method})`);
|
|
11162
11226
|
}
|
|
11163
11227
|
}
|
|
11164
11228
|
assertRequestHandlerCapability(method) {
|
|
@@ -11186,11 +11250,7 @@ var Server = class extends Protocol {
|
|
|
11186
11250
|
case "tasks/get":
|
|
11187
11251
|
case "tasks/list":
|
|
11188
11252
|
case "tasks/result":
|
|
11189
|
-
case "tasks/cancel":
|
|
11190
|
-
if (!this._capabilities.tasks) throw new Error(`Server does not support tasks capability (required for ${method})`);
|
|
11191
|
-
break;
|
|
11192
|
-
case "ping":
|
|
11193
|
-
case "initialize": break;
|
|
11253
|
+
case "tasks/cancel": if (!this._capabilities.tasks) throw new Error(`Server does not support tasks capability (required for ${method})`);
|
|
11194
11254
|
}
|
|
11195
11255
|
}
|
|
11196
11256
|
assertTaskCapability(method) {
|
|
@@ -11350,7 +11410,7 @@ var Server = class extends Protocol {
|
|
|
11350
11410
|
}
|
|
11351
11411
|
};
|
|
11352
11412
|
//#endregion
|
|
11353
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
11413
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js
|
|
11354
11414
|
const COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
|
|
11355
11415
|
/**
|
|
11356
11416
|
* Checks if a schema is completable (has completion metadata).
|
|
@@ -11369,7 +11429,7 @@ var McpZodTypeKind;
|
|
|
11369
11429
|
McpZodTypeKind["Completable"] = "McpCompletable";
|
|
11370
11430
|
})(McpZodTypeKind || (McpZodTypeKind = {}));
|
|
11371
11431
|
//#endregion
|
|
11372
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
11432
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js
|
|
11373
11433
|
/**
|
|
11374
11434
|
* Tool name validation utilities according to SEP: Specify Format for Tool Names
|
|
11375
11435
|
*
|
|
@@ -11440,7 +11500,7 @@ function validateAndWarnToolName(name) {
|
|
|
11440
11500
|
return result.isValid;
|
|
11441
11501
|
}
|
|
11442
11502
|
//#endregion
|
|
11443
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
11503
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js
|
|
11444
11504
|
/**
|
|
11445
11505
|
* Experimental McpServer task features for MCP SDK.
|
|
11446
11506
|
* WARNING: These APIs are experimental and may change without notice.
|
|
@@ -11471,7 +11531,7 @@ var ExperimentalMcpServerTasks = class {
|
|
|
11471
11531
|
}
|
|
11472
11532
|
};
|
|
11473
11533
|
//#endregion
|
|
11474
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
11534
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js
|
|
11475
11535
|
function toolInputElementCount(value, max) {
|
|
11476
11536
|
let count = 0;
|
|
11477
11537
|
const stack = [value];
|
|
@@ -12155,7 +12215,7 @@ function serializeMessage(message) {
|
|
|
12155
12215
|
return JSON.stringify(message) + "\n";
|
|
12156
12216
|
}
|
|
12157
12217
|
//#endregion
|
|
12158
|
-
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.
|
|
12218
|
+
//#region node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.7/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
12159
12219
|
/**
|
|
12160
12220
|
* Server transport for stdio: this communicates with an MCP client by reading from the current process' stdin and writing to stdout.
|
|
12161
12221
|
*
|
|
@@ -13576,6 +13636,44 @@ function agentActionsView(report, options = {}) {
|
|
|
13576
13636
|
};
|
|
13577
13637
|
}
|
|
13578
13638
|
//#endregion
|
|
13639
|
+
//#region packages/core/dist/providers/errors.js
|
|
13640
|
+
const PROVIDER_ERROR_CODES = {
|
|
13641
|
+
configuration: "AUTH_CONFIG_REQUIRED",
|
|
13642
|
+
authentication: "AUTH_CONFIG_REQUIRED",
|
|
13643
|
+
"rate-limit": "RATE_LIMITED",
|
|
13644
|
+
timeout: "PROVIDER_UNAVAILABLE",
|
|
13645
|
+
"response-too-large": "PROVIDER_UNAVAILABLE",
|
|
13646
|
+
"invalid-response": "PROVIDER_UNAVAILABLE",
|
|
13647
|
+
"remote-error": "PROVIDER_UNAVAILABLE"
|
|
13648
|
+
};
|
|
13649
|
+
var ProviderError = class extends Error {
|
|
13650
|
+
provider;
|
|
13651
|
+
operation;
|
|
13652
|
+
code;
|
|
13653
|
+
status;
|
|
13654
|
+
retryable;
|
|
13655
|
+
constructor(input) {
|
|
13656
|
+
super(input.message, { cause: input.cause });
|
|
13657
|
+
this.name = "ProviderError";
|
|
13658
|
+
this.provider = input.provider;
|
|
13659
|
+
this.operation = input.operation;
|
|
13660
|
+
this.code = input.code;
|
|
13661
|
+
this.status = input.status ?? null;
|
|
13662
|
+
this.retryable = input.retryable ?? false;
|
|
13663
|
+
}
|
|
13664
|
+
toJSON() {
|
|
13665
|
+
return {
|
|
13666
|
+
name: this.name,
|
|
13667
|
+
provider: this.provider,
|
|
13668
|
+
operation: this.operation,
|
|
13669
|
+
code: this.code,
|
|
13670
|
+
message: this.message,
|
|
13671
|
+
status: this.status,
|
|
13672
|
+
retryable: this.retryable
|
|
13673
|
+
};
|
|
13674
|
+
}
|
|
13675
|
+
};
|
|
13676
|
+
//#endregion
|
|
13579
13677
|
//#region packages/core/dist/errors.js
|
|
13580
13678
|
const errorMetadata = {
|
|
13581
13679
|
ACCESS_DENIED: {
|
|
@@ -13641,6 +13739,7 @@ function errorMessage$1(error) {
|
|
|
13641
13739
|
function toSeoError(error) {
|
|
13642
13740
|
if (error instanceof SeoError) return error;
|
|
13643
13741
|
const message = errorMessage$1(error);
|
|
13742
|
+
if (error instanceof ProviderError) return new SeoError(PROVIDER_ERROR_CODES[error.code], message);
|
|
13644
13743
|
if (/not logged in/i.test(message)) return new SeoError("AUTH_REQUIRED", message);
|
|
13645
13744
|
if (/oauth client config.*missing|shared seo google app/i.test(message)) return new SeoError("AUTH_CONFIG_REQUIRED", message);
|
|
13646
13745
|
if (/invalid_grant|refresh token.*no longer valid/i.test(message)) return new SeoError("AUTH_EXPIRED", message);
|
|
@@ -13854,7 +13953,7 @@ async function listAnalyticsAccounts(gfetch, options) {
|
|
|
13854
13953
|
return googleJson(gfetch, url.toString(), {
|
|
13855
13954
|
...options,
|
|
13856
13955
|
label: "Google Analytics accounts",
|
|
13857
|
-
maxBytes:
|
|
13956
|
+
maxBytes: 10485760
|
|
13858
13957
|
});
|
|
13859
13958
|
});
|
|
13860
13959
|
}
|
|
@@ -13863,7 +13962,7 @@ async function listAnalyticsDataStreams(gfetch, propertyId, options) {
|
|
|
13863
13962
|
...options,
|
|
13864
13963
|
label: "Google Analytics data streams",
|
|
13865
13964
|
subject: `property ${propertyId}`,
|
|
13866
|
-
maxBytes:
|
|
13965
|
+
maxBytes: 1048576
|
|
13867
13966
|
})).dataStreams ?? [];
|
|
13868
13967
|
}
|
|
13869
13968
|
async function runAnalyticsReport(gfetch, propertyId, body, options) {
|
|
@@ -13912,13 +14011,13 @@ function day$2(value) {
|
|
|
13912
14011
|
const date = legacy ? new Date(Number(legacy[1])) : new Date(value);
|
|
13913
14012
|
return Number.isNaN(date.getTime()) ? null : date.toISOString().slice(0, 10);
|
|
13914
14013
|
}
|
|
13915
|
-
const count$
|
|
13916
|
-
function list$
|
|
14014
|
+
const count$3 = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
14015
|
+
function list$2(data, label) {
|
|
13917
14016
|
if (!Array.isArray(data)) throw new SeoError("OPTIONAL_PROVIDER_UNAVAILABLE", `Bing Webmaster returned an invalid ${label}.`);
|
|
13918
14017
|
return data.filter((item) => Boolean(item) && typeof item === "object");
|
|
13919
14018
|
}
|
|
13920
14019
|
async function listBingSites(call) {
|
|
13921
|
-
return list$
|
|
14020
|
+
return list$2(await call("GetUserSites"), "site list").filter((row) => typeof row.Url === "string").map((row) => ({
|
|
13922
14021
|
url: row.Url,
|
|
13923
14022
|
verified: row.IsVerified === true
|
|
13924
14023
|
})).sort((a, b) => a.url.localeCompare(b.url, "en"));
|
|
@@ -13926,10 +14025,10 @@ async function listBingSites(call) {
|
|
|
13926
14025
|
async function bingTraffic(call, site) {
|
|
13927
14026
|
const rows = [];
|
|
13928
14027
|
let invalidRows = 0;
|
|
13929
|
-
for (const row of list$
|
|
14028
|
+
for (const row of list$2(await call("GetRankAndTrafficStats", { siteUrl: site }), "traffic list")) {
|
|
13930
14029
|
const date = day$2(row.Date);
|
|
13931
|
-
const clicks = count$
|
|
13932
|
-
const impressions = count$
|
|
14030
|
+
const clicks = count$3(row.Clicks);
|
|
14031
|
+
const impressions = count$3(row.Impressions);
|
|
13933
14032
|
if (!date || clicks === null || impressions === null) {
|
|
13934
14033
|
invalidRows += 1;
|
|
13935
14034
|
continue;
|
|
@@ -13949,12 +14048,12 @@ async function bingTraffic(call, site) {
|
|
|
13949
14048
|
async function keyed(call, method, params) {
|
|
13950
14049
|
const rows = [];
|
|
13951
14050
|
let invalidRows = 0;
|
|
13952
|
-
for (const row of list$
|
|
14051
|
+
for (const row of list$2(await call(method, params), "row list")) {
|
|
13953
14052
|
const date = day$2(row.Date);
|
|
13954
14053
|
const key = typeof row.Query === "string" ? row.Query.trim() : "";
|
|
13955
|
-
const clicks = count$
|
|
13956
|
-
const impressions = count$
|
|
13957
|
-
const position = count$
|
|
14054
|
+
const clicks = count$3(row.Clicks);
|
|
14055
|
+
const impressions = count$3(row.Impressions);
|
|
14056
|
+
const position = count$3(row.AvgImpressionPosition);
|
|
13958
14057
|
if (!date || !key || clicks === null || impressions === null) {
|
|
13959
14058
|
invalidRows += 1;
|
|
13960
14059
|
continue;
|
|
@@ -14424,15 +14523,18 @@ function factsOnly(value) {
|
|
|
14424
14523
|
if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).filter(([key]) => !ADVICE_KEYS.test(key)).map(([key, child]) => [key, factsOnly(child)]));
|
|
14425
14524
|
return value;
|
|
14426
14525
|
}
|
|
14526
|
+
function realIsoDate(value) {
|
|
14527
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(value) && (/* @__PURE__ */ new Date(`${value}T00:00:00Z`)).toISOString().startsWith(value);
|
|
14528
|
+
}
|
|
14427
14529
|
function dateWindow(input, fallbackDays) {
|
|
14428
|
-
if (input.startDate
|
|
14429
|
-
|
|
14430
|
-
|
|
14431
|
-
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14435
|
-
|
|
14530
|
+
if (!input.startDate && !input.endDate) return finalGscDateRange(fallbackDays);
|
|
14531
|
+
const endDate = input.endDate ?? latestFinalGscDate();
|
|
14532
|
+
const startDate = input.startDate ?? shiftIsoDate(endDate, 1 - fallbackDays);
|
|
14533
|
+
if (!realIsoDate(startDate) || !realIsoDate(endDate) || startDate > endDate) throw new CommandError("INVALID_INPUT", `Send real YYYY-MM-DD dates with the start before the end (got ${startDate} to ${endDate}).`);
|
|
14534
|
+
return {
|
|
14535
|
+
startDate,
|
|
14536
|
+
endDate
|
|
14537
|
+
};
|
|
14436
14538
|
}
|
|
14437
14539
|
function earlierRange(range) {
|
|
14438
14540
|
return decayComparisonRange(range, "previous-period");
|
|
@@ -14488,7 +14590,7 @@ function sharedReader(read, redirects = /* @__PURE__ */ new Map()) {
|
|
|
14488
14590
|
return found;
|
|
14489
14591
|
};
|
|
14490
14592
|
}
|
|
14491
|
-
const MAX_STATUS_BYTES =
|
|
14593
|
+
const MAX_STATUS_BYTES = 10485760;
|
|
14492
14594
|
async function googleUpdates(window) {
|
|
14493
14595
|
if (!window) return [];
|
|
14494
14596
|
const incidents = await fetch("https://status.search.google.com/incidents.json", { signal: AbortSignal.timeout(8e3) }).then((response) => response.ok ? readJson(response, "Google Search Status", { maxBytes: MAX_STATUS_BYTES }) : null).catch(() => null);
|
|
@@ -14516,20 +14618,38 @@ function listOfUpdates(value, checked) {
|
|
|
14516
14618
|
if (value.length === 0) return `Google updates ${where}: none.`;
|
|
14517
14619
|
return `Google updates ${where} (timing only, not cause): ${value.map((update) => `${update.name} (${update.start.slice(0, 10)} to ${update.end?.slice(0, 10) ?? "ongoing"})`).join("; ")}.`;
|
|
14518
14620
|
}
|
|
14621
|
+
function readable(names, who = "it") {
|
|
14622
|
+
if (!names.length) return `Search Console properties ${who} can read: none.`;
|
|
14623
|
+
const more = names.length > 20 ? `, and ${names.length - 20} more` : "";
|
|
14624
|
+
return `Search Console properties ${who} can read: ${names.slice(0, 20).join(", ")}${more}.`;
|
|
14625
|
+
}
|
|
14519
14626
|
function matchProperty(names, site) {
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
let
|
|
14627
|
+
const value = site.trim();
|
|
14628
|
+
if (names.includes(value)) return value;
|
|
14629
|
+
let url;
|
|
14523
14630
|
try {
|
|
14524
|
-
|
|
14525
|
-
host = url.hostname.replace(/^www\./, "");
|
|
14526
|
-
origin = url.origin;
|
|
14631
|
+
url = new URL(value.includes("://") ? value : `https://${value.replace(/^sc-domain:/i, "")}`);
|
|
14527
14632
|
} catch {
|
|
14528
14633
|
return null;
|
|
14529
14634
|
}
|
|
14530
|
-
const
|
|
14531
|
-
|
|
14532
|
-
|
|
14635
|
+
const bare = (name) => name.replace(/^www\./, "");
|
|
14636
|
+
const host = bare(url.hostname);
|
|
14637
|
+
const domain = names.filter((name) => name.startsWith("sc-domain:")).filter((name) => {
|
|
14638
|
+
const own = name.slice(10);
|
|
14639
|
+
return own.startsWith("www.") ? bare(own) === host : host === own || host.endsWith(`.${own}`);
|
|
14640
|
+
}).sort((a, b) => b.length - a.length || a.localeCompare(b))[0];
|
|
14641
|
+
if (domain) return domain;
|
|
14642
|
+
const schemes = value.includes("://") ? [url.protocol] : ["https:", "http:"];
|
|
14643
|
+
return names.map((name) => {
|
|
14644
|
+
try {
|
|
14645
|
+
return {
|
|
14646
|
+
name,
|
|
14647
|
+
url: new URL(name)
|
|
14648
|
+
};
|
|
14649
|
+
} catch {
|
|
14650
|
+
return null;
|
|
14651
|
+
}
|
|
14652
|
+
}).filter((entry) => entry !== null && schemes.includes(entry.url.protocol) && bare(entry.url.hostname) === host && `${url.pathname}/`.startsWith(entry.url.pathname)).sort((a, b) => b.url.pathname.length - a.url.pathname.length || schemes.indexOf(a.url.protocol) - schemes.indexOf(b.url.protocol) || Number(b.url.hostname === url.hostname) - Number(a.url.hostname === url.hostname) || a.name.localeCompare(b.name))[0]?.name ?? null;
|
|
14533
14653
|
}
|
|
14534
14654
|
//#endregion
|
|
14535
14655
|
//#region packages/core/dist/commands/present.js
|
|
@@ -14951,9 +15071,10 @@ var LinkedAccounts = class {
|
|
|
14951
15071
|
}
|
|
14952
15072
|
async resolve(site) {
|
|
14953
15073
|
if (this.google.length === 0) throw new CommandError("NOT_CONNECTED", `No Google account is connected. ${this.hint.signIn}`);
|
|
14954
|
-
const
|
|
15074
|
+
const names = await this.properties();
|
|
15075
|
+
const found = matchProperty(names, site);
|
|
14955
15076
|
if (found) return found;
|
|
14956
|
-
throw new CommandError("NO_ACCESS", `None of the connected Google accounts (${this.google.map((linked) => linked.email).join(", ")}) has a Search Console property for ${site}. ${this.hint.addGoogle}`);
|
|
15077
|
+
throw new CommandError("NO_ACCESS", `None of the connected Google accounts (${this.google.map((linked) => linked.email).join(", ")}) has a Search Console property for ${site}. ${readable(names, "they")} ${this.hint.addGoogle}`);
|
|
14957
15078
|
}
|
|
14958
15079
|
async owner(site) {
|
|
14959
15080
|
const owner = (await this.ownerMap()).get(await this.resolve(site));
|
|
@@ -15302,6 +15423,10 @@ function classify(error) {
|
|
|
15302
15423
|
errorCategory: "crawl_timeout",
|
|
15303
15424
|
failureReason: "crawl_timeout"
|
|
15304
15425
|
};
|
|
15426
|
+
const provider = signals.find((signal) => signal.name === "ProviderError");
|
|
15427
|
+
const providerCode = PROVIDER_ERROR_CODES[provider?.code];
|
|
15428
|
+
const fromProvider = providerCode && PRODUCT_FAILURES[providerCode];
|
|
15429
|
+
if (fromProvider) return fromProvider;
|
|
15305
15430
|
for (const code of codes) {
|
|
15306
15431
|
const product = PRODUCT_FAILURES[code];
|
|
15307
15432
|
if (product) return product;
|
|
@@ -15694,6 +15819,15 @@ async function cloudCredentials(options = {}) {
|
|
|
15694
15819
|
})();
|
|
15695
15820
|
return credentials;
|
|
15696
15821
|
}
|
|
15822
|
+
async function cloudWeek() {
|
|
15823
|
+
const token = cloudToken();
|
|
15824
|
+
if (!token) throw new SeoError("AUTH_REQUIRED", notSignedIn());
|
|
15825
|
+
const result = await call$1("/account/cli/week", { token });
|
|
15826
|
+
if (result.status === 401) throw new SeoError("AUTH_EXPIRED", `This machine is not linked to a seoskill.dev account any more. ${CLOUD_SIGN_IN}`);
|
|
15827
|
+
if (result.status === 403) return null;
|
|
15828
|
+
if (!result.ok) throw new SeoError("PROVIDER_UNAVAILABLE", `seoskill.dev returned ${result.status}. Try again in a minute.`);
|
|
15829
|
+
return result.body;
|
|
15830
|
+
}
|
|
15697
15831
|
function notSignedIn() {
|
|
15698
15832
|
return "Not signed in. Run `seo login` to use your seoskill.dev account on this machine (it prints a link to approve), or `seo auth login` to sign in with Google on this machine only. `seo crawl --url <url>` works without sign-in.";
|
|
15699
15833
|
}
|
|
@@ -16411,15 +16545,15 @@ function googleFetchFor(client) {
|
|
|
16411
16545
|
const LOCAL_SIGN_IN = { signIn: "Run `seo auth login` again." };
|
|
16412
16546
|
//#endregion
|
|
16413
16547
|
//#region packages/core/dist/storage/cache-maintenance.js
|
|
16414
|
-
const MEBIBYTE$
|
|
16415
|
-
const CACHE_MAX_AGE_MS =
|
|
16548
|
+
const MEBIBYTE$1 = 1048576;
|
|
16549
|
+
const CACHE_MAX_AGE_MS = 2592e6;
|
|
16416
16550
|
const CACHE_LIMITS = {
|
|
16417
|
-
gsc_cache: 48 * MEBIBYTE$
|
|
16418
|
-
url_inspection_cache: 16 * MEBIBYTE$
|
|
16419
|
-
ga4_cache: 24 * MEBIBYTE$
|
|
16420
|
-
provider_cache: 32 * MEBIBYTE$
|
|
16421
|
-
http_cache: 128 * MEBIBYTE$
|
|
16422
|
-
performance_reports: 8 * MEBIBYTE$
|
|
16551
|
+
gsc_cache: 48 * MEBIBYTE$1,
|
|
16552
|
+
url_inspection_cache: 16 * MEBIBYTE$1,
|
|
16553
|
+
ga4_cache: 24 * MEBIBYTE$1,
|
|
16554
|
+
provider_cache: 32 * MEBIBYTE$1,
|
|
16555
|
+
http_cache: 128 * MEBIBYTE$1,
|
|
16556
|
+
performance_reports: 8 * MEBIBYTE$1
|
|
16423
16557
|
};
|
|
16424
16558
|
const CACHE_POLICIES = [
|
|
16425
16559
|
{
|
|
@@ -17928,7 +18062,7 @@ async function extractMainMarkdown(fetchResult) {
|
|
|
17928
18062
|
const cut = markdown.slice(0, MARKDOWN_LIMIT);
|
|
17929
18063
|
const end = cut.lastIndexOf("\n");
|
|
17930
18064
|
return {
|
|
17931
|
-
markdown: (end >
|
|
18065
|
+
markdown: (end > 1e4 ? cut.slice(0, end) : cut).trimEnd(),
|
|
17932
18066
|
characters: markdown.length,
|
|
17933
18067
|
truncated: true
|
|
17934
18068
|
};
|
|
@@ -19190,7 +19324,7 @@ async function fetchWithRedirectChain(url, signal) {
|
|
|
19190
19324
|
}
|
|
19191
19325
|
//#endregion
|
|
19192
19326
|
//#region packages/core/dist/fetch/page-fetcher/robots.js
|
|
19193
|
-
const MAX_ROBOTS_RESPONSE_BYTES =
|
|
19327
|
+
const MAX_ROBOTS_RESPONSE_BYTES = 1048576;
|
|
19194
19328
|
var RobotsAccessError = class extends Error {
|
|
19195
19329
|
reason;
|
|
19196
19330
|
evidence;
|
|
@@ -19364,7 +19498,7 @@ function diagnosticRobotsEvidence(robots) {
|
|
|
19364
19498
|
}
|
|
19365
19499
|
//#endregion
|
|
19366
19500
|
//#region packages/core/dist/fetch/page-fetcher/plain.js
|
|
19367
|
-
const MAX_PAGE_RESPONSE_BYTES =
|
|
19501
|
+
const MAX_PAGE_RESPONSE_BYTES = 5242880;
|
|
19368
19502
|
function encodePageFetchCacheEvidence(result) {
|
|
19369
19503
|
return JSON.stringify({
|
|
19370
19504
|
finalUrl: result.finalUrl,
|
|
@@ -20129,7 +20263,7 @@ function assertUrlMatchesGscProperty(property, value) {
|
|
|
20129
20263
|
if (!url.startsWith(prefix)) return invalid(`${url} is outside the Search Console property ${property}.`);
|
|
20130
20264
|
return url;
|
|
20131
20265
|
}
|
|
20132
|
-
const RESERVATION_TTL_MS =
|
|
20266
|
+
const RESERVATION_TTL_MS = 3e5;
|
|
20133
20267
|
var UrlInspectionQuotaError = class extends SeoError {
|
|
20134
20268
|
property;
|
|
20135
20269
|
requestSent;
|
|
@@ -20174,8 +20308,8 @@ function reconcileExpiredReservations(input) {
|
|
|
20174
20308
|
WHERE credential_key = ? AND property_site_url = ? AND quota_date = ?`).run(expired.count, expired.count, input.now, input.credentialKey, input.property, input.quotaDate);
|
|
20175
20309
|
}
|
|
20176
20310
|
function pruneOldQuotaRows(database, now) {
|
|
20177
|
-
const reservationCutoff = now -
|
|
20178
|
-
const bucketCutoff = (/* @__PURE__ */ new Date(now -
|
|
20311
|
+
const reservationCutoff = now - 1728e5;
|
|
20312
|
+
const bucketCutoff = (/* @__PURE__ */ new Date(now - 6048e5)).toISOString().slice(0, 10);
|
|
20179
20313
|
database.prepare(`DELETE FROM url_inspection_quota_reservations
|
|
20180
20314
|
WHERE expires_at < ?`).run(reservationCutoff);
|
|
20181
20315
|
database.prepare(`DELETE FROM url_inspection_quota_buckets
|
|
@@ -20547,7 +20681,7 @@ async function queryPagesTopQueriesBatch(site, pageUrls, range = 28) {
|
|
|
20547
20681
|
}
|
|
20548
20682
|
//#endregion
|
|
20549
20683
|
//#region packages/core/dist/gsc/client/sites.js
|
|
20550
|
-
async function listSites(_refresh = false, accountEmail) {
|
|
20684
|
+
async function listSites$1(_refresh = false, accountEmail) {
|
|
20551
20685
|
const entries = !accountEmail && cloudLinked() ? await allCloudSites() : await listSearchConsoleSites(googleFetchFor((await getAuthorized(accountEmail)).client), LOCAL_SIGN_IN);
|
|
20552
20686
|
writeToCache((database) => {
|
|
20553
20687
|
const insert = database.prepare("INSERT OR REPLACE INTO sites (site_url, display_name, permission, added_at, is_default) VALUES (?, ?, ?, ?, COALESCE((SELECT is_default FROM sites WHERE site_url = ?), 0))");
|
|
@@ -22173,7 +22307,7 @@ const actionPriority = new Map([
|
|
|
22173
22307
|
"unverified",
|
|
22174
22308
|
"covered"
|
|
22175
22309
|
].map((type, index) => [type, index]));
|
|
22176
|
-
function plural$
|
|
22310
|
+
function plural$8(count, singular, pluralLabel) {
|
|
22177
22311
|
return count === 1 ? singular : pluralLabel;
|
|
22178
22312
|
}
|
|
22179
22313
|
function actionable(item) {
|
|
@@ -22207,7 +22341,7 @@ function pageOpportunityVerdict(input) {
|
|
|
22207
22341
|
if (focus === "unverified") return "GSC visibility exists, but the page was not verified and no specific change is justified yet.";
|
|
22208
22342
|
if (focus === "covered") return "The verified page covers the sampled queries and CTR is not materially below its directional benchmark.";
|
|
22209
22343
|
const count = analysis.summary.opportunities;
|
|
22210
|
-
const prefix = `${count} ${plural$
|
|
22344
|
+
const prefix = `${count} ${plural$8(count, "actionable observation", "actionable observations")} found.`;
|
|
22211
22345
|
if (focus === "content-gap") return `${prefix} Verified body coverage is the main issue; confirm intent before expanding the page.`;
|
|
22212
22346
|
if (focus === "serp-framing") return `${prefix} The body is relevant, but its title, meta description, or H1 framing is weak.`;
|
|
22213
22347
|
if (focus === "ranking") return `${prefix} Most upside requires stronger relevance or authority; no CTR-only lift is claimed for page-two queries.`;
|
|
@@ -22222,7 +22356,7 @@ function pageOpportunityRecommendations(analysis) {
|
|
|
22222
22356
|
}
|
|
22223
22357
|
const recommendations = [`Start with "${top.query}". ${top.recommendation}`];
|
|
22224
22358
|
const technical = actions.filter((item) => item.opportunityType === "technical-check").length;
|
|
22225
|
-
if (technical) recommendations.push(`Resolve the technical evidence affecting ${technical} ${plural$
|
|
22359
|
+
if (technical) recommendations.push(`Resolve the technical evidence affecting ${technical} ${plural$8(technical, "row", "rows")} before content work.`);
|
|
22226
22360
|
const gaps = actions.filter((item) => item.opportunityType === "content-gap").length;
|
|
22227
22361
|
if (gaps >= 3) recommendations.push(`Group the ${gaps} verified content gaps into useful sections rather than adding one thin paragraph per query.`);
|
|
22228
22362
|
return recommendations;
|
|
@@ -22649,8 +22783,8 @@ function urlKey(value) {
|
|
|
22649
22783
|
}
|
|
22650
22784
|
}
|
|
22651
22785
|
const SLOW_RESPONSE_MS = 2e3;
|
|
22652
|
-
const LARGE_HTML_BYTES =
|
|
22653
|
-
const COMPRESSION_MIN_BYTES =
|
|
22786
|
+
const LARGE_HTML_BYTES = 2097152;
|
|
22787
|
+
const COMPRESSION_MIN_BYTES = 4096;
|
|
22654
22788
|
const DEEP_PAGE_DEPTH = 4;
|
|
22655
22789
|
const WEAK_VALUABLE_INLINKS = 1;
|
|
22656
22790
|
const QUERY_COVERAGE_MIN_IMPRESSIONS = 50;
|
|
@@ -23529,8 +23663,10 @@ function summarizeCrawlReport(input) {
|
|
|
23529
23663
|
if (request.outcome === "response") {
|
|
23530
23664
|
responseRequests += 1;
|
|
23531
23665
|
if (request.extraction === "failed") extractionFailures += 1;
|
|
23532
|
-
} else if (request.outcome === "failure")
|
|
23533
|
-
|
|
23666
|
+
} else if (request.outcome === "failure") {
|
|
23667
|
+
if (request.failureKind === "aborted") abortedRequests += 1;
|
|
23668
|
+
else failedRequests += 1;
|
|
23669
|
+
}
|
|
23534
23670
|
}
|
|
23535
23671
|
let highIssues = 0;
|
|
23536
23672
|
let mediumIssues = 0;
|
|
@@ -24849,11 +24985,11 @@ function cancellationRace(signal) {
|
|
|
24849
24985
|
}
|
|
24850
24986
|
//#endregion
|
|
24851
24987
|
//#region packages/core/dist/analyze/crawler/crawl-memory.js
|
|
24852
|
-
const MEBIBYTE
|
|
24853
|
-
const MIN_CRAWL_MEMORY_LIMIT = 384 * MEBIBYTE
|
|
24854
|
-
const MAX_CRAWL_MEMORY_LIMIT = 640 * MEBIBYTE
|
|
24855
|
-
const MIN_CRAWL_RSS_LIMIT = 512 * MEBIBYTE
|
|
24856
|
-
const MAX_CRAWL_RSS_LIMIT = 896 * MEBIBYTE
|
|
24988
|
+
const MEBIBYTE = 1048576;
|
|
24989
|
+
const MIN_CRAWL_MEMORY_LIMIT = 384 * MEBIBYTE;
|
|
24990
|
+
const MAX_CRAWL_MEMORY_LIMIT = 640 * MEBIBYTE;
|
|
24991
|
+
const MIN_CRAWL_RSS_LIMIT = 512 * MEBIBYTE;
|
|
24992
|
+
const MAX_CRAWL_RSS_LIMIT = 896 * MEBIBYTE;
|
|
24857
24993
|
const SYSTEM_MEMORY_FRACTION = .1;
|
|
24858
24994
|
const SYSTEM_RSS_FRACTION = .2;
|
|
24859
24995
|
function crawlMemoryLimitBytes(totalMemoryBytes) {
|
|
@@ -25252,7 +25388,7 @@ async function collectCrawlSiteChecks(input) {
|
|
|
25252
25388
|
}
|
|
25253
25389
|
//#endregion
|
|
25254
25390
|
//#region packages/core/dist/analyze/crawler/site-crawl-ai-signals.js
|
|
25255
|
-
const MAX_AUXILIARY_RESPONSE_BYTES =
|
|
25391
|
+
const MAX_AUXILIARY_RESPONSE_BYTES = 2097152;
|
|
25256
25392
|
const LLMS_LINK_LIMIT = 20;
|
|
25257
25393
|
const AI_BOTS = [
|
|
25258
25394
|
["OAI-SearchBot", "search"],
|
|
@@ -26623,35 +26759,6 @@ async function fetchSitemapUrls(input) {
|
|
|
26623
26759
|
};
|
|
26624
26760
|
}
|
|
26625
26761
|
//#endregion
|
|
26626
|
-
//#region packages/core/dist/providers/errors.js
|
|
26627
|
-
var ProviderError = class extends Error {
|
|
26628
|
-
provider;
|
|
26629
|
-
operation;
|
|
26630
|
-
code;
|
|
26631
|
-
status;
|
|
26632
|
-
retryable;
|
|
26633
|
-
constructor(input) {
|
|
26634
|
-
super(input.message, { cause: input.cause });
|
|
26635
|
-
this.name = "ProviderError";
|
|
26636
|
-
this.provider = input.provider;
|
|
26637
|
-
this.operation = input.operation;
|
|
26638
|
-
this.code = input.code;
|
|
26639
|
-
this.status = input.status ?? null;
|
|
26640
|
-
this.retryable = input.retryable ?? false;
|
|
26641
|
-
}
|
|
26642
|
-
toJSON() {
|
|
26643
|
-
return {
|
|
26644
|
-
name: this.name,
|
|
26645
|
-
provider: this.provider,
|
|
26646
|
-
operation: this.operation,
|
|
26647
|
-
code: this.code,
|
|
26648
|
-
message: this.message,
|
|
26649
|
-
status: this.status,
|
|
26650
|
-
retryable: this.retryable
|
|
26651
|
-
};
|
|
26652
|
-
}
|
|
26653
|
-
};
|
|
26654
|
-
//#endregion
|
|
26655
26762
|
//#region packages/core/dist/providers/cache.js
|
|
26656
26763
|
function stableValue(value) {
|
|
26657
26764
|
if (Array.isArray(value)) return value.map(stableValue);
|
|
@@ -26906,7 +27013,7 @@ const identifierPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/u;
|
|
|
26906
27013
|
const packageNamePattern = /^(?:@[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*|[a-z0-9][a-z0-9._-]*)$/u;
|
|
26907
27014
|
const exactVersionPattern = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u;
|
|
26908
27015
|
const integrityPattern = /^sha(?:256|384|512)-[A-Za-z0-9+/=]+$/u;
|
|
26909
|
-
const MAX_SCHEMA_BYTES =
|
|
27016
|
+
const MAX_SCHEMA_BYTES = 65536;
|
|
26910
27017
|
const MAX_SCHEMA_DEPTH = 16;
|
|
26911
27018
|
const MAX_SCHEMA_VALUES = 5e3;
|
|
26912
27019
|
function boundedJsonObject(value) {
|
|
@@ -26979,7 +27086,7 @@ const providerCapabilityAdapterSchema = z.union([landingPageVisitsCapabilitySche
|
|
|
26979
27086
|
const providerActionAdapterSchema = z.custom((value) => {
|
|
26980
27087
|
if (typeof value !== "object" || value === null) return false;
|
|
26981
27088
|
const action = value;
|
|
26982
|
-
return typeof action.id === "string" && providerExtensionIdSchema.safeParse(action.id).success && typeof action.description === "string" && action.description.trim().length >= 1 && action.description.length <= 240 && supportedJsonSchema(action.inputSchema, true) && supportedJsonSchema(action.outputSchema) && (action.cacheTtlMs === void 0 || Number.isSafeInteger(action.cacheTtlMs) && action.cacheTtlMs >= 0 && action.cacheTtlMs <=
|
|
27089
|
+
return typeof action.id === "string" && providerExtensionIdSchema.safeParse(action.id).success && typeof action.description === "string" && action.description.trim().length >= 1 && action.description.length <= 240 && supportedJsonSchema(action.inputSchema, true) && supportedJsonSchema(action.outputSchema) && (action.cacheTtlMs === void 0 || Number.isSafeInteger(action.cacheTtlMs) && action.cacheTtlMs >= 0 && action.cacheTtlMs <= 6048e5) && typeof action.run === "function";
|
|
26983
27090
|
}, "Invalid provider action.");
|
|
26984
27091
|
const providerPackageManifestSchema = z.object({
|
|
26985
27092
|
apiVersion: z.literal(1),
|
|
@@ -27349,8 +27456,8 @@ async function loadInstalledProviderExtensions(options = {}) {
|
|
|
27349
27456
|
//#endregion
|
|
27350
27457
|
//#region packages/core/dist/provider-extensions/runtime.js
|
|
27351
27458
|
const DEFAULT_MAX_REQUESTS = 8;
|
|
27352
|
-
const MAX_RESPONSE_BYTES$1 =
|
|
27353
|
-
const MAX_REQUEST_BODY_BYTES =
|
|
27459
|
+
const MAX_RESPONSE_BYTES$1 = 10485760;
|
|
27460
|
+
const MAX_REQUEST_BODY_BYTES = 65536;
|
|
27354
27461
|
const TIMEOUT_MS$3 = 15e3;
|
|
27355
27462
|
function normalizeProviderExtensionAccount(provider, account) {
|
|
27356
27463
|
const fields = provider.connection.fields.filter((field) => field.kind === "account");
|
|
@@ -27407,7 +27514,7 @@ function runtimeForProvider(provider, options = {}) {
|
|
|
27407
27514
|
}
|
|
27408
27515
|
//#endregion
|
|
27409
27516
|
//#region packages/core/dist/provider-extensions/analytics.js
|
|
27410
|
-
const CACHE_TTL_MS$1 =
|
|
27517
|
+
const CACHE_TTL_MS$1 = 864e5;
|
|
27411
27518
|
const landingPageResultSchema = z.object({
|
|
27412
27519
|
metric: z.literal("landing-page-visits"),
|
|
27413
27520
|
rows: z.array(z.object({
|
|
@@ -28006,16 +28113,18 @@ async function crawlSite(input, dependencies) {
|
|
|
28006
28113
|
return;
|
|
28007
28114
|
}
|
|
28008
28115
|
if (queue.size + visited.size + inFlight.size >= config.maxPages * 5) {
|
|
28009
|
-
if (!queueSafetyDeferredUrls.has(normalized))
|
|
28010
|
-
queueSafetyDeferredUrls.
|
|
28011
|
-
|
|
28012
|
-
|
|
28013
|
-
|
|
28014
|
-
|
|
28015
|
-
|
|
28016
|
-
|
|
28017
|
-
|
|
28018
|
-
|
|
28116
|
+
if (!queueSafetyDeferredUrls.has(normalized)) {
|
|
28117
|
+
if (queueSafetyDeferredUrls.size < maxTrackedQueueSafetyUrls) {
|
|
28118
|
+
queueSafetyDeferredUrls.add(normalized);
|
|
28119
|
+
queueSafetySkippedUrls = queueSafetyDeferredUrls.size;
|
|
28120
|
+
recordSkip("queue-safety-limit");
|
|
28121
|
+
emitStatus("url_skipped", {
|
|
28122
|
+
url: normalized,
|
|
28123
|
+
depth,
|
|
28124
|
+
reason: "queue_safety_limit"
|
|
28125
|
+
});
|
|
28126
|
+
} else queueSafetyInventoryCapped = true;
|
|
28127
|
+
}
|
|
28019
28128
|
return;
|
|
28020
28129
|
}
|
|
28021
28130
|
discovered.add(normalized);
|
|
@@ -28121,12 +28230,14 @@ async function crawlSite(input, dependencies) {
|
|
|
28121
28230
|
extraction: "not-applicable"
|
|
28122
28231
|
});
|
|
28123
28232
|
requests.push(request);
|
|
28124
|
-
if (healthStrategy)
|
|
28125
|
-
|
|
28126
|
-
|
|
28127
|
-
|
|
28128
|
-
|
|
28129
|
-
|
|
28233
|
+
if (healthStrategy) {
|
|
28234
|
+
if (request.outcome === "response" && request.status < 400 && !request.accessBlock) {
|
|
28235
|
+
healthyProbeStreak += 1;
|
|
28236
|
+
activeConcurrency = Math.min(config.concurrency, 1 + Math.floor(healthyProbeStreak / 20));
|
|
28237
|
+
} else {
|
|
28238
|
+
healthyProbeStreak = 0;
|
|
28239
|
+
activeConcurrency = 1;
|
|
28240
|
+
}
|
|
28130
28241
|
}
|
|
28131
28242
|
checkMemoryPressure();
|
|
28132
28243
|
if (request.outcome === "skipped") {
|
|
@@ -28259,14 +28370,16 @@ async function crawlSite(input, dependencies) {
|
|
|
28259
28370
|
depth: task.depth,
|
|
28260
28371
|
statusCode: page.status
|
|
28261
28372
|
});
|
|
28262
|
-
if (followLinks && task.depth < config.maxDepth)
|
|
28263
|
-
|
|
28264
|
-
|
|
28265
|
-
|
|
28266
|
-
|
|
28373
|
+
if (followLinks && task.depth < config.maxDepth) {
|
|
28374
|
+
if (memoryLimited) for (const value of result.urls) {
|
|
28375
|
+
const normalized = normalizeUrl$1(value, finalUrl);
|
|
28376
|
+
if (normalized && sameOrigin(normalized, origin) && !isLikelyAsset(normalized) && passesFilters(normalized, config.include, config.exclude) && !visited.has(normalized) && !queue.has(normalized)) {
|
|
28377
|
+
discovered.add(normalized);
|
|
28378
|
+
memoryDeferredUrls.add(normalized);
|
|
28379
|
+
}
|
|
28267
28380
|
}
|
|
28381
|
+
else for (const url of result.urls) enqueue(url, task.depth + 1);
|
|
28268
28382
|
}
|
|
28269
|
-
else for (const url of result.urls) enqueue(url, task.depth + 1);
|
|
28270
28383
|
}
|
|
28271
28384
|
const memoryPressureSkippedUrls = memoryLimited ? queue.size + memoryDeferredUrls.size : 0;
|
|
28272
28385
|
const stoppedForMemory = memoryPressureSkippedUrls > 0;
|
|
@@ -28961,7 +29074,7 @@ function analyzeCtrUnderperformersFromRows(input) {
|
|
|
28961
29074
|
const MAX_GSC_ROWS$3 = 1e5;
|
|
28962
29075
|
const DEFAULT_DAYS$3 = 28;
|
|
28963
29076
|
const MAX_DAYS$2 = 548;
|
|
28964
|
-
function plural$
|
|
29077
|
+
function plural$7(count, singular, pluralLabel = `${singular}s`) {
|
|
28965
29078
|
return count === 1 ? singular : pluralLabel;
|
|
28966
29079
|
}
|
|
28967
29080
|
async function ctrUnderperformersReportWith(input, dependencies) {
|
|
@@ -29064,11 +29177,11 @@ async function ctrUnderperformersReportWith(input, dependencies) {
|
|
|
29064
29177
|
minImpressions,
|
|
29065
29178
|
limit,
|
|
29066
29179
|
brandFiltering: input.includeBrand ? "included" : "excluded",
|
|
29067
|
-
verdict: top ? `${selection.eligibleUnderperformers} CTR ${plural$
|
|
29180
|
+
verdict: top ? `${selection.eligibleUnderperformers} CTR ${plural$7(selection.eligibleUnderperformers, "underperformer")} found in retained rows, with a calculated heuristic shortfall of ${totalClickShortfall.toFixed(0)} clicks for this window. Start review with "${top.query}" because it has the largest gap.` : dataStatus === "partial" ? "No material CTR underperformers remained in the validated retained rows, but partial evidence prevents an all-clear." : `No high-impression rows at average position below 4 in the retained rows are materially below the heuristic CTR benchmark.`
|
|
29068
29181
|
},
|
|
29069
29182
|
items,
|
|
29070
29183
|
caveats: [
|
|
29071
|
-
`Date window: ${range.startDate} to ${range.endDate} (${days} ${plural$
|
|
29184
|
+
`Date window: ${range.startDate} to ${range.endDate} (${days} ${plural$7(days, "day")}), using final GSC data where available.`,
|
|
29072
29185
|
`Brand queries: ${input.includeBrand ? "included" : "excluded"}. Brand terms used: ${brand.terms.join(", ") || "none"} (${brand.source === "provided" ? "provided" : "host forms, plus the bare domain stem only when Search Console shows the site is its navigational answer"}).`,
|
|
29073
29186
|
`Only rows at average position below 4 with at least ${minImpressions} impressions were checked. Rows at position 4 to 10 belong to quick-wins, which uses the same site CTR curve.`,
|
|
29074
29187
|
minImpressionsCaveat({
|
|
@@ -29076,13 +29189,13 @@ async function ctrUnderperformersReportWith(input, dependencies) {
|
|
|
29076
29189
|
belowMinimumRows: selection.belowMinimumRows
|
|
29077
29190
|
}),
|
|
29078
29191
|
"Expected CTR uses the site CTR curve from all page-one rows (75th percentile of qualified URL CTRs per position) when enough peer data exists, otherwise the fallback position curve.",
|
|
29079
|
-
...selection.fragmentRows ? [`${selection.fragmentRows} source ${plural$
|
|
29080
|
-
...selection.flaggedRows ? [`${selection.flaggedRows} eligible ${plural$
|
|
29192
|
+
...selection.fragmentRows ? [`${selection.fragmentRows} source ${plural$7(selection.fragmentRows, "row")} with a #fragment URL ${selection.fragmentRows === 1 ? "was" : "were"} merged into the base URL.`] : [],
|
|
29193
|
+
...selection.flaggedRows ? [`${selection.flaggedRows} eligible ${plural$7(selection.flaggedRows, "row")} carry heuristic query flags (likely-automated or navigational-other) and rank after unflagged rows.`] : [],
|
|
29081
29194
|
"CTR benchmarks and calculated click shortfalls are directional heuristics, not forecasts or proof that clicks are available. Validate the search intent and live SERP before editing.",
|
|
29082
|
-
...selection.invalidRows ? [`${selection.invalidRows} invalid provider ${plural$
|
|
29083
|
-
...selection.duplicateRows ? [`${selection.duplicateRows} repeated query/page ${plural$
|
|
29195
|
+
...selection.invalidRows ? [`${selection.invalidRows} invalid provider ${plural$7(selection.invalidRows, "row")} ${selection.invalidRows === 1 ? "was" : "were"} excluded, so this report is partial.`] : [],
|
|
29196
|
+
...selection.duplicateRows ? [`${selection.duplicateRows} repeated query/page ${plural$7(selection.duplicateRows, "row")} ${selection.duplicateRows === 1 ? "was" : "were"} aggregated before CTR and average position were calculated.`] : [],
|
|
29084
29197
|
...possiblyTruncated ? [`The retained-row limit of ${MAX_GSC_ROWS$3} was reached, so lower-ranked source rows may be absent.`] : [],
|
|
29085
|
-
...selection.limitedUnderperformers ? [`${selection.limitedUnderperformers} eligible ${plural$
|
|
29198
|
+
...selection.limitedUnderperformers ? [`${selection.limitedUnderperformers} eligible ${plural$7(selection.limitedUnderperformers, "underperformer")} ${selection.limitedUnderperformers === 1 ? "was" : "were"} omitted by the output limit.`] : []
|
|
29086
29199
|
],
|
|
29087
29200
|
recommendations: top ? [
|
|
29088
29201
|
`Review the live SERP and displayed snippet for "${top.query}" first. Test the title or meta description only if the observed framing does not match the query intent.`,
|
|
@@ -29102,11 +29215,11 @@ function ctrUnderperformersReport(input, dependencies = defaultDependencies$9) {
|
|
|
29102
29215
|
}
|
|
29103
29216
|
//#endregion
|
|
29104
29217
|
//#region packages/core/dist/phrasing.js
|
|
29105
|
-
function plural$
|
|
29218
|
+
function plural$6(count, singular, pluralLabel = `${singular}s`) {
|
|
29106
29219
|
return count === 1 ? singular : pluralLabel;
|
|
29107
29220
|
}
|
|
29108
29221
|
function countLabel(count, singular, pluralLabel = `${singular}s`) {
|
|
29109
|
-
return `${count.toLocaleString("en-GB")} ${plural$
|
|
29222
|
+
return `${count.toLocaleString("en-GB")} ${plural$6(count, singular, pluralLabel)}`;
|
|
29110
29223
|
}
|
|
29111
29224
|
//#endregion
|
|
29112
29225
|
//#region packages/core/dist/analyze/diagnosis-priorities.js
|
|
@@ -29428,7 +29541,7 @@ function analyzeSegmentRows(input) {
|
|
|
29428
29541
|
}
|
|
29429
29542
|
//#endregion
|
|
29430
29543
|
//#region packages/core/dist/analyze/segment-impact-input.js
|
|
29431
|
-
const DAY_MS = 864e5;
|
|
29544
|
+
const DAY_MS$1 = 864e5;
|
|
29432
29545
|
const MAX_WINDOW_DAYS = 240;
|
|
29433
29546
|
function subtractDays(value, days) {
|
|
29434
29547
|
const date = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
|
|
@@ -29436,7 +29549,7 @@ function subtractDays(value, days) {
|
|
|
29436
29549
|
return date.toISOString().slice(0, 10);
|
|
29437
29550
|
}
|
|
29438
29551
|
function segmentRangeDays(range) {
|
|
29439
|
-
return Math.floor((Date.parse(`${range.endDate}T00:00:00.000Z`) - Date.parse(`${range.startDate}T00:00:00.000Z`)) / DAY_MS) + 1;
|
|
29552
|
+
return Math.floor((Date.parse(`${range.endDate}T00:00:00.000Z`) - Date.parse(`${range.startDate}T00:00:00.000Z`)) / DAY_MS$1) + 1;
|
|
29440
29553
|
}
|
|
29441
29554
|
function segmentComparisonRange(after, compareDays) {
|
|
29442
29555
|
const endDate = subtractDays(after.startDate, 1);
|
|
@@ -29657,9 +29770,10 @@ function delimiterCount(line, delimiter) {
|
|
|
29657
29770
|
let quoted = false;
|
|
29658
29771
|
for (let index = 0; index < line.length; index += 1) {
|
|
29659
29772
|
const character = line[index];
|
|
29660
|
-
if (character === "\"")
|
|
29661
|
-
|
|
29662
|
-
|
|
29773
|
+
if (character === "\"") {
|
|
29774
|
+
if (quoted && line[index + 1] === "\"") index += 1;
|
|
29775
|
+
else quoted = !quoted;
|
|
29776
|
+
} else if (!quoted && character === delimiter) count += 1;
|
|
29663
29777
|
}
|
|
29664
29778
|
return count;
|
|
29665
29779
|
}
|
|
@@ -29686,9 +29800,10 @@ function decodeText(decoder, chunk, stream, label) {
|
|
|
29686
29800
|
async function detectCsvDelimiter(path) {
|
|
29687
29801
|
const handle = await open$1(path, "r");
|
|
29688
29802
|
try {
|
|
29689
|
-
const buffer = Buffer.alloc(
|
|
29803
|
+
const buffer = Buffer.alloc(65536);
|
|
29690
29804
|
const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
|
|
29691
|
-
const
|
|
29805
|
+
const encoding = await detectTextEncoding(path);
|
|
29806
|
+
const firstRecord = new TextDecoder$1(encoding).decode(buffer.subarray(0, bytesRead)).split(/\r?\n/u, 1)[0]?.replace(/^\uFEFF/u, "");
|
|
29692
29807
|
if (!firstRecord) return ",";
|
|
29693
29808
|
const candidates = [
|
|
29694
29809
|
",",
|
|
@@ -29727,9 +29842,10 @@ async function* csvRecords(input) {
|
|
|
29727
29842
|
quoted = false;
|
|
29728
29843
|
pendingQuote = false;
|
|
29729
29844
|
}
|
|
29730
|
-
if (quoted)
|
|
29731
|
-
|
|
29732
|
-
|
|
29845
|
+
if (quoted) {
|
|
29846
|
+
if (character === "\"") pendingQuote = true;
|
|
29847
|
+
else field += character;
|
|
29848
|
+
} else if (character === "\"" && field.length === 0) quoted = true;
|
|
29733
29849
|
else if (character === delimiter) {
|
|
29734
29850
|
record.push(field);
|
|
29735
29851
|
field = "";
|
|
@@ -32803,7 +32919,7 @@ const INCIDENTS_URL = "https://status.search.google.com/incidents.json";
|
|
|
32803
32919
|
async function fetchSearchStatusIncidents() {
|
|
32804
32920
|
const response = await fetch$1(INCIDENTS_URL, { signal: AbortSignal.timeout(8e3) });
|
|
32805
32921
|
if (!response.ok) throw new SeoError("OPTIONAL_PROVIDER_UNAVAILABLE", `Google Search Status fetch failed with ${response.status}.`);
|
|
32806
|
-
return readJson(response, "Google Search Status", { maxBytes:
|
|
32922
|
+
return readJson(response, "Google Search Status", { maxBytes: 10485760 });
|
|
32807
32923
|
}
|
|
32808
32924
|
async function listSearchUpdates(input = {}) {
|
|
32809
32925
|
return searchUpdatesFromIncidents(withRankingHistory(await fetchSearchStatusIncidents()), input);
|
|
@@ -32865,7 +32981,7 @@ function anomalyEvidence(anomaly) {
|
|
|
32865
32981
|
if (anomaly.direction === "normal") return `${formatMetric(anomaly.metric)} changed ${changePhrase} (${anomaly.baselineMean.toLocaleString("en-GB")} -> ${anomaly.comparisonMean.toLocaleString("en-GB")} per observed day${anomaly.zScore === null ? "; the baseline had no observed variance" : `, z ${anomaly.zScore}`}).`;
|
|
32866
32982
|
return `${formatMetric(anomaly.metric)} ${direction} ${changePhrase} (${anomaly.baselineMean.toLocaleString("en-GB")} -> ${anomaly.comparisonMean.toLocaleString("en-GB")} per observed day${anomaly.zScore === null ? "; outside the flat observed baseline" : `, z ${anomaly.zScore}`}).`;
|
|
32867
32983
|
}
|
|
32868
|
-
function plural$
|
|
32984
|
+
function plural$5(count, singular, pluralLabel = `${singular}s`) {
|
|
32869
32985
|
return count === 1 ? singular : pluralLabel;
|
|
32870
32986
|
}
|
|
32871
32987
|
function strongestSignal(anomalies) {
|
|
@@ -32921,13 +33037,13 @@ function interpretUpdateCorrelation(input) {
|
|
|
32921
33037
|
summary,
|
|
32922
33038
|
evidence: [
|
|
32923
33039
|
...input.anomalies.map(anomalyEvidence),
|
|
32924
|
-
hasUpdate ? `${input.overlappingUpdates.length} official Google Ranking update ${plural$
|
|
33040
|
+
hasUpdate ? `${input.overlappingUpdates.length} official Google Ranking update ${plural$5(input.overlappingUpdates.length, "window")} overlapped the change date or comparison window: ${updateNames.join(", ")}.` : "No official Google Ranking update windows overlapped the change date or comparison window.",
|
|
32925
33041
|
largeMovement ? "Both clicks and impressions moved sharply in the same direction." : "Clicks and impressions did not both meet the sharp-movement evidence threshold.",
|
|
32926
33042
|
hasConfounders ? `Known overlapping site changes: ${confounders.map((confounder) => confounder.title).join("; ")}.` : "No overlapping site changes were supplied."
|
|
32927
33043
|
],
|
|
32928
33044
|
caveats: [
|
|
32929
33045
|
`GSC window: ${input.days} days; recent comparison window: ${input.recentDays} days.`,
|
|
32930
|
-
`Update overlap padding: ${input.paddingDays} ${plural$
|
|
33046
|
+
`Update overlap padding: ${input.paddingDays} ${plural$5(input.paddingDays, "day")} either side of the step-change date, or of the recent comparison window when no step change was found.`,
|
|
32931
33047
|
input.refresh ? "Data freshness: cache bypassed for GSC data." : "Data freshness: local GSC cache may have been used.",
|
|
32932
33048
|
"Source: official Google Search Status Dashboard Ranking incidents only; third-party volatility and unconfirmed chatter are not included.",
|
|
32933
33049
|
"An update-window overlap cannot establish causation, even when movement is large and no known site change was recorded.",
|
|
@@ -33077,7 +33193,7 @@ function analyzeTrafficAnomalyRows(input) {
|
|
|
33077
33193
|
const comparisonStart = shiftIsoDate(input.endDate, -(input.recentDays - 1));
|
|
33078
33194
|
const baselineEnd = shiftIsoDate(comparisonStart, -1);
|
|
33079
33195
|
const baselineExpectedDays = calendarDays(input.startDate, baselineEnd);
|
|
33080
|
-
if (comparisonStart < input.startDate || baselineExpectedDays < 14) throw new SeoError("INSUFFICIENT_DATA",
|
|
33196
|
+
if (comparisonStart < input.startDate || baselineExpectedDays < 14) throw new SeoError("INSUFFICIENT_DATA", `The date range needs at least ${input.recentDays + 14} days: 14 baseline days before the last ${input.recentDays}. Send a longer range, or leave the dates out for the default.`);
|
|
33081
33197
|
const aggregated = aggregateDailyRows({
|
|
33082
33198
|
rows: input.rows,
|
|
33083
33199
|
startDate: input.startDate,
|
|
@@ -33085,7 +33201,7 @@ function analyzeTrafficAnomalyRows(input) {
|
|
|
33085
33201
|
});
|
|
33086
33202
|
const baselineRows = aggregated.rows.filter((row) => (row.keys[0] ?? "") <= baselineEnd);
|
|
33087
33203
|
const comparisonRows = aggregated.rows.filter((row) => (row.keys[0] ?? "") >= comparisonStart);
|
|
33088
|
-
if (baselineRows.length < 14 || comparisonRows.length < 3) throw new SeoError("INSUFFICIENT_DATA", `Not enough
|
|
33204
|
+
if (baselineRows.length < 14 || comparisonRows.length < 3) throw new SeoError("INSUFFICIENT_DATA", `Not enough daily Search Console data to look for a drop: ${baselineRows.length} baseline days and ${comparisonRows.length} comparison days, and it needs 14 and 3. The site may be new or get too few clicks for daily rows.`);
|
|
33089
33205
|
const metrics = ["clicks", "impressions"];
|
|
33090
33206
|
const stepCaveats = [];
|
|
33091
33207
|
const anomalies = metrics.map((metric) => {
|
|
@@ -33095,7 +33211,7 @@ function analyzeTrafficAnomalyRows(input) {
|
|
|
33095
33211
|
if (step && changeDate) {
|
|
33096
33212
|
const previousDate = aggregated.rows[step.index - 1]?.keys[0];
|
|
33097
33213
|
const gap = previousDate ? calendarDays(previousDate, changeDate) - 2 : 0;
|
|
33098
|
-
stepCaveats.push(`${formatMetric(metric)} changed level on ${changeDate}, so its baseline is every observed day before that date and its comparison is every observed day from it.`, ...gap > 0 ? [`The ${metric} change date follows ${gap} missing ${plural$
|
|
33214
|
+
stepCaveats.push(`${formatMetric(metric)} changed level on ${changeDate}, so its baseline is every observed day before that date and its comparison is every observed day from it.`, ...gap > 0 ? [`The ${metric} change date follows ${gap} missing ${plural$5(gap, "day")}; the change may have started on one of them.`] : []);
|
|
33099
33215
|
return compareSegments({
|
|
33100
33216
|
site: input.site,
|
|
33101
33217
|
metric,
|
|
@@ -33126,9 +33242,9 @@ function analyzeTrafficAnomalyRows(input) {
|
|
|
33126
33242
|
const comparisonMissingDays = input.recentDays - comparisonRows.length;
|
|
33127
33243
|
const missingDays = expectedDays - aggregated.rows.length;
|
|
33128
33244
|
const caveats = [
|
|
33129
|
-
...missingDays > 0 ? [`${missingDays} requested calendar ${plural$
|
|
33130
|
-
...aggregated.invalidRows > 0 ? [`${aggregated.invalidRows} invalid provider ${plural$
|
|
33131
|
-
...aggregated.duplicateRows > 0 ? [`${aggregated.duplicateRows} duplicate date ${plural$
|
|
33245
|
+
...missingDays > 0 ? [`${missingDays} requested calendar ${plural$5(missingDays, "day")} had no returned date aggregate and ${missingDays === 1 ? "was" : "were"} not filled with zeros.`] : [],
|
|
33246
|
+
...aggregated.invalidRows > 0 ? [`${aggregated.invalidRows} invalid provider ${plural$5(aggregated.invalidRows, "row")} ${aggregated.invalidRows === 1 ? "was" : "were"} excluded.`] : [],
|
|
33247
|
+
...aggregated.duplicateRows > 0 ? [`${aggregated.duplicateRows} duplicate date ${plural$5(aggregated.duplicateRows, "row")} ${aggregated.duplicateRows === 1 ? "was" : "were"} aggregated before analysis.`] : [],
|
|
33132
33248
|
...stepCaveats
|
|
33133
33249
|
];
|
|
33134
33250
|
return {
|
|
@@ -33812,7 +33928,7 @@ var DecisionModelError = class extends Error {
|
|
|
33812
33928
|
const TYPESAFE_URL = "https://api.typesafe.ai/v1/systemone";
|
|
33813
33929
|
const JEV_PRICE_PER_MILLION = .042;
|
|
33814
33930
|
const REQUEST_TIMEOUT_MS = 6e4;
|
|
33815
|
-
const MAX_RESPONSE_BYTES =
|
|
33931
|
+
const MAX_RESPONSE_BYTES = 1048576;
|
|
33816
33932
|
function retryAfter(response) {
|
|
33817
33933
|
const value = Number(response.headers.get("retry-after"));
|
|
33818
33934
|
return Number.isFinite(value) && value > 0 ? Math.min(value, 30) * 1e3 : void 0;
|
|
@@ -34150,7 +34266,7 @@ function keyTerms(page) {
|
|
|
34150
34266
|
const title = page.title.replace(/\s+[|\u2013\u2014-]\s+[^|\u2013\u2014]*$/u, "");
|
|
34151
34267
|
for (const term of terms(page.description)) key.set(term, 1);
|
|
34152
34268
|
for (const term of terms(`${title} ${page.h1} ${lastSegmentWords(page.url)}`)) key.set(term, NAME_WEIGHT);
|
|
34153
|
-
for (const term of terms(siteName(page.url))) key.delete(term);
|
|
34269
|
+
for (const term of terms(siteName$1(page.url))) key.delete(term);
|
|
34154
34270
|
return key;
|
|
34155
34271
|
}
|
|
34156
34272
|
function lastSegmentWords(url) {
|
|
@@ -34160,7 +34276,7 @@ function lastSegmentWords(url) {
|
|
|
34160
34276
|
return "";
|
|
34161
34277
|
}
|
|
34162
34278
|
}
|
|
34163
|
-
function siteName(url) {
|
|
34279
|
+
function siteName$1(url) {
|
|
34164
34280
|
try {
|
|
34165
34281
|
return new URL(url).hostname.replace(/^www\./u, "").split(".")[0] ?? "";
|
|
34166
34282
|
} catch {
|
|
@@ -35037,15 +35153,15 @@ function internalLinksReportRange(input, fallbackDays, now) {
|
|
|
35037
35153
|
days: Math.round((Date.parse(`${endDate}T00:00:00Z`) - Date.parse(`${startDate}T00:00:00Z`)) / DAY$1) + 1
|
|
35038
35154
|
};
|
|
35039
35155
|
}
|
|
35040
|
-
const plural$
|
|
35156
|
+
const plural$4 = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
35041
35157
|
function internalLinksVerdict(report) {
|
|
35042
35158
|
const { counts } = report;
|
|
35043
35159
|
if (report.dataStatus === "blocked") return "robots.txt does not allow this crawler to read the site, so nothing was checked.";
|
|
35044
35160
|
if (report.dataStatus === "empty") return "No HTML page could be crawled, so there is nothing to link.";
|
|
35045
35161
|
if (report.dataStatus === "target-not-crawled") return "The target page could not be crawled as its own page (it failed, left the site, or names another page as canonical). Check it with seo page first.";
|
|
35046
35162
|
if (report.dataStatus === "target-not-linkable") return `The target is ${report.target?.noindex ? "noindex" : `a ${report.target?.type?.replaceAll("_", " ")} page`}, so no links to it are suggested.`;
|
|
35047
|
-
const judged = report.judge.status === "used" || report.judge.status === "partial" ? `${counts.strong} strong and ${counts.possible} possible link${counts.strong + counts.possible === 1 ? "" : "s"} judged by ${report.judge.model}${counts.heuristic ? `, plus ${plural$
|
|
35048
|
-
const scope = report.mode === "url" ? `to ${report.target?.url}` : `across ${plural$
|
|
35163
|
+
const judged = report.judge.status === "used" || report.judge.status === "partial" ? `${counts.strong} strong and ${counts.possible} possible link${counts.strong + counts.possible === 1 ? "" : "s"} judged by ${report.judge.model}${counts.heuristic ? `, plus ${plural$4(counts.heuristic, "heuristic link")} where a request failed` : ""}` : `${plural$4(counts.heuristic, "heuristic link")} (no decision model)`;
|
|
35164
|
+
const scope = report.mode === "url" ? `to ${report.target?.url}` : `across ${plural$4(counts.pagesCrawled, "page")}`;
|
|
35049
35165
|
const capped = report.crawl.capReached ? ` The crawl stopped at its limit of ${report.crawl.pageLimit} pages, so pages beyond it were not checked.` : "";
|
|
35050
35166
|
return `${judged} ${scope}${counts.heldBack ? `; ${counts.heldBack} held back by the evidence floors` : ""}.${capped}`;
|
|
35051
35167
|
}
|
|
@@ -36850,7 +36966,7 @@ async function runLighthouse(input) {
|
|
|
36850
36966
|
], {
|
|
36851
36967
|
env: lighthouseEnvironment(),
|
|
36852
36968
|
timeout: input.timeoutMs ?? 12e4,
|
|
36853
|
-
maxBuffer:
|
|
36969
|
+
maxBuffer: 31457280
|
|
36854
36970
|
});
|
|
36855
36971
|
const jsonStart = stdout.indexOf("{");
|
|
36856
36972
|
if (jsonStart < 0) throw new LighthouseRunError("invalid_result");
|
|
@@ -37483,14 +37599,14 @@ function* retainedQueryClusterRows(input) {
|
|
|
37483
37599
|
};
|
|
37484
37600
|
}
|
|
37485
37601
|
}
|
|
37486
|
-
function plural$
|
|
37602
|
+
function plural$3(count, singular, pluralLabel = `${singular}s`) {
|
|
37487
37603
|
return count === 1 ? singular : pluralLabel;
|
|
37488
37604
|
}
|
|
37489
37605
|
function reportVerdict(input) {
|
|
37490
37606
|
if (!input.clusters.length) return "No query clusters were generated for this scope.";
|
|
37491
37607
|
if (input.highOpportunityClusters > 0) {
|
|
37492
37608
|
const verb = input.highOpportunityClusters === 1 ? "has" : "have";
|
|
37493
|
-
return `${input.highOpportunityClusters} ${plural$
|
|
37609
|
+
return `${input.highOpportunityClusters} ${plural$3(input.highOpportunityClusters, "cluster")} ${verb} enough demand and weak enough performance to review first.`;
|
|
37494
37610
|
}
|
|
37495
37611
|
return "No obvious high-opportunity clusters were found. Use this report for content structure and intent mapping rather than urgent fixes.";
|
|
37496
37612
|
}
|
|
@@ -37631,7 +37747,7 @@ function movementLine(report) {
|
|
|
37631
37747
|
}
|
|
37632
37748
|
function countPhrase(count, singular, pluralLabel = `${singular}s`) {
|
|
37633
37749
|
if (count === 0) return `no ${pluralLabel}`;
|
|
37634
|
-
return `${count} ${plural$
|
|
37750
|
+
return `${count} ${plural$2(count, singular, pluralLabel)}`;
|
|
37635
37751
|
}
|
|
37636
37752
|
function headlineLine(report) {
|
|
37637
37753
|
const parts = [
|
|
@@ -37686,7 +37802,7 @@ function decayDiagnosisLabel(diagnosis) {
|
|
|
37686
37802
|
if (diagnosis === "lost_clicks") return "clicks dropped without one dominant signal";
|
|
37687
37803
|
return diagnosis.replaceAll("_", " ");
|
|
37688
37804
|
}
|
|
37689
|
-
function plural$
|
|
37805
|
+
function plural$2(count, singular, pluralLabel = `${singular}s`) {
|
|
37690
37806
|
return count === 1 ? singular : pluralLabel;
|
|
37691
37807
|
}
|
|
37692
37808
|
function decayClusterLine(report) {
|
|
@@ -37694,7 +37810,7 @@ function decayClusterLine(report) {
|
|
|
37694
37810
|
if (!group) return "No material decay cluster stood out.";
|
|
37695
37811
|
const diagnosis = decayDiagnosisLabel(group.diagnosis);
|
|
37696
37812
|
const samples = group.sampleQueries.slice(0, 2).join("; ");
|
|
37697
|
-
return `Top decay cluster: ${group.count} ${plural$
|
|
37813
|
+
return `Top decay cluster: ${group.count} ${plural$2(group.count, "finding")} in the ${group.template.label} template (${diagnosis}), ${group.totalClickLoss.toFixed(0)} fewer observed clicks across rows retained in both windows. Action: ${group.recommendation}${samples ? ` Example queries: ${samples}.` : ""}`;
|
|
37698
37814
|
}
|
|
37699
37815
|
function cannibalSuppressionLine(report) {
|
|
37700
37816
|
const suppressed = report.cannibalization.selection.suppressedQueries;
|
|
@@ -37712,21 +37828,21 @@ function contentOpportunityBullets(report) {
|
|
|
37712
37828
|
if (unavailableSections.length) bullets.push(`Could not assess ${unavailableSections.join(", ")} opportunities in this run; see report caveats.`);
|
|
37713
37829
|
if (report.summary.decayItems) {
|
|
37714
37830
|
const top = report.decay.items[0];
|
|
37715
|
-
bullets.push(top ? `${report.summary.decayItems} observed retained query/page ${plural$
|
|
37831
|
+
bullets.push(top ? `${report.summary.decayItems} observed retained query/page ${plural$2(report.summary.decayItems, "decline")} need review. Start with "${top.query}" on ${top.url}; it had ${top.clickLoss.toFixed(0)} fewer clicks.` : `${report.summary.decayItems} observed retained query/page ${plural$2(report.summary.decayItems, "decline")} need review.`);
|
|
37716
37832
|
bullets.push(decayClusterLine(report));
|
|
37717
37833
|
}
|
|
37718
37834
|
if (report.summary.cannibalItems) {
|
|
37719
37835
|
const top = report.cannibalization.items[0];
|
|
37720
|
-
bullets.push(top ? `${report.summary.cannibalItems} multi-URL query ${plural$
|
|
37836
|
+
bullets.push(top ? `${report.summary.cannibalItems} multi-URL query ${plural$2(report.summary.cannibalItems, "candidate")} need intent and technical review. Start with "${top.query}" and decide whether ${top.pages.length} ranking URLs answer the same intent.` : `${report.summary.cannibalItems} multi-URL query ${plural$2(report.summary.cannibalItems, "candidate")} need intent and technical review.`);
|
|
37721
37837
|
}
|
|
37722
37838
|
if (report.cannibalization.selection.suppressedQueries) bullets.push(cannibalSuppressionLine(report));
|
|
37723
37839
|
if (report.summary.strikingDistanceItems) {
|
|
37724
37840
|
const top = report.strikingDistance.items[0];
|
|
37725
|
-
bullets.push(top ? `${countLabel(report.summary.strikingDistanceItems, "query/page candidate")} ${plural$
|
|
37841
|
+
bullets.push(top ? `${countLabel(report.summary.strikingDistanceItems, "query/page candidate")} ${plural$2(report.summary.strikingDistanceItems, "has", "have")} an average GSC position above 10 and at most 20. Start by investigating "${top.query}" on ${top.url}; it averages position ${top.position.toFixed(1)} with ${top.impressions.toFixed(0)} impressions.` : `${countLabel(report.summary.strikingDistanceItems, "query/page candidate")} ${plural$2(report.summary.strikingDistanceItems, "has", "have")} an average GSC position above 10 and at most 20.`);
|
|
37726
37842
|
}
|
|
37727
37843
|
if (!skippedReason(report, "quick-win opportunities") && report.summary.quickWinItems) {
|
|
37728
37844
|
const top = report.quickWins.items[0];
|
|
37729
|
-
bullets.push(top ? `${report.summary.quickWinItems} retained query/page ${plural$
|
|
37845
|
+
bullets.push(top ? `${report.summary.quickWinItems} retained query/page ${plural$2(report.summary.quickWinItems, "candidate")} fell below a site-peer or versioned heuristic CTR target. Start with "${top.query}" on ${top.url}; it had ${top.impressions.toFixed(0)} impressions at average position ${top.position.toFixed(1)}.` : `${report.summary.quickWinItems} CTR-target ${plural$2(report.summary.quickWinItems, "candidate")} need review.`);
|
|
37730
37846
|
}
|
|
37731
37847
|
const templateLine = templateOpportunityLine(report);
|
|
37732
37848
|
if (!templateLine.startsWith("No dominant")) bullets.push(templateLine);
|
|
@@ -38086,10 +38202,10 @@ function applyVerification(item, coverage) {
|
|
|
38086
38202
|
function verdict(report) {
|
|
38087
38203
|
if (report.dataStatus === "empty") return "Google Search Console returned no retained query/page rows for this window.";
|
|
38088
38204
|
if (report.dataStatus === "filtered") return "No pages met the position, brand, and minimum-impression criteria.";
|
|
38089
|
-
if (report.technical > 0) return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.technical, "returned page")} ${plural$
|
|
38090
|
-
if (report.failed > 0) return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.failed, "returned page")} could not be verified and ${plural$
|
|
38091
|
-
if (report.content > 0) return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.content, "returned page")} ${plural$
|
|
38092
|
-
return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.returned, "page")} ${plural$
|
|
38205
|
+
if (report.technical > 0) return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.technical, "returned page")} ${plural$6(report.technical, "has", "have")} verified technical issues to fix before content changes.`;
|
|
38206
|
+
if (report.failed > 0) return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.failed, "returned page")} could not be verified and ${plural$6(report.failed, "needs", "need")} a fetch check before content changes.`;
|
|
38207
|
+
if (report.content > 0) return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.content, "returned page")} ${plural$6(report.content, "has", "have")} verified content or search-framing gaps.`;
|
|
38208
|
+
return `${countLabel(report.eligible, "eligible average-position page")} found; ${countLabel(report.returned, "page")} ${plural$6(report.returned, "is", "are")} returned in priority order for investigation.`;
|
|
38093
38209
|
}
|
|
38094
38210
|
function reportRecommendations(items) {
|
|
38095
38211
|
const first = items[0];
|
|
@@ -39204,7 +39320,7 @@ async function clickyDomain(site) {
|
|
|
39204
39320
|
}
|
|
39205
39321
|
//#endregion
|
|
39206
39322
|
//#region packages/core/dist/analyze/ai-queries.js
|
|
39207
|
-
const RULES
|
|
39323
|
+
const RULES = [
|
|
39208
39324
|
["agent_prompt", "^(search the web for|browse the web|find sources)|do not invent|return the [0-9]+ most relevant|include source urls|context: location|do not include location|question: |reply only with|the model you are using"],
|
|
39209
39325
|
["tracker", "\\. ?my location is |\\?\\. ?my( |$)|^evaluate the .+ on "],
|
|
39210
39326
|
["reply", "^(yes|yeah|yep|ok|okay|sure|yes please|go on|continue|keep going|tell me more|why not|how so|really|exactly|show me|and then|thanks|thank you|got it|what else|anything else)[?!.,]*$"],
|
|
@@ -39222,8 +39338,8 @@ const AI_QUERY_KINDS = {
|
|
|
39222
39338
|
chat: "chat phrasing, such as \"can you\" or \"should i\"",
|
|
39223
39339
|
long: "ten or more words with no other sign"
|
|
39224
39340
|
};
|
|
39225
|
-
const MATCHERS = RULES
|
|
39226
|
-
const AI_QUERY_PATTERN = RULES
|
|
39341
|
+
const MATCHERS = RULES.map(([kind, pattern]) => [kind, new RegExp(pattern)]);
|
|
39342
|
+
const AI_QUERY_PATTERN = RULES.map(([, pattern]) => `(?:${pattern})`).join("|");
|
|
39227
39343
|
const NOISE = [
|
|
39228
39344
|
["spaced_letters", /(^|\s)(\S\s){3,}\S(\s|$)/u],
|
|
39229
39345
|
["broken_encoding", /^(яю|ÿþ|þÿ)|&#[0-9]+;?|&[a-z]+;|[âÃÂ][\u0080-\u00bf€™œ“”]|\ufffd/u],
|
|
@@ -39797,15 +39913,15 @@ async function runRows(input, deps) {
|
|
|
39797
39913
|
};
|
|
39798
39914
|
}
|
|
39799
39915
|
const QUESTION_DAYS = 90;
|
|
39800
|
-
const list = (value) => Array.isArray(value) ? value : [];
|
|
39916
|
+
const list$1 = (value) => Array.isArray(value) ? value : [];
|
|
39801
39917
|
const urls = (items) => items.map((item) => item.url).filter((url) => typeof url === "string");
|
|
39802
39918
|
const overview = (result) => {
|
|
39803
|
-
const block = list(result.items).find((item) => item.type === "ai_overview");
|
|
39919
|
+
const block = list$1(result.items).find((item) => item.type === "ai_overview");
|
|
39804
39920
|
if (!block) return null;
|
|
39805
|
-
const parts = list(block.items);
|
|
39921
|
+
const parts = list$1(block.items);
|
|
39806
39922
|
return {
|
|
39807
39923
|
markdown: typeof block.markdown === "string" ? block.markdown : parts.map((part) => String(part.markdown ?? "")).join("\n"),
|
|
39808
|
-
sources: urls([...list(block.references), ...parts.flatMap((part) => list(part.references))]),
|
|
39924
|
+
sources: urls([...list$1(block.references), ...parts.flatMap((part) => list$1(part.references))]),
|
|
39809
39925
|
model: null
|
|
39810
39926
|
};
|
|
39811
39927
|
};
|
|
@@ -39821,7 +39937,7 @@ const ENGINES = [
|
|
|
39821
39937
|
}),
|
|
39822
39938
|
shown: (result) => {
|
|
39823
39939
|
const markdown = typeof result.markdown === "string" ? result.markdown : "";
|
|
39824
|
-
const sources = urls(list(result.sources));
|
|
39940
|
+
const sources = urls(list$1(result.sources));
|
|
39825
39941
|
if (!markdown && !sources.length) return null;
|
|
39826
39942
|
return {
|
|
39827
39943
|
markdown,
|
|
@@ -40400,7 +40516,7 @@ async function analyticsBeside(access, site, range, before, pages) {
|
|
|
40400
40516
|
//#region packages/core/dist/commands/audit.js
|
|
40401
40517
|
const AUDIT_SECTION = "weekly-audit";
|
|
40402
40518
|
const AUDIT_SECTION_TEXT = "What the weekly crawl of the site found (broken and redirected internal links, missing or duplicate titles, descriptions and H1s, noindex, canonicals to another page, sitemap URLs that do not return 200, thin pages), with what is new, back or resolved since the crawl before. Only for sites added to the weekly site audit beta.";
|
|
40403
|
-
const
|
|
40519
|
+
const AUDIT_RULES = {
|
|
40404
40520
|
link_to_error: "Internal links to a page that returns an error",
|
|
40405
40521
|
link_to_redirect: "Internal links to a redirect",
|
|
40406
40522
|
link_failed: "Internal links to a page that could not be fetched",
|
|
@@ -40557,7 +40673,7 @@ function runAuditReport(input, snapshot, call) {
|
|
|
40557
40673
|
text: [
|
|
40558
40674
|
head,
|
|
40559
40675
|
indexText,
|
|
40560
|
-
byRule.length ? ["finding | open | what it is", ...byRule.map(([rule, count]) => `${rule} | ${count} | ${
|
|
40676
|
+
byRule.length ? ["finding | open | what it is", ...byRule.map(([rule, count]) => `${rule} | ${count} | ${AUDIT_RULES[rule] ?? rule}`)].join("\n") : "No findings in this crawl.",
|
|
40561
40677
|
fresh.length ? `New, back or resolved this week, 1 to ${Math.min(SUMMARY_ROWS$1, fresh.length)} of ${fresh.length}:\n${table(fresh.slice(0, SUMMARY_ROWS$1), origin, since)}` : previous ? "Nothing new, back or resolved since the crawl before." : null,
|
|
40562
40678
|
changes.compared ? `Between the two crawls: ${changes.new_urls} new URLs, ${changes.gone_urls} gone, ${changes.status_changed} changed status, ${changes.title_changed} changed title.` : null,
|
|
40563
40679
|
`More: ${call("report", {
|
|
@@ -40582,9 +40698,9 @@ function auditPreview(snapshot) {
|
|
|
40582
40698
|
const index = snapshot.index_changes;
|
|
40583
40699
|
return `${index && (index.dropped || index.returned) ? `${index.dropped} URLs dropped out of Google's index this week and ${index.returned} came back. ` : ""}Last crawl ${day$1(snapshot.finished_at)}: ${findings.open} open findings, ${findings.new + findings.reopened} new or back, ${findings.resolved} resolved.`;
|
|
40584
40700
|
}
|
|
40585
|
-
const WEEK_MS =
|
|
40701
|
+
const WEEK_MS = 6048e5;
|
|
40586
40702
|
const day = (ms) => ms === null ? "" : new Date(ms).toISOString().slice(0, 10);
|
|
40587
|
-
const count$
|
|
40703
|
+
const count$2 = (value) => value.toLocaleString("en-US");
|
|
40588
40704
|
function relative$1(value, origin) {
|
|
40589
40705
|
if (!value) return "";
|
|
40590
40706
|
return origin && value.startsWith(origin) ? value.slice(origin.length) || "/" : value;
|
|
@@ -40605,7 +40721,7 @@ function rowsTable(rows, checks) {
|
|
|
40605
40721
|
changed(row) ? row.prev_coverage ?? "" : "",
|
|
40606
40722
|
changed(row) ? day(row.changed_at) : "",
|
|
40607
40723
|
day(row.checked_at),
|
|
40608
|
-
`${count$
|
|
40724
|
+
`${count$2(row.clicks)} (${count$2(row.previous_clicks)})${row.lost ? " lost" : ""}`,
|
|
40609
40725
|
row.in_sitemap ? "yes" : "no",
|
|
40610
40726
|
row.google_canonical && row.google_canonical !== row.url ? relative$1(row.google_canonical, checks.origin) : "",
|
|
40611
40727
|
row.error ?? ""
|
|
@@ -40613,12 +40729,12 @@ function rowsTable(rows, checks) {
|
|
|
40613
40729
|
}
|
|
40614
40730
|
function head(site, checks) {
|
|
40615
40731
|
const { queued } = checks;
|
|
40616
|
-
const quota = checks.properties.map((item) => `${item.property} (${count$
|
|
40732
|
+
const quota = checks.properties.map((item) => `${item.property} (${count$2(item.urls)} URLs: ${count$2(item.top)} top pages checked daily, the rest every ${item.cycle_days === 1 ? "day" : `${item.cycle_days} days`}; ${count$2(item.used_today)} of ${count$2(checks.per_day)} checks used today)`).join(", ");
|
|
40617
40733
|
return [
|
|
40618
40734
|
`Google indexing of ${site}, from the URL Inspection results this server keeps for it (as of ${new Date(checks.as_of).toISOString().slice(0, 16).replace("T", " ")} UTC).`,
|
|
40619
|
-
checks.dropped_this_week || checks.returned_this_week ? `In the last 7 days ${count$
|
|
40620
|
-
`Covered: ${count$
|
|
40621
|
-
queued.total ? `Queued: ${count$
|
|
40735
|
+
checks.dropped_this_week || checks.returned_this_week ? `In the last 7 days ${count$2(checks.dropped_this_week)} ${checks.dropped_this_week === 1 ? "URL" : "URLs"} dropped out of Google's index and ${count$2(checks.returned_this_week)} came back; they are listed first. A top page's drop counts only after a second check an hour later.` : null,
|
|
40736
|
+
`Covered: ${count$2(checks.covered)} of ${count$2(checks.known)} known URLs have a current result. Known URLs are the sitemap's, the crawl's and the Search Console pages with clicks or impressions. Each property spends its full ${count$2(checks.per_day)} checks a day: its top pages (lost clicks, then clicks, then impressions, up to ${count$2(checks.top_per_day)}) daily, the rest as often as the quota allows, and a page the weekly crawl saw change at once.`,
|
|
40737
|
+
queued.total ? `Queued: ${count$2(queued.total)} (${count$2(queued.lost)} pages that lost their clicks, ${count$2(queued.search)} with clicks or impressions, ${count$2(queued.sitemap)} sitemap URLs never checked, ${count$2(queued.stale)} older or changed), checked in that order. Time left: ${etaText(checks.eta_hours)}, at up to ${count$2(checks.per_day)} checks a day per property, spread over the day.` : "Queued: nothing; every known URL has a current result.",
|
|
40622
40738
|
quota ? `Checked through ${quota}.` : null,
|
|
40623
40739
|
checks.stopped ? `Checks stopped early: ${checks.stopped}` : null,
|
|
40624
40740
|
"A URL without a result has none here, so this is not an all-clear for it."
|
|
@@ -40627,9 +40743,9 @@ function head(site, checks) {
|
|
|
40627
40743
|
function suggestionsText(checks) {
|
|
40628
40744
|
if (!checks.suggestions.length) return null;
|
|
40629
40745
|
return [
|
|
40630
|
-
`The sitemap has more URLs than these properties can check every 7 days. Each Search Console property gets its own ${count$
|
|
40746
|
+
`The sitemap has more URLs than these properties can check every 7 days. Each Search Console property gets its own ${count$2(checks.per_day)} checks a day, so adding these folders as URL-prefix properties (on the same Google account) would check more:`,
|
|
40631
40747
|
"property to add | sitemap URLs in it | more URLs checked a week",
|
|
40632
|
-
...checks.suggestions.map((item) => `${item.property} | ${count$
|
|
40748
|
+
...checks.suggestions.map((item) => `${item.property} | ${count$2(item.urls)} | ${count$2(item.gain)}`),
|
|
40633
40749
|
"The next day the checks find a new property in Search Console and use its quota for the URLs in that folder."
|
|
40634
40750
|
].join("\n");
|
|
40635
40751
|
}
|
|
@@ -40644,7 +40760,7 @@ function runAuditChecks(input, checks, call) {
|
|
|
40644
40760
|
data: checks
|
|
40645
40761
|
};
|
|
40646
40762
|
if (!checks.started) return {
|
|
40647
|
-
text: `${site} is in the weekly site audit, and its Google checks are starting now: pages that lost their clicks first, then pages by clicks and impressions, then sitemap URLs. ${checks.known ? `${count$
|
|
40763
|
+
text: `${site} is in the weekly site audit, and its Google checks are starting now: pages that lost their clicks first, then pages by clicks and impressions, then sitemap URLs. ${checks.known ? `${count$2(checks.known)} URLs are known so far. ` : ""}Run ${call("index", { site })} again in a few minutes for the coverage and the time left.`,
|
|
40648
40764
|
data: checks
|
|
40649
40765
|
};
|
|
40650
40766
|
const more = (offset) => input.paged ? `More: ${call("index", {
|
|
@@ -40668,7 +40784,7 @@ function runAuditChecks(input, checks, call) {
|
|
|
40668
40784
|
const reasons = checks.reasons.length ? [
|
|
40669
40785
|
"Google's reason at each URL's latest check:",
|
|
40670
40786
|
"reason | verdict | urls | changed to it this week",
|
|
40671
|
-
...checks.reasons.map((item) => `${item.coverage ?? ""} | ${item.verdict ?? ""} | ${count$
|
|
40787
|
+
...checks.reasons.map((item) => `${item.coverage ?? ""} | ${item.verdict ?? ""} | ${count$2(item.urls)} | ${count$2(item.changed_this_week)}`)
|
|
40672
40788
|
].join("\n") : "No URL has a result yet.";
|
|
40673
40789
|
const shown = checks.rows.slice(0, 20);
|
|
40674
40790
|
return {
|
|
@@ -41078,13 +41194,13 @@ function clickyRange(input) {
|
|
|
41078
41194
|
endDate: input.endDate
|
|
41079
41195
|
};
|
|
41080
41196
|
}
|
|
41081
|
-
const count = (item) => {
|
|
41197
|
+
const count$1 = (item) => {
|
|
41082
41198
|
const value = Number(item.value);
|
|
41083
41199
|
return Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
41084
41200
|
};
|
|
41085
41201
|
const totals = (items) => items.map((item) => ({
|
|
41086
41202
|
name: item.title ?? "",
|
|
41087
|
-
visits: count(item)
|
|
41203
|
+
visits: count$1(item)
|
|
41088
41204
|
})).filter((item) => Boolean(item.name) && item.visits !== null);
|
|
41089
41205
|
const line = (items) => {
|
|
41090
41206
|
const top = items.slice(0, 10).map((item) => `${item.name} ${item.visits}`);
|
|
@@ -41115,7 +41231,7 @@ async function runClickyRows(input, keys, options) {
|
|
|
41115
41231
|
const entrances = stats["pages-entrance"] ?? [];
|
|
41116
41232
|
const visitsByPage = /* @__PURE__ */ new Map();
|
|
41117
41233
|
for (const item of entrances) {
|
|
41118
|
-
const visits = count(item);
|
|
41234
|
+
const visits = count$1(item);
|
|
41119
41235
|
if (visits === null || !item.url) continue;
|
|
41120
41236
|
let page;
|
|
41121
41237
|
try {
|
|
@@ -41166,7 +41282,7 @@ async function runClickyRows(input, keys, options) {
|
|
|
41166
41282
|
const DR_ATTRIBUTION = "domain_rating: Domain Rating by Ahrefs (https://ahrefs.com/).";
|
|
41167
41283
|
const ENDPOINT = "https://api.ahrefs.com/v3/public/domain-rating-free";
|
|
41168
41284
|
const MAX_DOMAINS = 25;
|
|
41169
|
-
const TTL_SECONDS =
|
|
41285
|
+
const TTL_SECONDS = 86400;
|
|
41170
41286
|
const DOMAIN_FIELDS = [
|
|
41171
41287
|
"domain",
|
|
41172
41288
|
"competitor_domain",
|
|
@@ -41273,14 +41389,14 @@ const samePath = (a, b) => {
|
|
|
41273
41389
|
return from.pathname === to.pathname && from.search === to.search;
|
|
41274
41390
|
};
|
|
41275
41391
|
const authPath = (url) => AUTH_SEGMENTS.has(new URL(url).pathname.split("/")[1]?.toLowerCase() ?? "");
|
|
41276
|
-
const plural = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
41392
|
+
const plural$1 = (count, word) => `${count} ${word}${count === 1 ? "" : "s"}`;
|
|
41277
41393
|
function labelOf(e) {
|
|
41278
41394
|
const { url, status, live } = e;
|
|
41279
41395
|
const { first, hops, last } = live;
|
|
41280
41396
|
const indexed = status.verdict === "PASS";
|
|
41281
41397
|
const coverage = status.coverage ?? "";
|
|
41282
41398
|
const referring = status.referring_urls.filter((item) => item !== url && sameSite(item, url) && !samePath(item, url));
|
|
41283
|
-
const pointers = [e.inSitemap ? "the sitemap lists it" : null, referring.length ? `Google lists ${plural(referring.length, "referring page")} on this site as of its last crawl (${referring[0]}${referring.length > 1 ? ", and more" : ""})` : null].filter(Boolean);
|
|
41399
|
+
const pointers = [e.inSitemap ? "the sitemap lists it" : null, referring.length ? `Google lists ${plural$1(referring.length, "referring page")} on this site as of its last crawl (${referring[0]}${referring.length > 1 ? ", and more" : ""})` : null].filter(Boolean);
|
|
41284
41400
|
if (first.error) return indexed ? {
|
|
41285
41401
|
label: "indexed",
|
|
41286
41402
|
why: `Google indexes it. The live check failed (${first.error}).`
|
|
@@ -41562,20 +41678,20 @@ function indexingText(site, run, page, origin, askMore, now) {
|
|
|
41562
41678
|
const sources = [
|
|
41563
41679
|
`lost-click pages ${n(known.lostClicks)}`,
|
|
41564
41680
|
`Search Console pages with impressions in the last 28 days ${n(known.searchConsole)}${known.searchConsoleCapped ? ", capped" : ""}`,
|
|
41565
|
-
`sitemap ${n(known.sitemap.urls.length)} from ${plural(known.sitemap.files, "file")}${known.sitemap.partial ? ", partial" : ""}`
|
|
41681
|
+
`sitemap ${n(known.sitemap.urls.length)} from ${plural$1(known.sitemap.files, "file")}${known.sitemap.partial ? ", partial" : ""}`
|
|
41566
41682
|
];
|
|
41567
41683
|
const lowerBound = known.sitemap.partial || known.searchConsoleCapped ? " at least" : "";
|
|
41568
41684
|
const asked = run.inspected - run.fromSaved;
|
|
41569
41685
|
const most = Math.min(total, MAX_INSPECT_LIMIT, run.quota ? run.inspected + run.quota.limit - run.quota.used - asked : MAX_INSPECT_LIMIT);
|
|
41570
41686
|
const days = run.oldestSaved ? Math.floor((now.getTime() - Date.parse(run.oldestSaved)) / 864e5) : 0;
|
|
41571
|
-
const savedNote = run.fromSaved ? ` (${n(asked)} asked of Google now, ${n(run.fromSaved)} from saved results; the oldest was inspected ${run.oldestSaved?.slice(0, 16).replace("T", " ")} UTC, ${days === 0 ? "under a day" : plural(days, "day")} ago. Saved results are reused for 7 days)` : "";
|
|
41687
|
+
const savedNote = run.fromSaved ? ` (${n(asked)} asked of Google now, ${n(run.fromSaved)} from saved results; the oldest was inspected ${run.oldestSaved?.slice(0, 16).replace("T", " ")} UTC, ${days === 0 ? "under a day" : plural$1(days, "day")} ago. Saved results are reused for 7 days)` : "";
|
|
41572
41688
|
const stop = run.stoppedBy === "quota" ? "The URL Inspection quota stopped it." : run.stoppedBy === "limit" ? `It stopped at ${n(run.limit)}, the number of inspections for this run${askMore && most > run.limit ? `; to inspect more, up to the quota left today: ${askMore(most)}` : ""}.` : "Every known URL has a result.";
|
|
41573
41689
|
const lines = [
|
|
41574
41690
|
`Google's indexing reasons for ${site}, from URL Inspection. Search Console's Page indexing report has no API, so known URLs are inspected one at a time, in a fixed order (lost-click pages, Search Console pages by clicks then impressions, sitemap URLs, then the rest), and checked live from here.`,
|
|
41575
41691
|
`Known URLs:${lowerBound} ${n(total)} (${sources.join("; ")}). Inspected ${n(run.inspected)} of ${n(total)}${savedNote}. ${stop}${notInspected > 0 ? ` The ${n(notInspected)} URLs not inspected have no result here, so this is not an all-clear for them.` : ""}${known.sitemap.notes.length ? ` Sitemap: ${known.sitemap.notes.join("; ")}.` : ""}`,
|
|
41576
41692
|
run.quota ? `URL Inspection quota: this machine had used ${n(run.quota.used)} of ${n(run.quota.limit)} today for this property before the run. Google also counts inspections from other tools.` : "URL Inspection quota: not counted on this server; Google stops inspections at 2,000 a day per property."
|
|
41577
41693
|
];
|
|
41578
|
-
if (run.failed.length) lines.push(`URL Inspection failed for ${plural(run.failed.length, "URL")}: ${run.failed.slice(0, 5).map((item) => `${item.url} (${item.error})`).join("; ")}${run.failed.length > 5 ? "; and more" : ""}.`);
|
|
41694
|
+
if (run.failed.length) lines.push(`URL Inspection failed for ${plural$1(run.failed.length, "URL")}: ${run.failed.slice(0, 5).map((item) => `${item.url} (${item.error})`).join("; ")}${run.failed.length > 5 ? "; and more" : ""}.`);
|
|
41579
41695
|
const groups = byReason(run.rows);
|
|
41580
41696
|
if (groups.length) lines.push(`By Google's reason, with labels from the rules below (not Google's):\n${table$1(groups, [
|
|
41581
41697
|
"reason",
|
|
@@ -42669,10 +42785,10 @@ function markdownText(markdown, url) {
|
|
|
42669
42785
|
return `Main content as Markdown (live page${markdown.truncated ? `, cut to ${markdown.markdown.length.toLocaleString("en-US")} of ${markdown.characters.toLocaleString("en-US")} characters` : ""}):\n\n${markdown.markdown}`;
|
|
42670
42786
|
}
|
|
42671
42787
|
async function runCompare(input, deps) {
|
|
42672
|
-
if (
|
|
42788
|
+
if (!realIsoDate(input.date)) throw new CommandError("INVALID_INPUT", "The date must be a real day as YYYY-MM-DD.");
|
|
42673
42789
|
const last = latestFinalGscDate(deps.now?.() ?? /* @__PURE__ */ new Date());
|
|
42674
42790
|
const daysAfter = Math.round((Date.parse(last) - Date.parse(input.date)) / 864e5) + 1;
|
|
42675
|
-
if (daysAfter < 3) throw new CommandError("INVALID_INPUT", `Search Console has final data to ${last}
|
|
42791
|
+
if (daysAfter < 3) throw new CommandError("INVALID_INPUT", `Search Console has final data to ${last}, and a comparison needs 3 days after the change. The latest date that works is ${shiftIsoDate(last, -2)}.`);
|
|
42676
42792
|
const days = Math.min(28, daysAfter);
|
|
42677
42793
|
const after = {
|
|
42678
42794
|
startDate: input.date,
|
|
@@ -42900,11 +43016,176 @@ function telemetryReportFor(command, args = {}) {
|
|
|
42900
43016
|
}[command] ?? null;
|
|
42901
43017
|
}
|
|
42902
43018
|
//#endregion
|
|
43019
|
+
//#region packages/core/dist/commands/week.js
|
|
43020
|
+
const DAY_MS = 864e5;
|
|
43021
|
+
function weekLabel(start, end) {
|
|
43022
|
+
const parts = (date) => {
|
|
43023
|
+
const value = /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
|
|
43024
|
+
return {
|
|
43025
|
+
day: value.getUTCDate(),
|
|
43026
|
+
month: value.toLocaleString("en-GB", {
|
|
43027
|
+
month: "short",
|
|
43028
|
+
timeZone: "UTC"
|
|
43029
|
+
})
|
|
43030
|
+
};
|
|
43031
|
+
};
|
|
43032
|
+
const from = parts(start);
|
|
43033
|
+
const to = parts(end);
|
|
43034
|
+
return from.month === to.month ? `${from.day} to ${to.day} ${to.month}` : `${from.day} ${from.month} to ${to.day} ${to.month}`;
|
|
43035
|
+
}
|
|
43036
|
+
const weekTitle = (data) => `Your SEO Skill week, ${weekLabel(data.start, data.end)}`;
|
|
43037
|
+
const siteName = (property) => property.replace(/^sc-domain:|^https?:\/\//, "").replace(/\/$/, "");
|
|
43038
|
+
const count = (n) => n.toLocaleString("en-US");
|
|
43039
|
+
const plural = (n, one, many = `${one}s`) => `${count(n)} ${n === 1 ? one : many}`;
|
|
43040
|
+
const list = (items) => items.length <= 1 ? items[0] ?? "" : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
|
|
43041
|
+
function path(url) {
|
|
43042
|
+
try {
|
|
43043
|
+
const parsed = new URL(url);
|
|
43044
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
43045
|
+
} catch {
|
|
43046
|
+
return url;
|
|
43047
|
+
}
|
|
43048
|
+
}
|
|
43049
|
+
function clicksChange(site) {
|
|
43050
|
+
const clicks = site.clicks;
|
|
43051
|
+
if (!clicks) return null;
|
|
43052
|
+
const change = clicks.clicks - clicks.previous;
|
|
43053
|
+
if (Math.abs(change) < 50) return null;
|
|
43054
|
+
if (change < 0 && clicks.previous >= 100 && -change >= .3 * clicks.previous) return "fell";
|
|
43055
|
+
if (change > 0 && clicks.previous >= 50 && change >= .3 * clicks.previous) return "rose";
|
|
43056
|
+
return null;
|
|
43057
|
+
}
|
|
43058
|
+
const percent = (site) => {
|
|
43059
|
+
const clicks = site.clicks;
|
|
43060
|
+
return Math.round(Math.abs(clicks.clicks - clicks.previous) / clicks.previous * 100);
|
|
43061
|
+
};
|
|
43062
|
+
function issues(site, startMs, endMs) {
|
|
43063
|
+
const name = siteName(site.property);
|
|
43064
|
+
const found = [];
|
|
43065
|
+
const index = site.index;
|
|
43066
|
+
if (index?.dropped) {
|
|
43067
|
+
const paths = index.dropped_pages.map((page) => path(page.url));
|
|
43068
|
+
const more = index.dropped - paths.length;
|
|
43069
|
+
const shown = more > 0 ? `${paths.join(", ")} and ${plural(more, "more")}` : list(paths);
|
|
43070
|
+
const reasons = new Set(index.dropped_pages.map((page) => page.coverage));
|
|
43071
|
+
const reason = reasons.size === 1 ? [...reasons][0] : null;
|
|
43072
|
+
found.push({
|
|
43073
|
+
rank: 0,
|
|
43074
|
+
heading: `${plural(index.dropped, "page")} dropped`,
|
|
43075
|
+
line: `${shown} dropped out of Google’s index.${reason ? ` Google says: ${reason}.` : ""}`,
|
|
43076
|
+
next: `check ${index.dropped === 1 ? "it" : "they"} still return${index.dropped === 1 ? "s" : ""} 200 and ${index.dropped === 1 ? "is" : "are"} not noindexed.`,
|
|
43077
|
+
prompt: `Why did ${paths[0] ?? "a page"} on ${name} drop out of Google’s index this week, and how do I fix it?`
|
|
43078
|
+
});
|
|
43079
|
+
}
|
|
43080
|
+
const crawl = site.crawl;
|
|
43081
|
+
const crawled = crawl !== null && crawl.finished_at >= startMs && crawl.finished_at < endMs;
|
|
43082
|
+
if (crawled && crawl.status === "failed") found.push({
|
|
43083
|
+
rank: 1,
|
|
43084
|
+
heading: "crawl stopped early",
|
|
43085
|
+
line: `The weekly crawl stopped after ${plural(crawl.pages, "page")}${crawl.error ? `: ${crawl.error}` : "."}`,
|
|
43086
|
+
next: "check the site is up. The next weekly crawl tries again.",
|
|
43087
|
+
prompt: `Why did the weekly crawl of ${name} stop early, and what should I check?`
|
|
43088
|
+
});
|
|
43089
|
+
else if (!crawled && site.added_at < startMs) found.push({
|
|
43090
|
+
rank: 1,
|
|
43091
|
+
heading: "no crawl this week",
|
|
43092
|
+
line: `No weekly crawl finished this week${site.start_error ? `: ${site.start_error}` : "."}`,
|
|
43093
|
+
next: "check the site is up. The crawl tries again each hour.",
|
|
43094
|
+
prompt: `Why has the weekly crawl of ${name} not finished, and what should I check?`
|
|
43095
|
+
});
|
|
43096
|
+
if (clicksChange(site) === "fell") {
|
|
43097
|
+
const clicks = site.clicks;
|
|
43098
|
+
found.push({
|
|
43099
|
+
rank: 2,
|
|
43100
|
+
heading: `clicks down ${percent(site)}%`,
|
|
43101
|
+
line: `Search clicks fell ${percent(site)}%, from ${count(clicks.previous)} to ${count(clicks.clicks)} (${weekLabel(clicks.start, clicks.end)}, against the 7 days before).`,
|
|
43102
|
+
next: "ask your agent which pages and queries lost them.",
|
|
43103
|
+
prompt: `Which pages and queries lost search clicks on ${name} in the last week, and why?`
|
|
43104
|
+
});
|
|
43105
|
+
}
|
|
43106
|
+
if (crawled && crawl.new_issues > 0) {
|
|
43107
|
+
const rule = crawl.top_rule ? AUDIT_RULES[crawl.top_rule] : void 0;
|
|
43108
|
+
found.push({
|
|
43109
|
+
rank: 3,
|
|
43110
|
+
heading: plural(crawl.new_issues, "new issue"),
|
|
43111
|
+
line: `The weekly crawl found ${plural(crawl.new_issues, "new issue")}${rule ? `, most of them ${rule.charAt(0).toLowerCase()}${rule.slice(1)}` : ""}.`,
|
|
43112
|
+
next: "ask your agent for the weekly audit of this site.",
|
|
43113
|
+
prompt: `What did the weekly crawl of ${name} find this week, and what should I fix first?`
|
|
43114
|
+
});
|
|
43115
|
+
}
|
|
43116
|
+
return found;
|
|
43117
|
+
}
|
|
43118
|
+
function weekMarkdown(data) {
|
|
43119
|
+
const startMs = Date.parse(`${data.start}T00:00:00Z`);
|
|
43120
|
+
const endMs = Date.parse(`${data.end}T00:00:00Z`) + DAY_MS;
|
|
43121
|
+
const title = `# ${weekTitle(data)}`;
|
|
43122
|
+
if (!data.sites.length) return `${title}\n\nNo site is in your weekly audit yet. Add one on the Sites tab: ${data.account}#sites`;
|
|
43123
|
+
const byName = (a, b) => siteName(a.property).localeCompare(siteName(b.property)) || a.property.localeCompare(b.property);
|
|
43124
|
+
const sites = [...data.sites].sort(byName);
|
|
43125
|
+
const attention = [];
|
|
43126
|
+
const quiet = [];
|
|
43127
|
+
const waiting = [];
|
|
43128
|
+
for (const site of sites) {
|
|
43129
|
+
const found = issues(site, startMs, endMs);
|
|
43130
|
+
if (found.length) attention.push({
|
|
43131
|
+
site,
|
|
43132
|
+
found
|
|
43133
|
+
});
|
|
43134
|
+
else if (!site.crawl || !site.index) waiting.push(site);
|
|
43135
|
+
else quiet.push(site);
|
|
43136
|
+
}
|
|
43137
|
+
attention.sort((a, b) => a.found[0].rank - b.found[0].rank || byName(a.site, b.site));
|
|
43138
|
+
const total = sites.length;
|
|
43139
|
+
const out = [
|
|
43140
|
+
title,
|
|
43141
|
+
"",
|
|
43142
|
+
attention.length ? total === 1 ? "Your site needs a look this week." : `${attention.length} of your ${total} sites ${attention.length === 1 ? "needs" : "need"} a look this week.` : quiet.length ? total === 1 ? "Your site had a quiet week." : quiet.length === total ? `All ${total} of your sites had a quiet week.` : `${quiet.length} of your ${total} sites had a quiet week.` : "Your sites are still on their first checks."
|
|
43143
|
+
];
|
|
43144
|
+
if (attention.length) {
|
|
43145
|
+
out.push("", "## Needs attention");
|
|
43146
|
+
for (const { site, found } of attention) {
|
|
43147
|
+
const [first, ...rest] = found;
|
|
43148
|
+
const also = rest.length ? ` Also: ${list(rest.map((item) => item.heading))}.` : "";
|
|
43149
|
+
const rose = clicksChange(site) === "rose" ? ` Search clicks rose ${percent(site)}%.` : "";
|
|
43150
|
+
out.push("", `### ${siteName(site.property)}: ${first.heading}`, "", `- ${first.line}${also}${rose}`, `- Next step: ${first.next}`, ...site.link ? [`- [View site](${site.link})`] : []);
|
|
43151
|
+
}
|
|
43152
|
+
}
|
|
43153
|
+
if (quiet.length) {
|
|
43154
|
+
const risen = quiet.filter((site) => clicksChange(site) === "rose");
|
|
43155
|
+
out.push("", "## All quiet", "", `${list(quiet.map((site) => siteName(site.property)))}: no drops, no new issues.${risen.map((site) => ` Search clicks rose ${percent(site)}% on ${siteName(site.property)}.`).join("")}`);
|
|
43156
|
+
}
|
|
43157
|
+
if (waiting.length) out.push("", "## Not checked yet", "", `${list(waiting.map((site) => siteName(site.property)))}: the first crawl or Google checks are still running.`);
|
|
43158
|
+
const first = attention[0];
|
|
43159
|
+
const prompt = first ? first.found[0].prompt : `What are the best quick wins on ${siteName((quiet[0] ?? sites[0]).property)} this month?`;
|
|
43160
|
+
out.push("", "## Ask your agent", "", "Paste this into your agent:", "", "```", prompt, "```");
|
|
43161
|
+
return out.join("\n");
|
|
43162
|
+
}
|
|
43163
|
+
async function runAllSites(deps, sites) {
|
|
43164
|
+
const data = deps.week ? await deps.week() : null;
|
|
43165
|
+
if (!data && sites) {
|
|
43166
|
+
const list = await sites();
|
|
43167
|
+
return {
|
|
43168
|
+
text: `No site given. Pick one below and send it: ${deps.call("report", { site: "<site>" })}. The summary of every site is for accounts in the weekly site audit beta.\n\n${list.text}`,
|
|
43169
|
+
data: list.data
|
|
43170
|
+
};
|
|
43171
|
+
}
|
|
43172
|
+
if (!data) throw new CommandError("INVALID_INPUT", `No site given. Name one: ${deps.call("report", { site: "<site>" })}. The summary of every site is for accounts in the weekly site audit beta.`);
|
|
43173
|
+
const startMs = Date.parse(`${data.start}T00:00:00Z`);
|
|
43174
|
+
const endMs = Date.parse(`${data.end}T00:00:00Z`) + DAY_MS;
|
|
43175
|
+
const urgency = (site) => issues(site, startMs, endMs)[0]?.rank ?? Number.POSITIVE_INFINITY;
|
|
43176
|
+
const first = [...data.sites].sort((a, b) => urgency(a) - urgency(b) || siteName(a.property).localeCompare(siteName(b.property)))[0];
|
|
43177
|
+
const example = first ? siteName(first.property) : "<site>";
|
|
43178
|
+
return {
|
|
43179
|
+
text: `${weekMarkdown(data)}\n\nFull report on one site: ${deps.call("report", { site: example })}`,
|
|
43180
|
+
data
|
|
43181
|
+
};
|
|
43182
|
+
}
|
|
43183
|
+
//#endregion
|
|
42903
43184
|
//#region packages/core/dist/commands/tools.js
|
|
42904
43185
|
const site = z.string().min(1).describe("Search Console property or site, such as sc-domain:example.com, https://example.com/ or example.com.");
|
|
42905
43186
|
const dates = {
|
|
42906
|
-
start_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("YYYY-MM-DD. Optional;
|
|
42907
|
-
end_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("YYYY-MM-DD. Optional
|
|
43187
|
+
start_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("YYYY-MM-DD. Optional; without end_date it runs to the latest final day."),
|
|
43188
|
+
end_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("YYYY-MM-DD. Optional.")
|
|
42908
43189
|
};
|
|
42909
43190
|
const detail = {
|
|
42910
43191
|
detail: z.enum([
|
|
@@ -42923,6 +43204,14 @@ const DATA_SOURCES = [
|
|
|
42923
43204
|
function tool(spec) {
|
|
42924
43205
|
return spec;
|
|
42925
43206
|
}
|
|
43207
|
+
const listSites = async (surface) => runSites({
|
|
43208
|
+
accounts: await surface.accounts(),
|
|
43209
|
+
keys: await surface.keys(),
|
|
43210
|
+
clicky: clickySites(await surface.keys()).map(clickyLabel),
|
|
43211
|
+
signIn: surface.signIn,
|
|
43212
|
+
bing: surface.deps.bing ? await surface.deps.bing() : void 0,
|
|
43213
|
+
connect: surface.connect
|
|
43214
|
+
});
|
|
42926
43215
|
const SHARED_TOOLS = [
|
|
42927
43216
|
tool({
|
|
42928
43217
|
name: "seo_sites",
|
|
@@ -42930,30 +43219,31 @@ const SHARED_TOOLS = [
|
|
|
42930
43219
|
title: "List sites",
|
|
42931
43220
|
description: "Lists the Search Console and Google Analytics properties the connected Google accounts can read, the Bing Webmaster site for each, and which research keys are set. Call it first.",
|
|
42932
43221
|
input: z.object({}),
|
|
42933
|
-
run:
|
|
42934
|
-
accounts: await surface.accounts(),
|
|
42935
|
-
keys: await surface.keys(),
|
|
42936
|
-
clicky: clickySites(await surface.keys()).map(clickyLabel),
|
|
42937
|
-
signIn: surface.signIn,
|
|
42938
|
-
bing: surface.deps.bing ? await surface.deps.bing() : void 0,
|
|
42939
|
-
connect: surface.connect
|
|
42940
|
-
})
|
|
43222
|
+
run: listSites
|
|
42941
43223
|
}),
|
|
42942
43224
|
tool({
|
|
42943
43225
|
name: "seo_report",
|
|
42944
43226
|
command: "report",
|
|
42945
43227
|
title: "Search Console report",
|
|
42946
|
-
description: `
|
|
43228
|
+
description: `Start here. Without site: a short summary of every site in the person's weekly site audit (beta) for last week, with what needs a look and the next step for each, ending with the site to ask about next; an account outside that beta gets its site list to pick from. With site: the main report for that Search Console property, the overview plus each section's row count and top rows. With site and section: that section's rows; page sections also check their top 20 URLs live. Sections:\n${Object.entries(SECTIONS).map(([id, text]) => `- ${id}: ${text}`).join("\n")}`,
|
|
42947
43229
|
input: z.object({
|
|
42948
|
-
site,
|
|
42949
|
-
section: z.enum(SECTION_IDS).optional().describe("Optional. Leave it out first; then ask for one section."),
|
|
43230
|
+
site: site.optional().describe("Leave it out for the summary of every audited site (weekly site audit beta). Otherwise a Search Console property or site, such as sc-domain:example.com, https://example.com/ or example.com."),
|
|
43231
|
+
section: z.enum(SECTION_IDS).optional().describe("Optional, needs site. Leave it out first; then ask for one section."),
|
|
42950
43232
|
...dates,
|
|
42951
43233
|
...detail
|
|
42952
43234
|
}),
|
|
42953
43235
|
run: async (surface, input) => {
|
|
42954
|
-
|
|
43236
|
+
if (!input.site) {
|
|
43237
|
+
if (input.section) throw new CommandError("INVALID_INPUT", `section needs a site: ${surface.deps.call("report", {
|
|
43238
|
+
site: "<site>",
|
|
43239
|
+
section: input.section
|
|
43240
|
+
})}.`);
|
|
43241
|
+
return runAllSites(surface.deps, () => listSites(surface));
|
|
43242
|
+
}
|
|
43243
|
+
const target = input.site;
|
|
43244
|
+
const resolved = await surface.resolveSite(target).catch((error) => error instanceof Error ? error : new Error(String(error)));
|
|
42955
43245
|
if (resolved instanceof Error && !input.section && surface.deps.bing) return runBingReport({
|
|
42956
|
-
site:
|
|
43246
|
+
site: target,
|
|
42957
43247
|
startDate: input.start_date,
|
|
42958
43248
|
endDate: input.end_date
|
|
42959
43249
|
}, surface.deps).catch(() => {
|
|
@@ -42961,7 +43251,7 @@ const SHARED_TOOLS = [
|
|
|
42961
43251
|
});
|
|
42962
43252
|
if (resolved instanceof Error && input.section !== "bing") throw resolved;
|
|
42963
43253
|
return runReport$1({
|
|
42964
|
-
site: resolved instanceof Error ?
|
|
43254
|
+
site: resolved instanceof Error ? target : resolved,
|
|
42965
43255
|
section: input.section,
|
|
42966
43256
|
startDate: input.start_date,
|
|
42967
43257
|
endDate: input.end_date,
|
|
@@ -43168,9 +43458,34 @@ async function runSharedTool(tool, surface, input, local = false) {
|
|
|
43168
43458
|
if (!parsed.success) throw new CommandError("INVALID_INPUT", parsed.error.issues.map((issue) => `${issue.path.join(".") || "input"}: ${issue.message}`).join("; "));
|
|
43169
43459
|
return tool.run(surface, parsed.data);
|
|
43170
43460
|
}
|
|
43461
|
+
const MCP_SERVER_INFO = {
|
|
43462
|
+
name: "seo",
|
|
43463
|
+
title: "SEO Skill",
|
|
43464
|
+
description: "Search Console, Google Analytics and keyword data for your AI agent.",
|
|
43465
|
+
websiteUrl: "https://seoskill.dev",
|
|
43466
|
+
icons: [
|
|
43467
|
+
{
|
|
43468
|
+
src: "https://seoskill.dev/favicon-light.png",
|
|
43469
|
+
mimeType: "image/png",
|
|
43470
|
+
sizes: ["512x512"],
|
|
43471
|
+
theme: "light"
|
|
43472
|
+
},
|
|
43473
|
+
{
|
|
43474
|
+
src: "https://seoskill.dev/favicon-dark.png",
|
|
43475
|
+
mimeType: "image/png",
|
|
43476
|
+
sizes: ["512x512"],
|
|
43477
|
+
theme: "dark"
|
|
43478
|
+
},
|
|
43479
|
+
{
|
|
43480
|
+
src: "https://seoskill.dev/favicon.svg",
|
|
43481
|
+
mimeType: "image/svg+xml",
|
|
43482
|
+
sizes: ["any"]
|
|
43483
|
+
}
|
|
43484
|
+
]
|
|
43485
|
+
};
|
|
43171
43486
|
const MCP_INSTRUCTIONS = `SEO Skill reads the person's own Search Console, Google Analytics, Bing Webmaster Tools, Clicky and optional keyword accounts, and returns facts with their dates and limits. It gives no advice.
|
|
43172
43487
|
1. seo_sites: the properties the connected accounts can read.
|
|
43173
|
-
2. seo_report:
|
|
43488
|
+
2. seo_report: start here. Without site it summarises last week across every site in the weekly site audit (beta) and names the site to ask about next. With site it shows that property's overview and every section's count and top rows; then ask for the one section you need.
|
|
43174
43489
|
3. seo_page for one URL, seo_compare for before and after a date, seo_index for Google's indexing reasons and pages that lost their clicks, seo_research for keyword, competitor and backlink data, and whether AI answers cite the site, from the DataForSEO or Ahrefs key the person saved, seo_data for raw rows, including Google Analytics, Bing and Clicky.`;
|
|
43175
43490
|
const mcpCall = (command, args) => {
|
|
43176
43491
|
const name = `seo_${command.replace("-", "_")}`;
|
|
@@ -43186,7 +43501,7 @@ const SKILL_RESOURCE = {
|
|
|
43186
43501
|
};
|
|
43187
43502
|
//#endregion
|
|
43188
43503
|
//#region packages/core/dist/gsc/client/inspection-cache.js
|
|
43189
|
-
const INSPECTION_FRESH_MS =
|
|
43504
|
+
const INSPECTION_FRESH_MS = 6048e5;
|
|
43190
43505
|
function readSavedInspections(site, urls, now = Date.now()) {
|
|
43191
43506
|
const found = /* @__PURE__ */ new Map();
|
|
43192
43507
|
try {
|
|
@@ -43415,7 +43730,8 @@ function nodeCommandDeps(options) {
|
|
|
43415
43730
|
analytics: {
|
|
43416
43731
|
accounts: localAccounts,
|
|
43417
43732
|
signIn: LOCAL_SIGN_IN.signIn
|
|
43418
|
-
}
|
|
43733
|
+
},
|
|
43734
|
+
...cloudLinked() ? { week: cloudWeek } : {}
|
|
43419
43735
|
};
|
|
43420
43736
|
}
|
|
43421
43737
|
const LOCAL_BING_CONNECT = "Connect Bing on your seoskill.dev account and run `seo login`, or run `seo providers bing connect` with an API key from Bing Webmaster Tools (Settings, API access).";
|
|
@@ -43478,8 +43794,9 @@ async function localRefreshClicky() {
|
|
|
43478
43794
|
return localResearchKeys();
|
|
43479
43795
|
}
|
|
43480
43796
|
async function resolveLocalSite(site, options = {}) {
|
|
43481
|
-
const
|
|
43482
|
-
|
|
43797
|
+
const names = (await listSites$1(options.refresh, options.account)).map((entry) => entry.siteUrl);
|
|
43798
|
+
const found = matchProperty(names, site);
|
|
43799
|
+
if (!found) throw new CommandError("NO_ACCESS", `This Google login has no Search Console property for ${site}. ${readable(names)}`);
|
|
43483
43800
|
return found;
|
|
43484
43801
|
}
|
|
43485
43802
|
const ERROR_CODES = {
|
|
@@ -43487,6 +43804,7 @@ const ERROR_CODES = {
|
|
|
43487
43804
|
NOT_CONNECTED: "AUTH_REQUIRED",
|
|
43488
43805
|
NO_ACCESS: "PROPERTY_NOT_FOUND",
|
|
43489
43806
|
NO_KEY: "AUTH_CONFIG_REQUIRED",
|
|
43807
|
+
NO_DATA: "INSUFFICIENT_DATA",
|
|
43490
43808
|
RATE_LIMITED: "RATE_LIMITED",
|
|
43491
43809
|
GOOGLE_ERROR: "PROVIDER_UNAVAILABLE",
|
|
43492
43810
|
PROVIDER_ERROR: "PROVIDER_UNAVAILABLE"
|
|
@@ -43569,10 +43887,10 @@ async function runDoctor(dependencies = {}) {
|
|
|
43569
43887
|
}
|
|
43570
43888
|
//#endregion
|
|
43571
43889
|
//#region packages/core/dist/provider-extensions/actions.js
|
|
43572
|
-
const MAX_ACTION_PARAM_BYTES =
|
|
43890
|
+
const MAX_ACTION_PARAM_BYTES = 65536;
|
|
43573
43891
|
const MAX_ACTION_PARAM_DEPTH = 16;
|
|
43574
43892
|
const MAX_ACTION_PARAM_VALUES = 5e3;
|
|
43575
|
-
const MAX_ACTION_RESULT_BYTES =
|
|
43893
|
+
const MAX_ACTION_RESULT_BYTES = 10485760;
|
|
43576
43894
|
const MAX_ACTION_RESULT_DEPTH = 20;
|
|
43577
43895
|
const MAX_ACTION_RESULT_VALUES = 1e5;
|
|
43578
43896
|
function normalizedParams(params) {
|
|
@@ -43946,7 +44264,7 @@ function updateNotice(options = {}) {
|
|
|
43946
44264
|
}
|
|
43947
44265
|
//#endregion
|
|
43948
44266
|
//#region packages/mcp/src/agent-output-budget.ts
|
|
43949
|
-
const AGENT_STRUCTURED_OUTPUT_MAX_BYTES =
|
|
44267
|
+
const AGENT_STRUCTURED_OUTPUT_MAX_BYTES = 98304;
|
|
43950
44268
|
function jsonBytes(value) {
|
|
43951
44269
|
return Buffer.byteLength(JSON.stringify(value));
|
|
43952
44270
|
}
|
|
@@ -46411,13 +46729,20 @@ const REMOVED_REPORT_IDS = {
|
|
|
46411
46729
|
"server-log-analysis": null,
|
|
46412
46730
|
"technical-watch": "seo crawl"
|
|
46413
46731
|
};
|
|
46414
|
-
|
|
46732
|
+
const REPORT_ALIASES = {
|
|
46733
|
+
cannibalization: "cannibalisation",
|
|
46734
|
+
"content-decay": "decaying-pages",
|
|
46735
|
+
"low-ctr": "ctr-underperformers",
|
|
46736
|
+
"traffic-drop": "traffic-anomaly"
|
|
46737
|
+
};
|
|
46738
|
+
function activeReport(name) {
|
|
46739
|
+
const id = REPORT_ALIASES[name] ?? name;
|
|
46415
46740
|
if (Object.hasOwn(REMOVED_REPORT_IDS, id)) {
|
|
46416
46741
|
const replacement = REMOVED_REPORT_IDS[id];
|
|
46417
46742
|
throw new SeoError("INVALID_INPUT", replacement ? `The ${id} report was removed. Use \`${replacement}\` instead.` : `The ${id} report was removed. Run \`seo help\` for the commands.`);
|
|
46418
46743
|
}
|
|
46419
46744
|
const report = getReportDefinition(id);
|
|
46420
|
-
if (!report) throw new SeoError("INVALID_INPUT", `Unknown report: ${id}.`);
|
|
46745
|
+
if (!report) throw new SeoError("INVALID_INPUT", `Unknown report: ${id}. Reports: ${listReportDefinitions().map((item) => item.id).join(", ")}.`);
|
|
46421
46746
|
return report;
|
|
46422
46747
|
}
|
|
46423
46748
|
function listReports(category) {
|
|
@@ -46499,8 +46824,10 @@ async function countedRun(command, args, telemetry, run) {
|
|
|
46499
46824
|
if (report && telemetry) trackTelemetryReportStart(report, telemetry());
|
|
46500
46825
|
try {
|
|
46501
46826
|
const result = await run();
|
|
46502
|
-
if (report && telemetry)
|
|
46503
|
-
|
|
46827
|
+
if (report && telemetry) {
|
|
46828
|
+
if (result.isError) trackTelemetryReportFailed(report, result.structuredContent?.error, telemetry());
|
|
46829
|
+
else trackTelemetryReportComplete(report, telemetry());
|
|
46830
|
+
}
|
|
46504
46831
|
return result;
|
|
46505
46832
|
} catch (error) {
|
|
46506
46833
|
const failure = localError(error);
|
|
@@ -46599,7 +46926,9 @@ function readSkill() {
|
|
|
46599
46926
|
}
|
|
46600
46927
|
function createServer(options = {}) {
|
|
46601
46928
|
const server = new McpServer({
|
|
46602
|
-
|
|
46929
|
+
...MCP_SERVER_INFO,
|
|
46930
|
+
title: "SEO Skill (local)",
|
|
46931
|
+
description: `${MCP_SERVER_INFO.description} Runs on your machine.`,
|
|
46603
46932
|
version: SEO_VERSION
|
|
46604
46933
|
}, {
|
|
46605
46934
|
capabilities: { logging: {} },
|