opencode-skills-collection 3.0.46 → 3.0.47

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.
Files changed (71) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +10 -1
  2. package/bundled-skills/2slides-ppt-generator/SKILL.md +1 -1
  3. package/bundled-skills/2slides-ppt-generator/scripts/create_pdf_slides.py +2 -1
  4. package/bundled-skills/2slides-ppt-generator/scripts/generate_narration.py +2 -1
  5. package/bundled-skills/2slides-ppt-generator/scripts/generate_slides.py +13 -7
  6. package/bundled-skills/android-dev/references/hybrid.md +7 -4
  7. package/bundled-skills/android-dev/references/react-native.md +5 -2
  8. package/bundled-skills/atlas-contract/SKILL.md +4 -4
  9. package/bundled-skills/atlas-ledger/SKILL.md +10 -7
  10. package/bundled-skills/bun-development/SKILL.md +1 -1
  11. package/bundled-skills/cloud-penetration-testing/SKILL.md +1 -1
  12. package/bundled-skills/codebase-to-wordpress-converter/SKILL.md +1 -0
  13. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  14. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  15. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  16. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  17. package/bundled-skills/docs/users/bundles.md +1 -1
  18. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  19. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  20. package/bundled-skills/docs/users/getting-started.md +1 -1
  21. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  22. package/bundled-skills/docs/users/usage.md +4 -4
  23. package/bundled-skills/docs/users/visual-guide.md +4 -4
  24. package/bundled-skills/dos-verify-done-claims/SKILL.md +173 -0
  25. package/bundled-skills/ecl-harness-engineer/LICENSE +21 -0
  26. package/bundled-skills/ecl-harness-engineer/SKILL.md +714 -0
  27. package/bundled-skills/ecl-harness-engineer/agents/analyzer.md +119 -0
  28. package/bundled-skills/ecl-harness-engineer/agents/auditor.md +212 -0
  29. package/bundled-skills/ecl-harness-engineer/agents/creator-config.md +343 -0
  30. package/bundled-skills/ecl-harness-engineer/agents/creator-docs.md +201 -0
  31. package/bundled-skills/ecl-harness-engineer/agents/creator-linters.md +123 -0
  32. package/bundled-skills/ecl-harness-engineer/references/adapters/adapter-schema.md +204 -0
  33. package/bundled-skills/ecl-harness-engineer/references/adapters/generic.md +156 -0
  34. package/bundled-skills/ecl-harness-engineer/references/adapters/go.md +212 -0
  35. package/bundled-skills/ecl-harness-engineer/references/adapters/java.md +205 -0
  36. package/bundled-skills/ecl-harness-engineer/references/adapters/python.md +225 -0
  37. package/bundled-skills/ecl-harness-engineer/references/adapters/rust.md +220 -0
  38. package/bundled-skills/ecl-harness-engineer/references/adapters/typescript.md +245 -0
  39. package/bundled-skills/ecl-harness-engineer/references/architecture-diagrams.md +420 -0
  40. package/bundled-skills/ecl-harness-engineer/references/audit-templates.md +649 -0
  41. package/bundled-skills/ecl-harness-engineer/references/capability-registry.md +485 -0
  42. package/bundled-skills/ecl-harness-engineer/references/darwin-eval-prompts.md +373 -0
  43. package/bundled-skills/ecl-harness-engineer/references/documentation-templates.md +741 -0
  44. package/bundled-skills/ecl-harness-engineer/references/durability-patterns.md +423 -0
  45. package/bundled-skills/ecl-harness-engineer/references/ecl-harness.md +1431 -0
  46. package/bundled-skills/ecl-harness-engineer/references/environment-config-guide.md +534 -0
  47. package/bundled-skills/ecl-harness-engineer/references/environment-detection-guide.md +751 -0
  48. package/bundled-skills/ecl-harness-engineer/references/eval-templates.md +377 -0
  49. package/bundled-skills/ecl-harness-engineer/references/gc-templates.md +798 -0
  50. package/bundled-skills/ecl-harness-engineer/references/greenfield-templates.md +1385 -0
  51. package/bundled-skills/ecl-harness-engineer/references/linter-templates.md +448 -0
  52. package/bundled-skills/ecl-harness-engineer/references/observability-templates.md +315 -0
  53. package/bundled-skills/environment-setup-guide/SKILL.md +2 -2
  54. package/bundled-skills/evolution/SKILL.md +1 -1
  55. package/bundled-skills/gitops-workflow/SKILL.md +1 -1
  56. package/bundled-skills/linkerd-patterns/SKILL.md +1 -1
  57. package/bundled-skills/loki-mode/examples/todo-app-generated/frontend/package-lock.json +504 -1317
  58. package/bundled-skills/loki-mode/examples/todo-app-generated/frontend/package.json +2 -2
  59. package/bundled-skills/lovable-cleanup/SKILL.md +416 -0
  60. package/bundled-skills/monopoly/SKILL.md +397 -0
  61. package/bundled-skills/monopoly/patterns/SKILL.md +331 -0
  62. package/bundled-skills/monopoly/scale-benchmarks/SKILL.md +174 -0
  63. package/bundled-skills/monopoly/security-checklist/SKILL.md +69 -0
  64. package/bundled-skills/monopoly/tech-matrix/SKILL.md +268 -0
  65. package/bundled-skills/pagespeed-enhancer/SKILL.md +579 -0
  66. package/bundled-skills/polis-protocol/SKILL.md +6 -3
  67. package/bundled-skills/unship/SKILL.md +11 -5
  68. package/bundled-skills/uv-package-manager/resources/implementation-playbook.md +1 -1
  69. package/bundled-skills/varlock/SKILL.md +2 -2
  70. package/package.json +1 -1
  71. package/skills_index.json +204 -4
