pagesight 0.5.0 → 0.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagesight",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "See your site the way search engines and AI see it.",
5
5
  "keywords": [
6
6
  "seo",
@@ -322,11 +322,15 @@ export function registerMetatagsTool(server: McpServer): void {
322
322
  // Redirect chain (only if there were redirects)
323
323
  if (chain.length > 1) {
324
324
  output.push("--- Redirect Chain ---", "");
325
- for (let i = 0; i < chain.length; i++) {
326
- const hop = chain[i];
327
- const prefix = i === chain.length - 1 ? "" : `${hop.status} → `;
328
- output.push(`${i + 1}. ${prefix}${hop.url}`);
325
+ const parts: string[] = [];
326
+ for (const hop of chain) {
327
+ parts.push(hop.url);
328
+ parts.push(String(hop.status));
329
329
  }
330
+ // Format: URL → status → URL → status (drop trailing status)
331
+ parts.pop();
332
+ output.push(parts.join(" → "));
333
+ output.push(`Hops: ${chain.length - 1}`);
330
334
  output.push("");
331
335
  }
332
336
 
@@ -352,9 +356,27 @@ export function registerMetatagsTool(server: McpServer): void {
352
356
  output.push(`${check.tag}: BROKEN — HTTP ${check.status}`);
353
357
  output.push(` URL: ${check.url}`);
354
358
  } else {
355
- const size = check.contentLength ? ` (${Math.round(check.contentLength / 1024)} KB)` : "";
359
+ const sizeKB = check.contentLength ? Math.round(check.contentLength / 1024) : null;
360
+ const size = sizeKB ? ` (${sizeKB} KB)` : "";
356
361
  const type = check.contentType ? ` ${check.contentType}` : "";
357
362
  output.push(`${check.tag}: OK —${type}${size}`);
363
+ if (sizeKB && sizeKB > 1024) {
364
+ output.push(` Warning: ${sizeKB} KB is large for social previews — consider compressing below 1 MB`);
365
+ }
366
+ }
367
+
368
+ // Check declared dimensions from meta tags
369
+ if (check.tag === "og:image") {
370
+ const w = getMeta(parsed.meta, "og:image:width");
371
+ const h = getMeta(parsed.meta, "og:image:height");
372
+ if (w && h) {
373
+ output.push(` Declared dimensions: ${w}x${h}`);
374
+ const wn = Number(w);
375
+ const hn = Number(h);
376
+ if (wn && hn && (wn < 1200 || hn < 630)) {
377
+ output.push(` Note: recommended minimum for og:image is 1200x630`);
378
+ }
379
+ }
358
380
  }
359
381
  }
360
382
  }
@@ -108,6 +108,15 @@ async function inspectSingle(url: string, siteUrl: string): Promise<InspectionSu
108
108
  }
109
109
  }
110
110
 
111
+ function humanizeState(state: string): string {
112
+ const map: Record<string, string> = {
113
+ PAGE_FETCH_STATE_UNSPECIFIED: "not yet crawled",
114
+ ROBOTS_TXT_STATE_UNSPECIFIED: "not yet checked",
115
+ INDEXING_STATE_UNSPECIFIED: "not yet determined",
116
+ };
117
+ return map[state] ?? state;
118
+ }
119
+
111
120
  function formatResults(siteUrl: string, sitemapUrl: string, totalUrls: number, results: InspectionSummary[]): string {
112
121
  const lines: string[] = [
113
122
  `=== Sample Inspection: ${siteUrl} ===`,
@@ -153,7 +162,7 @@ function formatResults(siteUrl: string, sitemapUrl: string, totalUrls: number, r
153
162
  lines.push("");
154
163
  lines.push("Page fetch issues:");
155
164
  for (const [state, count] of fetchIssues) {
156
- lines.push(` ${state}: ${count}`);
165
+ lines.push(` ${humanizeState(state)}: ${count}`);
157
166
  }
158
167
  }
159
168
 
@@ -171,9 +180,9 @@ function formatResults(siteUrl: string, sitemapUrl: string, totalUrls: number, r
171
180
  } else {
172
181
  lines.push(` Verdict: ${r.verdict}`);
173
182
  lines.push(` Coverage: ${r.coverageState}`);
174
- lines.push(` Page fetch: ${r.pageFetchState}`);
175
- if (r.robotsTxtState !== "ALLOWED") lines.push(` Robots.txt: ${r.robotsTxtState}`);
176
- if (r.indexingState !== "INDEXING_ALLOWED") lines.push(` Indexing: ${r.indexingState}`);
183
+ lines.push(` Page fetch: ${humanizeState(r.pageFetchState)}`);
184
+ if (r.robotsTxtState !== "ALLOWED") lines.push(` Robots.txt: ${humanizeState(r.robotsTxtState)}`);
185
+ if (r.indexingState !== "INDEXING_ALLOWED") lines.push(` Indexing: ${humanizeState(r.indexingState)}`);
177
186
  if (r.lastCrawlTime) lines.push(` Last crawled: ${r.lastCrawlTime}`);
178
187
  if (r.googleCanonical && r.googleCanonical !== r.url) {
179
188
  lines.push(` Google canonical: ${r.googleCanonical}`);