pagesight 0.12.0 → 0.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pagesight",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "See your site the way search engines and AI see it.",
5
5
  "keywords": [
6
6
  "seo",
package/src/lib/psi.ts CHANGED
@@ -79,6 +79,10 @@ export interface PsiResult {
79
79
  export type PsiStrategy = "mobile" | "desktop";
80
80
  export type PsiCategoryType = "performance" | "accessibility" | "best-practices" | "seo";
81
81
 
82
+ export function hasApiKey(): boolean {
83
+ return !!process.env.GOOGLE_API_KEY;
84
+ }
85
+
82
86
  export async function runPagespeed(
83
87
  url: string,
84
88
  options?: {
@@ -252,26 +252,28 @@ function addInspectFindings(verdict: string, coverageState: string, findings: Fi
252
252
  function formatAudit(url: string, findings: Finding[], errors: string[]): string {
253
253
  const lines: string[] = [`=== Site Audit: ${url} ===`, ""];
254
254
 
255
+ // Lead with errors so partial results are obvious
256
+ if (errors.length > 0) {
257
+ lines.push(`${errors.length} check${errors.length > 1 ? "s" : ""} failed — results below are partial:`, "");
258
+ for (const e of errors) {
259
+ lines.push(` FAIL ${e}`);
260
+ }
261
+ lines.push("");
262
+ }
263
+
255
264
  // Sort: HIGH first, then MEDIUM, then LOW
256
265
  const order: Record<string, number> = { HIGH: 0, MEDIUM: 1, LOW: 2 };
257
266
  findings.sort((a, b) => order[a.severity] - order[b.severity]);
258
267
 
259
- if (findings.length === 0) {
268
+ if (findings.length === 0 && errors.length === 0) {
260
269
  lines.push("No issues found.");
261
- } else {
262
- lines.push(`${findings.length} findings:`, "");
270
+ } else if (findings.length > 0) {
271
+ lines.push(`${findings.length} finding${findings.length > 1 ? "s" : ""}:`, "");
263
272
  for (const f of findings) {
264
273
  lines.push(`${f.severity.padEnd(6)} ${f.message}`);
265
274
  }
266
275
  }
267
276
 
268
- if (errors.length > 0) {
269
- lines.push("", "--- Errors (partial audit) ---", "");
270
- for (const e of errors) {
271
- lines.push(`- ${e}`);
272
- }
273
- }
274
-
275
277
  return lines.join("\n");
276
278
  }
277
279
 
@@ -1,6 +1,7 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { z } from "zod";
3
3
  import {
4
+ hasApiKey,
4
5
  type PsiAudit,
5
6
  type PsiAuditDetailItem,
6
7
  type PsiCategoryType,
@@ -8,6 +9,9 @@ import {
8
9
  runPagespeed,
9
10
  } from "../lib/psi.js";
10
11
 
12
+ const QUOTA_NOTE =
13
+ "\n\nNote: No GOOGLE_API_KEY configured — using shared quota (400 req/day). Set your own key to avoid rate limits.";
14
+
11
15
  function scoreLabel(score: number | null): string {
12
16
  if (score === null) return "N/A";
13
17
  const pct = Math.round(score * 100);
@@ -536,7 +540,8 @@ export function registerPagespeedTool(server: McpServer): void {
536
540
  if (url) {
537
541
  try {
538
542
  const result = await runPagespeed(url, opts);
539
- return { content: [{ type: "text", text: formatPagespeed(url, result) }] };
543
+ const text = formatPagespeed(url, result) + (hasApiKey() ? "" : QUOTA_NOTE);
544
+ return { content: [{ type: "text", text }] };
540
545
  } catch (err) {
541
546
  const msg = err instanceof Error ? err.message : String(err);
542
547
  return { content: [{ type: "text", text: `Error running PageSpeed analysis: ${msg}` }] };
@@ -569,6 +574,8 @@ export function registerPagespeedTool(server: McpServer): void {
569
574
  output += `\n\n--- Errors ---\n${errorLines.join("\n")}`;
570
575
  }
571
576
 
577
+ if (!hasApiKey()) output += QUOTA_NOTE;
578
+
572
579
  return { content: [{ type: "text", text: output }] };
573
580
  },
574
581
  );