@@ -0,0 +1,579 @@
1
+ ---
2
+ name: pagespeed-enhancer
3
+ description: "Scan, audit, and fix web performance issues across all four Lighthouse/PageSpeed Insights pillars — Performance, Accessibility, Best Practices, and SEO — in structured batches."
4
+ risk: safe
5
+ source: personal
6
+ date_added: "2026-06-14"
7
+ author: WHOISABHISHEKADHIKARI
8
+ ---
9
+
10
+ # PageSpeed Enhancer Skill
11
+
12
+ A structured, batch-wise audit-and-fix workflow for all four Lighthouse pillars. Always follow the batch flow in order. Never jump straight to fixes without completing the scan and risk assessment phases.
13
+
14
+ ---
15
+
16
+ ## When to Use This Skill
17
+
18
+ - User pastes a PageSpeed Insights report or mentions Lighthouse scores
19
+ - User asks to improve Core Web Vitals (LCP, FCP, CLS, TBT, SI)
20
+ - User needs help with render-blocking resources, unused JavaScript, image optimisation, security headers, ARIA compliance, or SEO meta-tag fixes
21
+ - User asks "why is my LCP slow", "fix accessibility issues", "improve my SEO score", or "my site scores 80 on performance"
22
+ - Any mention of PageSpeed, Lighthouse, Web Vitals, or site speed
23
+
24
+ ---
25
+
26
+ ## High-Level Workflow
27
+
28
+ ```
29
+ PHASE 1 → Ingest Report & Parse Scores
30
+ PHASE 2 → Batch Scan (4 sections, parallel analysis)
31
+ PHASE 3 → Consolidated Risk Report (changes ranked by impact vs risk)
32
+ PHASE 4 → Fix Batches (applied in safe order: low-risk → high-risk)
33
+ PHASE 5 → Verification Checklist
34
+ ```
35
+
36
+ ---
37
+
38
+ ## PHASE 1 — Ingest & Classify
39
+
40
+ When the user provides a PageSpeed Insights report (pasted text, screenshot, or URL):
41
+
42
+ 1. Extract the four pillar scores: Performance, Accessibility, Best Practices, SEO.
43
+ 2. Extract each flagged metric with its value and Lighthouse weight.
44
+ 3. Identify the **critical path bottleneck** (the single issue most responsible for the lowest pillar score).
45
+ 4. Output a **Score Summary Table**:
46
+
47
+ ```
48
+ | Pillar | Score | Status | Critical Issue |
49
+ |-----------------|-------|---------|-------------------------------------|
50
+ | Performance | 80 | ⚠️ Warn | LCP 4.0s — element render delay |
51
+ | Accessibility | 100 | ✅ Pass | — |
52
+ | Best Practices | 100 | ✅ Pass | CSP missing (unscored) |
53
+ | SEO | 100 | ✅ Pass | — |
54
+ ```
55
+
56
+ Then proceed immediately to Phase 2 without waiting for user input unless the report is ambiguous.
57
+
58
+ ---
59
+
60
+ ## PHASE 2 — Batch Scan (4 Sections)
61
+
62
+ Run all four section scans. Present as collapsible sections in output.
63
+
64
+ ### Batch A — Performance Scan
65
+
66
+ Audit these in order (highest Lighthouse weight first):
67
+
68
+ | Audit | Metric Impact | Key Questions |
69
+ |-------|--------------|---------------|
70
+ | LCP breakdown | LCP | Is the LCP element lazily loaded? Is TTFB > 600ms? Is element render delay > 1s? |
71
+ | Render-blocking resources | FCP, LCP | Which CSS/JS files block the critical path? Can they be deferred or inlined? |
72
+ | CSS `@import` rules | FCP, LCP | Are external stylesheets loaded via `@import url()` in CSS? This is **2x render-blocking** — browser must fetch CSS, parse it, then fetch imported CSS. Use `<link>` instead. |
73
+ | Unused JavaScript | FCP, LCP, TBT | What % of the main bundle is unused? Is code-splitting possible? |
74
+ | Network dependency tree | LCP | What is the critical path chain? Max latency? |
75
+ | Forced reflows | TBT | Which JS functions query geometry after DOM mutation? |
76
+ | Image delivery | FCP, LCP | Are images in WebP/AVIF? Are above-fold images lazy-loaded? |
77
+ | Speed Index | SI | Is page visually progressive or does it paint all at once? |
78
+ | CLS culprits | CLS | Any images without width/height? Any late-injected content? |
79
+ | JavaScript execution time | TBT | Total parse + compile + evaluate time? |
80
+ | Long main-thread tasks | TBT | Tasks > 50ms? Starting when? |
81
+ | Bundled asset sizes | FCP, LCP, TBT | Check `dist/` output: any single JS chunk > 500KB gzipped? CSS > 100KB? Code-splitting creating proper vendor chunks? |
82
+
83
+ For each audit item, output:
84
+ - **Finding**: What the report says
85
+ - **Root Cause**: Why it's happening
86
+ - **Fix Category**: Quick Win / Medium Effort / Refactor Required
87
+
88
+ ### Batch B — Accessibility Scan
89
+
90
+ Focus on any failed audits. For a 100-score page, still check:
91
+
92
+ | Check | What to Verify |
93
+ |-------|---------------|
94
+ | ARIA attribute correctness | All `aria-*` attributes match element roles |
95
+ | Colour contrast | All text meets WCAG AA (4.5:1 normal, 3:1 large) |
96
+ | Image alt text quality | Alt text is descriptive, not filename-style |
97
+ | Keyboard navigation | All interactive elements reachable by Tab |
98
+ | Skip links | Present and focusable |
99
+ | Heading hierarchy | No skipped levels (h1 → h2 → h3) |
100
+ | Touch target size | Min 44×44px on mobile |
101
+ | Form labels | Every input has an associated label |
102
+ | `lang` attribute | `<html lang="en">` present and valid BCP 47 |
103
+ | `font-display` | Set to `swap` or `optional` to prevent FOIT |
104
+
105
+ ### Batch C — Best Practices Scan
106
+
107
+ Security headers are often unflagged by Lighthouse score but are critical. Check ALL deployment targets:
108
+
109
+ | Check | Header/Setting | Where to Configure | Severity |
110
+ |-------|---------------|-------------------|----------|
111
+ | Content Security Policy | `Content-Security-Policy` | `netlify.toml` `[[headers]]` / `vercel.json` `"headers"` | 🔴 High |
112
+ | Cross-Origin-Opener-Policy | `COOP` header | Same as above | 🔴 High |
113
+ | Clickjacking protection | `X-Frame-Options` or CSP `frame-ancestors` | Same as above | 🔴 High |
114
+ | HSTS configuration | `Strict-Transport-Security` with `includeSubDomains` + `preload` | Same as above | 🟡 Medium |
115
+ | Trusted Types (DOM XSS) | CSP `require-trusted-types-for 'script'` | Same as above | 🟡 Medium |
116
+ | X-Content-Type-Options | `nosniff` header | Same as above | 🟡 Medium |
117
+ | Referrer-Policy | `strict-origin-when-cross-origin` | Same as above | 🟡 Medium |
118
+ | Permissions-Policy | Restrict camera/mic/geolocation | Same as above | 🟡 Medium |
119
+ | Third-party cookies | Any `SameSite=None` cookies without `Secure`? | — | 🟡 Medium |
120
+ | Deprecated APIs | Any browser-deprecated JS APIs in use? | — | 🟢 Low |
121
+ | Source maps | Are source maps deployed for debugging? | — | 🟢 Low |
122
+
123
+ When both `netlify.toml` and `vercel.json` exist, check BOTH. Each has a different syntax (TOML vs JSON).
124
+
125
+ ### Batch D — SEO Scan
126
+
127
+ | Check | What to Verify |
128
+ |-------|---------------|
129
+ | `<title>` tag | Present, 50–60 chars, includes primary keyword |
130
+ | Meta description | Present, 150–160 chars, compelling |
131
+ | Canonical tag | `<link rel="canonical">` points to correct URL |
132
+ | hreflang | Present if multilingual; correct language codes |
133
+ | robots.txt | Valid, not blocking key resources |
134
+ | Structured data | JSON-LD present; run Schema validator |
135
+ | Image alt attributes | Every `<img>` has meaningful alt |
136
+ | Link descriptiveness | No "click here" / "read more" link text |
137
+ | Crawlability | No `noindex` on important pages |
138
+ | HTTP status | 200 on main page and critical resources |
139
+ | SPA meta injection | If using react-helmet-async / Next.js Head: verify via "View Page Source", not DevTools Elements — meta tags may be JS-injected |
140
+
141
+ ---
142
+
143
+ ## PHASE 3 — Risk Report
144
+
145
+ After completing all four batch scans, output a consolidated **Risk vs Impact Matrix**:
146
+
147
+ ```
148
+ | Fix | Impact Score | Risk Level | Effort | Priority |
149
+ |----------------------------------|-------------|------------|----------|----------|
150
+ | Add defer/async to non-critical JS | High (LCP -0.8s est) | 🟢 Low | 1h | P1 |
151
+ | Convert images to WebP/AVIF | Medium (LCP -0.3s) | 🟢 Low | 2h | P1 |
152
+ | Add CSP header | Security | 🟡 Medium | 3h | P2 |
153
+ | Code-split main JS bundle | High (TBT -20ms) | 🟡 Medium | 1 day | P2 |
154
+ | Fix forced reflows | Medium (TBT -15ms) | 🔴 High | 2 days | P3 |
155
+ | Add HSTS preload | Security | 🟡 Medium | 30min | P2 |
156
+ ```
157
+
158
+ **Risk Level Definitions:**
159
+ - 🟢 Low: Config/header change, no code change. Rollback in < 5 min.
160
+ - 🟡 Medium: Build config or asset pipeline change. Test in staging first.
161
+ - 🔴 High: JavaScript refactor, architectural change. Requires full QA cycle.
162
+
163
+ Always recommend: fix P1 (Low Risk, High Impact) items first, then P2, then P3.
164
+
165
+ ---
166
+
167
+ ## PHASE 4 — Fix Batches
168
+
169
+ Apply fixes in risk order. For each fix, provide:
170
+
171
+ 1. **What to change** — file, line, specific change
172
+ 2. **Before** (code snippet)
173
+ 3. **After** (code snippet)
174
+ 4. **Expected metric improvement** — estimated delta
175
+ 5. **How to verify** — what to check after deploying
176
+
177
+ ### Fix Batch 1 — Quick Wins (Low Risk, deploy immediately)
178
+
179
+ Examples from common audits:
180
+
181
+ **F1.1 — Move CSS `@import` to `<link>` tag**
182
+
183
+ CSS `@import url()` is 2x render-blocking. Move to `<link>` in `<head>`:
184
+
185
+ ```css
186
+ /* Before: in index.css */
187
+ @import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');
188
+ ```
189
+
190
+ ```html
191
+ <!-- After: in index.html <head> -->
192
+ <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter&display=swap" />
193
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter&display=swap" media="print" onload="this.media='all'" />
194
+ <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter&display=swap" /></noscript>
195
+ ```
196
+
197
+ **F1.2 — Defer render-blocking CSS (if not above-fold critical)**
198
+ ```html
199
+ <!-- Before -->
200
+ <link rel="stylesheet" href="/assets/index.css">
201
+
202
+ <!-- After: load async, apply on load -->
203
+ <link rel="preload" href="/assets/index.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
204
+ <noscript><link rel="stylesheet" href="/assets/index.css"></noscript>
205
+ ```
206
+
207
+ **F1.3 — Fix broken preconnect (crossorigin mismatch)**
208
+ ```html
209
+ <!-- Before (broken — no crossorigin on font CDN) -->
210
+ <link rel="preconnect" href="https://api.rss2json.com">
211
+
212
+ <!-- After -->
213
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
214
+ <!-- Only preconnect origins used in critical path, max 4 -->
215
+ ```
216
+
217
+ **F1.4 — Convert images to WebP**
218
+ ```bash
219
+ # Using cwebp
220
+ cwebp -q 80 input.jpeg -o output.webp
221
+
222
+ # Using sharp (Node.js)
223
+ sharp('image.jpeg').webp({ quality: 80 }).toFile('image.webp')
224
+
225
+ # macOS fallback (sips built-in)
226
+ sips -s format webp input.jpeg --out output.webp
227
+
228
+ # Python Pillow fallback
229
+ python3 -c "
230
+ from PIL import Image
231
+ Image.open('input.jpg').save('output.webp', 'WebP', quality=80)
232
+ "
233
+ ```
234
+
235
+ **F1.5 — Add explicit image dimensions (CLS fix)**
236
+ ```html
237
+ <!-- Before -->
238
+ <img src="hero.webp" alt="...">
239
+
240
+ <!-- After -->
241
+ <img src="hero.webp" alt="..." width="800" height="400">
242
+ ```
243
+
244
+ **F1.6 — Add security headers (netlify.toml)**
245
+ ```toml
246
+ [[headers]]
247
+ for = "/*"
248
+ [headers.values]
249
+ X-Frame-Options = "DENY"
250
+ X-Content-Type-Options = "nosniff"
251
+ Referrer-Policy = "strict-origin-when-cross-origin"
252
+ Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload"
253
+ Cross-Origin-Opener-Policy = "same-origin"
254
+ Permissions-Policy = "camera=(), microphone=(), geolocation=()"
255
+ Content-Security-Policy = "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://api.rss2json.com"
256
+ ```
257
+
258
+ **F1.7 — Add security headers (vercel.json)**
259
+ ```json
260
+ {
261
+ "headers": [
262
+ {
263
+ "source": "/(.*)",
264
+ "headers": [
265
+ { "key": "X-Frame-Options", "value": "DENY" },
266
+ { "key": "X-Content-Type-Options", "value": "nosniff" },
267
+ { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
268
+ { "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains; preload" },
269
+ { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
270
+ { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" },
271
+ { "key": "Content-Security-Policy", "value": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://api.rss2json.com" }
272
+ ]
273
+ }
274
+ ]
275
+ }
276
+ ```
277
+
278
+ **F1.8 — Self-host Google Fonts (eliminate external CSS request)**
279
+
280
+ Download woff2 files and serve them locally to remove the Google Fonts CSS round-trip entirely:
281
+
282
+ ```bash
283
+ # 1. Download woff2 files from Google Fonts CSS URL
284
+ # Open https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap
285
+ # in a browser, then download each woff2 URL listed in the @font-face blocks.
286
+
287
+ # 2. Place files in public/fonts/ or src/assets/fonts/
288
+ public/fonts/
289
+ inter-v12-latin-400.woff2
290
+ inter-v12-latin-700.woff2
291
+
292
+ # 3. Add @font-face CSS (load once, no external request)
293
+ ```
294
+
295
+ ```css
296
+ /* src/styles/fonts.css */
297
+ @font-face {
298
+ font-family: 'Inter';
299
+ font-style: normal;
300
+ font-weight: 400;
301
+ font-display: swap;
302
+ src: url('/fonts/inter-v12-latin-400.woff2') format('woff2');
303
+ }
304
+
305
+ @font-face {
306
+ font-family: 'Inter';
307
+ font-style: normal;
308
+ font-weight: 700;
309
+ font-display: swap;
310
+ src: url('/fonts/inter-v12-latin-700.woff2') format('woff2');
311
+ }
312
+ ```
313
+
314
+ ```css
315
+ /* Remove the old Google Fonts <link> from index.html */
316
+ /* Before: */
317
+ <link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet">
318
+
319
+ /* After: just use the font-family normally */
320
+ body { font-family: 'Inter', sans-serif; }
321
+ ```
322
+
323
+ **Result:** Zero external CSS requests, faster FCP/LCP, no FOIT risk, and works offline.
324
+
325
+ **F1.9 — Resize oversized icons**
326
+
327
+ Icons (favicon, apple-touch-icon, OG image) should never be > 50KB. Check and resize:
328
+ ```bash
329
+ python3 -c "
330
+ from PIL import Image
331
+ img = Image.open('favicon.png')
332
+ img.resize((192, 192)).save('favicon.png', 'PNG', optimize=True)
333
+ img.resize((32, 32)).save('favicon-32x32.png', 'PNG', optimize=True)
334
+ img.resize((16, 16)).save('favicon-16x16.png', 'PNG', optimize=True)
335
+ "
336
+ ```
337
+
338
+ ### Fix Batch 2 — Medium Effort (staging test recommended)
339
+
340
+ **F2.1 — Remove LCP element lazy loading**
341
+
342
+ The LCP element must NEVER be lazy-loaded:
343
+ ```html
344
+ <!-- Before: wrong — LCP image is lazy -->
345
+ <img src="hero.webp" loading="lazy" ...>
346
+
347
+ <!-- After: eager load the above-fold LCP element -->
348
+ <img src="hero.webp" loading="eager" fetchpriority="high" ...>
349
+ ```
350
+
351
+ **F2.2 — Preload LCP image**
352
+
353
+ ⚠️ Only works for files in `public/` or with stable URLs. If using Vite/Webpack (content-hashed filenames), use `<picture>` + `fetchPriority="high"` instead:
354
+ ```html
355
+ <!-- For stable URLs (public/ directory): -->
356
+ <link rel="preload" as="image" href="/hero.webp" fetchpriority="high">
357
+
358
+ <!-- For hashed filenames (Vite/Rollup): use component-level approach -->
359
+ <picture>
360
+ <source srcSet={webpImage} type="image/webp" />
361
+ <img src={jpgImage} fetchPriority="high" loading="eager" width="1920" height="1080" />
362
+ </picture>
363
+ ```
364
+
365
+ **F2.3 — Reduce unused JS (Vite/Rollup config)**
366
+ ```js
367
+ // vite.config.js — enable manual chunking
368
+ build: {
369
+ rollupOptions: {
370
+ output: {
371
+ manualChunks: {
372
+ vendor: ['react', 'react-dom'],
373
+ rss: ['rss-parser'],
374
+ }
375
+ }
376
+ }
377
+ }
378
+ ```
379
+
380
+ **F2.4 — Eliminate forced reflows**
381
+ ```js
382
+ // Before: reads layout property inside animation loop
383
+ element.addEventListener('scroll', () => {
384
+ const h = element.offsetHeight; // triggers reflow
385
+ doSomething(h);
386
+ });
387
+
388
+ // After: cache geometry reads outside event handlers
389
+ const h = element.offsetHeight; // read once
390
+ element.addEventListener('scroll', () => {
391
+ doSomething(h);
392
+ });
393
+ ```
394
+
395
+ **F2.5 — Optimise DOM size**
396
+
397
+ If DOM > 1,500 elements:
398
+ - Use virtual scrolling for long lists (react-virtual, TanStack Virtual)
399
+ - Lazy-render off-screen sections
400
+ - Remove hidden/display:none nodes that never become visible
401
+
402
+ ### Fix Batch 3 — Refactor Required (full QA cycle)
403
+
404
+ **F3.1 — External API in critical path (e.g. api.rss2json.com)**
405
+
406
+ Current: HTML → JS bundle → external API (adds 1,574ms to critical path)
407
+
408
+ Solution: Move external API calls to build time or server-side:
409
+ ```js
410
+ // Option A: Fetch at build time (Astro/Next.js SSG)
411
+ export async function getStaticProps() {
412
+ const res = await fetch('https://api.rss2json.com/v1/api.json?rss_url=...');
413
+ const data = await res.json();
414
+ return { props: { posts: data.items }, revalidate: 3600 };
415
+ }
416
+
417
+ // Option B: Edge function / serverless proxy
418
+ // Cache RSS response at CDN edge, return stale-while-revalidate
419
+ ```
420
+
421
+ **F3.2 — Content Security Policy (full CSP)**
422
+
423
+ Build the CSP iteratively:
424
+ 1. Deploy in report-only mode first: `Content-Security-Policy-Report-Only`
425
+ 2. Check browser console for violations for 48h
426
+ 3. Whitelist required origins
427
+ 4. Promote to enforcement mode
428
+
429
+ ---
430
+
431
+ ## PRE-DEPLOY GATE
432
+
433
+ Before deploying any fix batch, run these checks:
434
+
435
+ ```
436
+ Build:
437
+ □ npm run build (or equivalent) — exits 0
438
+ □ npm run lint / typecheck — no new errors vs baseline
439
+ □ Inspect dist/ output:
440
+ - No single JS chunk > 500KB (gzipped)
441
+ - CSS < 100KB
442
+ - Code-splitting created separate vendor chunks
443
+
444
+ Asset verification:
445
+ □ For Vite/Rollup/Webpack: preload <link> in index.html won't match hashed filenames.
446
+ Use fetchPriority="high" + <picture> on the component instead.
447
+ □ Favicons and icons are < 50KB each (not multi-MB source images used as icons)
448
+ □ WebP/AVIF versions exist alongside originals
449
+
450
+ Deploy target:
451
+ □ If dual-deployed (Netlify + Vercel), verify headers on BOTH
452
+ □ If using SPA framework: verify meta tags via "View Page Source", not DevTools Elements
453
+ (react-helmet-async injects at runtime — check prerendered/SSR output)
454
+ ```
455
+
456
+ ---
457
+
458
+ ## PHASE 5 — Verification Checklist
459
+
460
+ After deploying each fix batch, verify:
461
+
462
+ ```
463
+ Performance:
464
+ □ Re-run PageSpeed Insights on mobile AND desktop
465
+ □ LCP < 2.5s (Good)
466
+ □ FCP < 1.8s (Good)
467
+ □ TBT < 200ms (Good)
468
+ □ CLS < 0.1 (Good)
469
+ □ SI < 3.4s (Good)
470
+
471
+ Accessibility:
472
+ □ Run axe DevTools browser extension
473
+ □ Navigate page with keyboard only (Tab, Shift+Tab, Enter, Space)
474
+ □ Test with screen reader (NVDA/VoiceOver)
475
+ □ Check contrast with browser DevTools accessibility panel
476
+
477
+ Best Practices:
478
+ □ Verify security headers at https://securityheaders.com
479
+ □ Check HTTPS: no mixed content warnings in DevTools
480
+ □ Run Lighthouse Best Practices audit again
481
+
482
+ SEO:
483
+ □ Validate structured data at https://search.google.com/test/rich-results
484
+ □ Check robots.txt at /robots.txt
485
+ □ Verify canonical tag in page source (View Source, not DevTools)
486
+ □ Submit updated sitemap to Google Search Console
487
+ ```
488
+
489
+ ---
490
+
491
+ ## Output Format Conventions
492
+
493
+ - Always label outputs: **[SCAN]**, **[RISK]**, **[FIX]**, **[VERIFY]**
494
+ - Use emoji severity indicators: 🔴 Critical / 🟡 Warning / 🟢 Pass / ℹ️ Info
495
+ - Always show "Before" and "After" code for every fix
496
+ - Always include estimated metric delta (e.g. "Est. LCP improvement: -0.8s")
497
+ - Never suggest fixes that conflict with each other — sequence matters
498
+
499
+ ---
500
+
501
+ ## Quick Reference: Metric Thresholds
502
+
503
+ | Metric | Good | Needs Work | Poor |
504
+ |--------|------|-----------|------|
505
+ | FCP | < 1.8s | 1.8–3.0s | > 3.0s |
506
+ | LCP | < 2.5s | 2.5–4.0s | > 4.0s |
507
+ | TBT | < 200ms | 200–600ms | > 600ms |
508
+ | CLS | < 0.1 | 0.1–0.25 | > 0.25 |
509
+ | SI | < 3.4s | 3.4–5.8s | > 5.8s |
510
+
511
+ ---
512
+
513
+ ## Examples
514
+
515
+ ### Example 1: User pastes a PageSpeed report
516
+
517
+ **User:** "My site scores 65 on Performance. LCP is 4.2s."
518
+
519
+ **Agent:**
520
+ 1. Parses the score summary table — identifies LCP as critical bottleneck
521
+ 2. Runs Batch A scan — finds lazy-loaded hero image and render-blocking CSS
522
+ 3. Outputs risk report: F1.1 (CSS @import → link) ranked P1, F1.5 (LCP image eager) ranked P1
523
+ 4. Applies Fix Batch 1, verifies with re-test
524
+
525
+ ### Example 2: User asks about slow LCP
526
+
527
+ **User:** "Why is my LCP slow?"
528
+
529
+ **Agent:**
530
+ 1. Asks for a PageSpeed report URL or pasted results
531
+ 2. Runs LCP-specific audit from Batch A — checks TTFB, element render delay, lazy loading
532
+ 3. Identifies the LCP element, its current loading strategy, and the critical path chain
533
+ 4. Recommends targeted fix (preload, eager loading, or server response time improvement)
534
+
535
+ ---
536
+
537
+ ## Limitations
538
+
539
+ - Does not run actual Lighthouse or PageSpeed tests — the user must provide the report or URL
540
+ - Security header recommendations assume the user controls the deployment platform (Netlify, Vercel, etc.)
541
+ - Fixes are general patterns; exact file paths and config syntax may vary by project setup
542
+ - Does not cover server-level optimisations (CDN config, PHP opcode caching, database queries, etc.)
543
+ - Image conversion commands assume the user has the required tools installed (cwebp, sharp, Pillow)
544
+ - CSP guidance uses a report-only iterative approach — the final policy must be tuned to each project's actual resource origins
545
+
546
+ ---
547
+
548
+ ## Change Log & Revert Checklist
549
+
550
+ After each fix batch, log what changed and whether it caused build failures:
551
+
552
+ | Fix | File(s) Modified | Build Pass? | Errors | Revert Steps |
553
+ |-----|-----------------|-------------|--------|-------------|
554
+ | F1.1 — CSS @import → `<link>` | `index.html`, `src/styles/*.css` | □ Yes □ No | | Restore original `<link>` tags |
555
+ | F1.2 — Defer render-blocking CSS | `index.html` | □ Yes □ No | | Remove `media="print"` + `onload` |
556
+ | F1.4 — WebP conversion | `public/images/*.webp` | □ Yes □ No | | Delete .webp files, restore originals |
557
+ | F1.5 — Image dimensions | `src/components/*.tsx` | □ Yes □ No | | Remove `width`/`height`/`loading` attrs |
558
+ | F1.6 — Security headers (Netlify) | `netlify.toml` | □ Yes □ No | | Delete the `[[headers]]` block |
559
+ | F1.7 — Security headers (Vercel) | `vercel.json` | □ Yes □ No | | Remove the `"headers"` array entry |
560
+ | F1.8 — Self-host fonts | `public/fonts/*.woff2`, `src/styles/fonts.css`, `index.html` | □ Yes □ No | | Delete font files, remove `@font-face`, restore Google Fonts `<link>` |
561
+ | F1.9 — Resize icons | `public/favicon*`, `public/apple-touch-icon*`, `public/og-image*` | □ Yes □ No | | Restore original icon files |
562
+ | F2.1 — LCP eager loading | `src/components/*.tsx` | □ Yes □ No | | Change `loading="eager"` back to `loading="lazy"` |
563
+ | F2.2 — Preload LCP image | `index.html` or `src/components/*.tsx` | □ Yes □ No | | Remove `<link rel="preload">` or revert `<picture>` |
564
+ | F2.3 — Code-split JS | `vite.config.ts` | □ Yes □ No | | Remove `manualChunks` config |
565
+ | F2.4 — Fix forced reflows | `src/**/*.ts` | □ Yes □ No | | Revert geometry caching changes |
566
+ | F2.5 — Optimise DOM | `src/components/*.tsx` | □ Yes □ No | | Restore removed hidden nodes |
567
+ | F3.1 — External API to build time | `src/**/*.ts`, config files | □ Yes □ No | | Restore client-side fetch |
568
+ | F3.2 — CSP headers | `netlify.toml` / `vercel.json` | □ Yes □ No | | Remove or relax CSP directives |
569
+
570
+ If **Build Pass?** is **No**, run `npm run build` to see the exact error, revert the failed fix immediately, and re-test before applying the next batch.
571
+
572
+ ---
573
+
574
+ ## References
575
+
576
+ See `references/` for deep-dives:
577
+ - `references/performance-deep-dive.md` — LCP, CLS, TBT root cause trees
578
+ - `references/security-headers.md` — Complete CSP/HSTS/COOP reference
579
+ - `references/image-optimization.md` — WebP/AVIF conversion pipelines
@@ -37,16 +37,19 @@ In Antigravity specifically, this turns Manager View's fixed pipeline into a tea
37
37
 
