@aexol/spectral 0.9.125 → 0.9.127
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +5 -0
- package/dist/cli.js +6 -0
- package/dist/commands/update.d.ts +17 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +292 -0
- package/dist/extensions/seo/analyzers/content.d.ts +29 -6
- package/dist/extensions/seo/analyzers/content.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/content.js +243 -8
- package/dist/extensions/seo/analyzers/crawler.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/crawler.js +133 -7
- package/dist/extensions/seo/analyzers/drift.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/drift.js +86 -29
- package/dist/extensions/seo/analyzers/images.d.ts +10 -4
- package/dist/extensions/seo/analyzers/images.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/images.js +153 -5
- package/dist/extensions/seo/analyzers/performance.d.ts +3 -3
- package/dist/extensions/seo/analyzers/performance.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/performance.js +77 -6
- package/dist/extensions/seo/analyzers/readability.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/readability.js +17 -9
- package/dist/extensions/seo/analyzers/schema.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/schema.js +99 -10
- package/dist/extensions/seo/analyzers/sitemap.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/sitemap.js +57 -16
- package/dist/extensions/seo/analyzers/technical.d.ts +0 -7
- package/dist/extensions/seo/analyzers/technical.d.ts.map +1 -1
- package/dist/extensions/seo/analyzers/technical.js +408 -37
- package/dist/extensions/seo/config.d.ts +2 -0
- package/dist/extensions/seo/config.d.ts.map +1 -1
- package/dist/extensions/seo/config.js +2 -0
- package/dist/extensions/seo/tools/batch.js +1 -1
- package/dist/extensions/seo/tools/content.d.ts.map +1 -1
- package/dist/extensions/seo/tools/content.js +5 -3
- package/dist/extensions/seo/tools/full-audit.d.ts +1 -1
- package/dist/extensions/seo/tools/full-audit.d.ts.map +1 -1
- package/dist/extensions/seo/tools/full-audit.js +391 -66
- package/dist/extensions/seo/tools/helpers.d.ts +15 -4
- package/dist/extensions/seo/tools/helpers.d.ts.map +1 -1
- package/dist/extensions/seo/tools/helpers.js +57 -6
- package/dist/extensions/seo/tools/performance.d.ts.map +1 -1
- package/dist/extensions/seo/tools/performance.js +17 -11
- package/dist/extensions/seo/tools/report.d.ts.map +1 -1
- package/dist/extensions/seo/tools/report.js +513 -47
- package/dist/extensions/seo/types.d.ts +295 -3
- package/dist/extensions/seo/types.d.ts.map +1 -1
- package/dist/extensions/seo/utils/fetcher.d.ts +4 -0
- package/dist/extensions/seo/utils/fetcher.d.ts.map +1 -1
- package/dist/extensions/seo/utils/fetcher.js +77 -11
- package/dist/extensions/seo/utils/parser.d.ts +3 -1
- package/dist/extensions/seo/utils/parser.d.ts.map +1 -1
- package/dist/extensions/seo/utils/parser.js +105 -25
- package/dist/extensions/seo/utils/renderer.d.ts +6 -1
- package/dist/extensions/seo/utils/renderer.d.ts.map +1 -1
- package/dist/extensions/seo/utils/renderer.js +207 -1
- package/dist/extensions/seo/utils/url-safety.d.ts.map +1 -1
- package/dist/extensions/seo/utils/url-safety.js +19 -3
- package/dist/extensions/web/tools/fetch.js +2 -2
- package/dist/memory/tools/compact-context.d.ts.map +1 -1
- package/dist/memory/tools/compact-context.js +10 -3
- package/dist/sdk/agent-core/agent-loop.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent-loop.js +87 -4
- package/dist/sdk/agent-core/types.d.ts +1 -0
- package/dist/sdk/agent-core/types.d.ts.map +1 -1
- package/dist/sdk/ai/utils/validation.d.ts +0 -7
- package/dist/sdk/ai/utils/validation.d.ts.map +1 -1
- package/dist/sdk/ai/utils/validation.js +21 -1
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +41 -0
- package/dist/server/storage.d.ts +9 -0
- package/dist/server/storage.d.ts.map +1 -1
- package/dist/server/storage.js +35 -9
- package/dist/server/wire.d.ts +2 -0
- package/dist/server/wire.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,56 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export
|
|
1
|
+
/** Version of the SEO tool result schema. Increment on breaking changes. */
|
|
2
|
+
export const SEO_RESULT_VERSION = 2;
|
|
3
|
+
/** Create a text tool result. Accepts either legacy (text, details) or new (text, result, warnings). */
|
|
4
|
+
export function textResult(text, detailsOrResult, warnings) {
|
|
5
|
+
// Detect legacy call: second arg is a plain object with string keys.
|
|
6
|
+
const isLegacy = detailsOrResult !== undefined
|
|
7
|
+
&& typeof detailsOrResult === "object"
|
|
8
|
+
&& detailsOrResult !== null
|
|
9
|
+
&& !Array.isArray(detailsOrResult);
|
|
10
|
+
if (isLegacy) {
|
|
11
|
+
const details = detailsOrResult;
|
|
12
|
+
return {
|
|
13
|
+
content: [{ type: "text", text }],
|
|
14
|
+
details: {
|
|
15
|
+
...details,
|
|
16
|
+
metadata: { ...(details.metadata ?? {}), version: SEO_RESULT_VERSION },
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
3
20
|
return {
|
|
4
21
|
content: [{ type: "text", text }],
|
|
5
|
-
details
|
|
22
|
+
details: {
|
|
23
|
+
result: detailsOrResult,
|
|
24
|
+
warnings: warnings ?? [],
|
|
25
|
+
metadata: { version: SEO_RESULT_VERSION },
|
|
26
|
+
},
|
|
6
27
|
};
|
|
7
28
|
}
|
|
8
|
-
/** Create an error tool result. */
|
|
9
|
-
export function errorResult(message,
|
|
29
|
+
/** Create an error tool result. Accepts either legacy (msg, details) or new (msg, result, warnings). */
|
|
30
|
+
export function errorResult(message, detailsOrResult, warnings) {
|
|
31
|
+
const isLegacy = detailsOrResult !== undefined
|
|
32
|
+
&& typeof detailsOrResult === "object"
|
|
33
|
+
&& detailsOrResult !== null
|
|
34
|
+
&& !Array.isArray(detailsOrResult);
|
|
35
|
+
if (isLegacy) {
|
|
36
|
+
const details = detailsOrResult;
|
|
37
|
+
return {
|
|
38
|
+
content: [{ type: "text", text: `❌ ${message}` }],
|
|
39
|
+
details: {
|
|
40
|
+
isError: true,
|
|
41
|
+
...details,
|
|
42
|
+
metadata: { ...(details.metadata ?? {}), version: SEO_RESULT_VERSION },
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
10
46
|
return {
|
|
11
47
|
content: [{ type: "text", text: `❌ ${message}` }],
|
|
12
|
-
details: {
|
|
48
|
+
details: {
|
|
49
|
+
isError: true,
|
|
50
|
+
result: detailsOrResult,
|
|
51
|
+
warnings: warnings ?? [],
|
|
52
|
+
metadata: { version: SEO_RESULT_VERSION },
|
|
53
|
+
},
|
|
13
54
|
};
|
|
14
55
|
}
|
|
15
56
|
/** Format a JSON object as pretty-printed text for tool output. */
|
|
@@ -22,3 +63,13 @@ export function truncate(text, maxLen) {
|
|
|
22
63
|
return text;
|
|
23
64
|
return text.slice(0, maxLen) + "... (truncated)";
|
|
24
65
|
}
|
|
66
|
+
/** Validate and normalize a tool URL input, enforcing length limits. */
|
|
67
|
+
export function validateToolUrl(raw, maxLen = 4096) {
|
|
68
|
+
const trimmed = raw.trim();
|
|
69
|
+
if (trimmed.length > maxLen) {
|
|
70
|
+
throw new Error(`URL exceeds maximum length of ${maxLen} characters.`);
|
|
71
|
+
}
|
|
72
|
+
if (!trimmed)
|
|
73
|
+
throw new Error("URL is required.");
|
|
74
|
+
return trimmed;
|
|
75
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../../../src/extensions/seo/tools/performance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,oCAAoC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../../../src/extensions/seo/tools/performance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,oCAAoC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAS9C,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA8MnF"}
|
|
@@ -2,14 +2,13 @@ import { fetchPage } from "../utils/fetcher.js";
|
|
|
2
2
|
import { calculatePerformanceFromFetch, analyzePageWeight, analyzeRenderBlocking, analyzeFonts, } from "../analyzers/performance.js";
|
|
3
3
|
import { errorResult, textResult } from "./helpers.js";
|
|
4
4
|
export function registerPerformanceTools(ext, config) {
|
|
5
|
-
// === seo_performance ===
|
|
6
5
|
const perfTool = {
|
|
7
6
|
name: "seo_performance",
|
|
8
7
|
label: "SEO Performance Audit (Core Web Vitals)",
|
|
9
8
|
description: "Estimate Core Web Vitals metrics from page structure analysis. " +
|
|
10
9
|
"Reports LCP (Largest Contentful Paint), CLS (Cumulative Layout Shift), TBT (Total Blocking Time), FCP, and TTFB. " +
|
|
11
10
|
"Each metric is rated: good, needs-improvement, or poor against Google's thresholds. " +
|
|
12
|
-
"
|
|
11
|
+
"When a browser is available, real Web Vitals are measured via Playwright.",
|
|
13
12
|
promptSnippet: "`seo_performance { url }` — estimate Core Web Vitals (LCP, CLS, TBT) with ratings",
|
|
14
13
|
parameters: {
|
|
15
14
|
type: "object",
|
|
@@ -22,7 +21,17 @@ export function registerPerformanceTools(ext, config) {
|
|
|
22
21
|
const { url } = params;
|
|
23
22
|
try {
|
|
24
23
|
const fetchResult = await fetchPage(url, config);
|
|
25
|
-
|
|
24
|
+
let measuredPerformance = undefined;
|
|
25
|
+
try {
|
|
26
|
+
const { isRendererAvailable, renderPage } = await import("../utils/renderer.js");
|
|
27
|
+
if (await isRendererAvailable()) {
|
|
28
|
+
const rendered = await renderPage(url, config, { capturePerformance: true });
|
|
29
|
+
if (rendered.measuredPerformance)
|
|
30
|
+
measuredPerformance = rendered.measuredPerformance;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch { /* renderer not available */ }
|
|
34
|
+
const perf = calculatePerformanceFromFetch(fetchResult, url, measuredPerformance);
|
|
26
35
|
const lines = [
|
|
27
36
|
`✓ Performance Estimate: ${perf.url}`,
|
|
28
37
|
``,
|
|
@@ -34,8 +43,8 @@ export function registerPerformanceTools(ext, config) {
|
|
|
34
43
|
` TBT: ${perf.tbt.value}ms — ${perf.tbt.rating.toUpperCase()}`,
|
|
35
44
|
``,
|
|
36
45
|
`Other Metrics:`,
|
|
37
|
-
` FCP: ${perf.fcp}ms`,
|
|
38
|
-
` TTFB: ${perf.ttfb}ms`,
|
|
46
|
+
` FCP: ${perf.fcp.value}ms (${perf.fcp.rating})`,
|
|
47
|
+
` TTFB: ${perf.ttfb.value}ms (${perf.ttfb.rating})`,
|
|
39
48
|
``,
|
|
40
49
|
`Google Thresholds:`,
|
|
41
50
|
` LCP: good ≤ 2500ms, poor > 4000ms`,
|
|
@@ -49,7 +58,6 @@ export function registerPerformanceTools(ext, config) {
|
|
|
49
58
|
}
|
|
50
59
|
},
|
|
51
60
|
};
|
|
52
|
-
// === seo_page_weight ===
|
|
53
61
|
const weightTool = {
|
|
54
62
|
name: "seo_page_weight",
|
|
55
63
|
label: "SEO Page Weight Analysis",
|
|
@@ -84,11 +92,11 @@ export function registerPerformanceTools(ext, config) {
|
|
|
84
92
|
if (weight.topHeavyResources.length > 0) {
|
|
85
93
|
lines.push(``, `Heaviest resources:`);
|
|
86
94
|
for (const r of weight.topHeavyResources) {
|
|
87
|
-
lines.push(` ${r.type.toUpperCase()}: ${r.
|
|
95
|
+
lines.push(` ${r.type.toUpperCase()}: ${r.url} (${r.sizeKb} KB)`);
|
|
88
96
|
}
|
|
89
97
|
}
|
|
90
|
-
if (weight.totalKb
|
|
91
|
-
lines.push(``,
|
|
98
|
+
if (weight.totalKb < 500) {
|
|
99
|
+
lines.push(``, `✓ Page weight is excellent.`);
|
|
92
100
|
}
|
|
93
101
|
else if (weight.totalKb > 2000) {
|
|
94
102
|
lines.push(``, `⚡ Page weight is above average. Consider optimizing assets.`);
|
|
@@ -100,7 +108,6 @@ export function registerPerformanceTools(ext, config) {
|
|
|
100
108
|
}
|
|
101
109
|
},
|
|
102
110
|
};
|
|
103
|
-
// === seo_render_blocking ===
|
|
104
111
|
const blockingTool = {
|
|
105
112
|
name: "seo_render_blocking",
|
|
106
113
|
label: "SEO Render-Blocking Resource Audit",
|
|
@@ -151,7 +158,6 @@ export function registerPerformanceTools(ext, config) {
|
|
|
151
158
|
}
|
|
152
159
|
},
|
|
153
160
|
};
|
|
154
|
-
// === seo_font_audit ===
|
|
155
161
|
const fontTool = {
|
|
156
162
|
name: "seo_font_audit",
|
|
157
163
|
label: "SEO Font Optimization Audit",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../src/extensions/seo/tools/report.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../../src/extensions/seo/tools/report.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,oCAAoC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAqB9C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAgH9E"}
|