speed-fix — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited speed-fix (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Run a PageSpeed Insights audit against a URL, produce a ranked, file-linked remediation plan for the current working directory, and apply approved fixes. Covers the long tail of Lighthouse opportunities — LCP render delay, render-blocking CSS/JS, legacy polyfills, oversized images, unused JS, font loading, preconnect hygiene, third-party weight.
/speed-fix <url> # audit mobile, produce plan, wait for approval
/speed-fix <url> --strategy desktop # desktop audit instead
/speed-fix <url> --strategy both # audit both; plan from the worst-scoring audits
/speed-fix <url> --apply # skip the approval gate, edit + rebuild + verify
/speed-fix # no URL → infer from repo configSet GOOGLE_PAGESPEED_API_KEY to avoid the ~1 req/s anonymous rate limit. The skill resolves the key in this order — first hit wins:
$GOOGLE_PAGESPEED_API_KEY in the current shell environment~/.claude/skills/speed-fix/.env — a single line GOOGLE_PAGESPEED_API_KEY=AIza...Get a free key at <https://console.cloud.google.com/apis/credentials> → _Create credentials_ → _API key_ → restrict to the _PageSpeed Insights API_. No quota cost for the free tier.
To use the local-file option:
echo 'GOOGLE_PAGESPEED_API_KEY=YOUR_KEY_HERE' > ~/.claude/skills/speed-fix/.env
chmod 600 ~/.claude/skills/speed-fix/.envThe file is gitignored by this repo.
When invoked, execute these steps in order. Output should be terse: one-line status per step, a full plan table at step 6, and a before/after diff at step 9.
If <url> is passed, use it. Otherwise infer:
package.json → homepage fieldnext.config.* → aeo.url / metadataBase / any string literal https://...astro.config.* → sitevercel.json / netlify.toml → production domain.env* → NEXT_PUBLIC_SITE_URL, SITE_URL, PUBLIC_URL, etc.If multiple candidates or none, ask the user once.
Check project root (in order; first hit wins):
| Marker | Stack | Playbook section |
|---|---|---|
next.config.{ts,js,mjs} | nextjs | playbooks.md#nextjs |
nuxt.config.{ts,js} | nuxt | playbooks.md#nuxt |
astro.config.{ts,js,mjs} | astro | playbooks.md#astro |
svelte.config.{js,ts} | sveltekit | playbooks.md#sveltekit |
vite.config.{ts,js,mjs} (and not Astro/SvelteKit) | vite | playbooks.md#vite |
wp-config.php | wordpress | playbooks.md#wordpress |
| otherwise | generic | playbooks.md#generic |
State the detected stack on one line (e.g. stack: nextjs (next.config.ts)).
# Resolve API key: env var, then ~/.claude/skills/speed-fix/.env, else anonymous
KEY="${GOOGLE_PAGESPEED_API_KEY:-}"
ENV_FILE="$HOME/.claude/skills/speed-fix/.env"
if [ -z "$KEY" ] && [ -f "$ENV_FILE" ]; then
KEY=$(grep -E '^GOOGLE_PAGESPEED_API_KEY=' "$ENV_FILE" | head -1 | cut -d= -f2- | tr -d '"'"'" )
fi
STRATEGIES=("mobile") # or ("desktop") or ("mobile" "desktop") for --strategy both
HOST=$(echo "$URL" | sed -E 's|https?://||; s|/.*||')
TS=$(date +%s)
mkdir -p /tmp/speed-fix
for S in "${STRATEGIES[@]}"; do
curl -sS --max-time 60 \
"https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$(printf '%s' "$URL" | jq -sRr @uri)&strategy=$S&category=PERFORMANCE${KEY:+&key=$KEY}" \
> "/tmp/speed-fix/psi-$HOST-$S-$TS.json"
doneOn non-200 or missing lighthouseResult, surface the error and stop.
Print one summary line per strategy:
mobile: Perf 62 | LCP 3.9s | CLS 0.04 | TBT 680ms | TTFB 280msPull from lighthouseResult.categories.performance.score (×100) and lighthouseResult.audits.metrics.details.items[0].
For each audit in lighthouseResult.audits where any of:
score !== null && score < 0.9details.overallSavingsMs > 100details.overallSavingsBytes > 5120details.type === "opportunity" with non-empty items…record { id, title, savingsMs, savingsBytes, items }. If --strategy both, merge on audit id and take the worse score.
Look up each id in audits.md. If the id isn't in the table, bucket it as investigate and include verbatim in the plan; extend audits.md opportunistically after the run.
For each remediation, use Grep/Glob to locate the concrete files — e.g.:
| Audit id | Grep targets |
|---|---|
render-blocking-resources | <link rel="stylesheet" in app/layout.*, pages/_document.*, public/**/*.html; <script[^>]*src= without defer/async |
legacy-javascript | browserslist in package.json, .browserslistrc; target in tsconfig.json, vite.config.*, next.config.* |
uses-responsive-images | <Image / <img with sizes=, srcset=, or missing them |
uses-optimized-images | image extensions in public/, src/assets/, static/ |
uses-rel-preconnect | <link rel="preconnect" in <head> templates |
third-party-facades | script tags / dynamic imports matching known third-parties (YouTube, Intercom, Drift, HubSpot, GTM, Cal.com) |
Annotate each item with file:line when found. If you can't locate a clean file target, mark the item as advisory — include it in the plan but don't propose an automated edit.
Output a ranked markdown table grouped by category. Column order:
| # | audit | category | est. savings | file(s) | proposed change |Rank primarily by savingsMs (descending), then savingsBytes. Group headings in this order: LCP critical path, Payload reduction, Images, Fonts, Third-party, Build config, Advisory.
Below the table, list explicit file edits as path:line → change, short enough to scan.
Unless --apply, stop here:
ExitPlanMode. The plan content is the markdown from step 6.Apply these fixes? (yes / pick / no). pick lets the user mark items to skip.For each approved item, perform the Edit/Write/Bash actions listed in playbooks.md under the detected stack. Rules:
/speed-fix skill edits files only. User runs git commit when satisfied.package.json has typecheck, run it; if it has build, run it. On failure, stop and report — do not keep applying.Re-fetch PSI for the same strategy (or strategies). Emit a before/after line per strategy and per fixed audit:
mobile: Perf 62 → 81 | LCP 3.9s → 2.1s | TBT 680ms → 240ms
legacy-javascript: failed (14 KiB) → passing
uses-responsive-images: 48 KiB → 8 KiB
render-blocking-resources: 380 ms → 120 msIf any audit regressed, flag it in red and do not proceed to further edits — ask the user how to handle.
Append .speed-fix/<ISO-ts>.md to the project with:
advisory items/tmp/speed-fix/ (for later diffing)Ensure .speed-fix/ is in .gitignore — if not, prepend it.
audits.md — PSI audit id → remediation mapping. Consult this in step 4.playbooks.md — per-stack recipes. Consult this in steps 5 and 8.browserslist, aliasing polyfill-module, setting experimental.inlineCss) have non-obvious blast radius. A user-reviewed plan catches mistakes the skill can't.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.