38
38
  ### Step 1: Found a polis
39
39
 
40
- Run the published CLI `uvx` fetches the latest release from PyPI ([polis-protocol](https://pypi.org/project/polis-protocol/)), so you always get the current version:
40
+ Use a reviewed checkout by default so the scaffolder code is pinned before it writes into the project:
41
41
 
42
42
  ```bash
43
- uvx polis-protocol init \
43
+ git clone https://github.com/yehudalevy-collab/polis-protocol.git
44
+ cd polis-protocol
45
+ git checkout <reviewed-commit-sha>
46
+ python3 scripts/init_polis.py \
44
47
  --project-root . \
45
48
  --agent-id gemini-antigravity-yourproject \
46
49
  --vendor google --model gemini-3 --tool antigravity
47
50
  ```
48
51
 
49
- (Prefer a pinned, reviewed install? `pipx install polis-protocol==<version>`, or clone the repo and run `python3 scripts/init_polis.py` with the same flags.)
52
+ If you prefer the published PyPI package, install an exact version after reviewing that release, for example `pipx install polis-protocol==<reviewed-version>`. Do not invoke the package through an unpinned `uvx` or "latest" workflow for automated setup.
50
53
 
51
54
  This writes `_polis/` plus the skill into `.agents/skills/` (the path Antigravity reads), and bridge pointers (`GEMINI.md`, `AGENTS.md`) that point every tool at `_polis/CONSTITUTION.md`. Tip: add `--dry-run` to preview every file before anything is written; init never overwrites existing files, and `polis init --repair` restores missing ones.
52
55
 
@@ -2,7 +2,7 @@
2
2
  name: unship
3
3
  description: "Compare AI agent-made UI variants locally in a real app, then keep one and clean up unused temporary code."
4
4
  category: development
5
- risk: safe
5
+ risk: critical
6
6
  source: community
7
7
  source_repo: mbenhard/unship
8
8
  source_type: community
@@ -12,6 +12,10 @@ tags: [ui-variants, frontend, local-first, coding-agents]
12
12
  tools: [claude-code, antigravity, cursor, gemini-cli, codex-cli, opencode]
13
13
  license: "MIT"
14
14
  license_source: "https://github.com/mbenhard/unship/blob/main/LICENSE"
15
+ plugin:
16
+ targets:
17
+ codex: blocked
18
+ claude: blocked
15
19
  ---
16
20
 
17
21
  # Unship
@@ -44,16 +48,17 @@ Prefer the project-local binary when it exists:
44
48
  ./node_modules/.bin/unship doctor --json --no-update-check
45
49
  ```
46
50
 
47
- Otherwise use the npm package without assuming a global binary:
51
+ Otherwise install a reviewed, exact CLI version into the project and then run the local binary:
48
52
 
49
53
  ```bash
50
- npx -y @unship/cli@latest doctor --json --no-update-check
54
+ npm install --save-dev @unship/cli@<reviewed-version>
55
+ ./node_modules/.bin/unship doctor --json --no-update-check
51
56
  ```
52
57
 
53
58
  If setup is needed for the local picker, run:
54
59
 
55
60
  ```bash
56
- npx -y @unship/cli@latest setup --json
61
+ ./node_modules/.bin/unship setup --json
57
62
  ```
58
63
 
59
64
  Patch only the smallest development-only mount point required to load the picker in the local preview.
@@ -95,7 +100,7 @@ When the user picks a winner, keep that option's real source and remove losing o
95
100
  For final cleanup before shipping, remove all Unship artifacts and run:
96
101
 
97
102
  ```bash
98
- npx -y @unship/cli@latest check --json
103
+ ./node_modules/.bin/unship check --json
99
104
  ```
100
105
 
101
106
  Do not claim cleanup is complete until the check reports clean.
@@ -117,6 +122,7 @@ Do not claim cleanup is complete until the check reports clean.
117
122
  ## Security & Safety Notes
118
123
 
119
124
  - Run commands only in a local project the user has authorized you to modify.
125
+ - Do not run `npx @unship/cli@latest` or any unpinned remote CLI in automated agent workflows. Pin and review the package version first, then execute the project-local binary.
120
126
  - Treat generated variants as temporary code that must be cleaned before release.
121
127
  - Before destructive cleanup, confirm the selected option label when the user's choice is ambiguous.
122
128
  - If a baseline build or typecheck already fails before Unship edits, report that baseline state and keep variant work isolated.
@@ -54,7 +54,7 @@ Comprehensive guide to using uv, an extremely fast Python package installer and
54
54
  tmpdir="$(mktemp -d)"
55
55
  trap 'rm -rf "$tmpdir"' EXIT
56
56
  curl -LsSf https://astral.sh/uv/install.sh -o "$tmpdir/uv-install.sh"
57
- sed -n '1,160p' "$tmpdir/uv-install.sh"
57
+ cat "$tmpdir/uv-install.sh" # review the full installer before executing
58
58
  sh "$tmpdir/uv-install.sh"
59
59
 
60
60
  # Windows (PowerShell)