From vibe-check
Scan web projects for AI-generated slop patterns in styling and content
How this skill is triggered — by the user, by Claude, or both
Slash command
/vibe-check:slop-checkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Scan a web project for AI-generated "slop" -- telltale patterns of low-effort, template-driven styling and content produced by AI code generators.
Scan a web project for AI-generated "slop" -- telltale patterns of low-effort, template-driven styling and content produced by AI code generators.
Follow these steps precisely when the user invokes /slop-check.
Use the Glob tool to search for **/vibe-check/dist/index.js to find the scanner binary. The plugin root is the vibe-check/ directory that contains dist/index.js. If Glob finds nothing, try searching for **/slop-detector/dist/index.js or **/vibe-check/package.json.
Check whether the dist/index.js file was found in Step 1. If not found, the scanner needs to be built:
npm run build --prefix <plugin-root>
Execute the scanner using the absolute path to dist/index.js found in Step 1. Do NOT use npx slop-scan — the package is not published to npm.
node /absolute/path/to/vibe-check/dist/index.js [path] [flags] --json
For example, if Glob found /Users/someone/dev/vibe-check/dist/index.js, run:
node /Users/someone/dev/vibe-check/dist/index.js . --json
[path] argument, pass it through. If not, use the current working directory.--verbose, --deep, or --full, pass those flags through.--json to get machine-readable output. If the user also passed --json, the scanner handles the duplicate gracefully.The scanner outputs a JSON object conforming to the ScanReport schema (v1.0.0). Extract these key fields:
| Field | Path | Description |
|---|---|---|
| Slop Score | overall.slopScore | 0-100 numeric score |
| Band | overall.band | "Low", "Moderate", "High", or "Severe" |
| Confidence | overall.confidence | "High", "Medium", or "Low" |
| Intent Score | intent.score | 0-100 numeric score |
| Intent Tier | intent.tier | "None", "Partial", or "Full" |
| Files Scanned | scope.filesScanned | Number of files analyzed |
| Categories | categories[] | Array of 4 category scores (0-1 scale) |
| Signals | signals[] | Array of individual signal results |
| Recommendations | recommendations | Deep scan suggestion and reason |
Use the Decision Tree to determine tone, then populate the Output Template.
Apply these rules in order to determine the framing and tone of the report:
If overall.slopScore > 75 (Severe band):
If intent.tier is "Full" (intent score >= 56):
If only 1-2 signals have scores above their warn threshold (0.4):
If overall.confidence is "Low":
coverage.extractors[] for degraded/failed extractors).--full if the smart scope missed relevant files.If recommendations.deepScanSuggested is true:
recommendations.reason text as context.Format the report using this exact structure. Use block characters to render category score bars.
Slop Score: {overall.slopScore} ({overall.band})
Confidence: {overall.confidence} | Files: {scope.filesScanned} scanned | Intent: {intent.tier} ({intent.score})
{category bars}
Top issues:
{for each signal where score > warn threshold, sorted by score descending:}
{signal.name} -- {signal.evidence[0].summary}
-> {signal.evidence[0].files, comma-separated, max 3}
{if recommendations.deepScanSuggested: "Consider --deep for content and structure analysis."}
{if --verbose flag was passed: full verbose details}
Render each category as a 10-character bar where filled blocks represent the score (0-1 scale, so score of 0.72 = 7 filled + 3 empty). Use these characters:
Format each line as:
{bar} {category.name padded to 25 chars} {score as 0-100 integer}
Example:
██████████ Typography & Color 72
██████░░░░ Spacing & Effects 58
█████░░░░░ Content 48
██████░░░░ Structure 63
List signals that scored above their warn threshold (default 0.4), sorted by score descending. For each:
name and the first evidence summary.files references from the evidence, prefixed with ->.detail in its evidence, include it as an indented note.If no signals exceed the warn threshold, output: "No significant slop patterns detected."
When --verbose was passed (check scanMeta.flags for "--verbose"), expand the report with:
coverage.extractors[] with its status, coverage percentage, and any notes.intent.evidence[] with type, count, and description.suppressions[] array.When the --deep flag was passed, perform additional LLM-assisted analysis on Tier 2 signals after formatting the base report.
For each Tier 2 signal that scored above 0.2 in the fast pass, re-examine its evidence:
evidence[].detail text which contains the matched buzzwords and their source context..sloprc removals.evidence[].detail which describes the hero section structure.evidence[].detail which lists the section fingerprints per page.intent.tier is "Full", structural similarity is more likely intentional.evidence[].detail which lists CTA elements per page.Append a section to the report:
--- Deep Scan Analysis ---
{For each re-examined signal:}
{signal.name}: {verdict: "Confirmed" | "Contextually Justified" | "Inconclusive"}
{Explanation of the LLM assessment}
{If justified: "Consider adding to .sloprc removals/allowlist."}
Scanner JSON (abbreviated):
{
"overall": { "slopScore": 82, "band": "Severe", "confidence": "High" },
"intent": { "score": 8, "tier": "None", "evidence": [], "attenuations": {} },
"scope": { "filesScanned": 34 },
"categories": [
{ "id": "typography-color", "name": "Typography & Color", "score": 0.88 },
{ "id": "spacing-effects", "name": "Spacing & Effects", "score": 0.76 },
{ "id": "content", "name": "Content", "score": 0.79 },
{ "id": "structure", "name": "Structure", "score": 0.71 }
],
"signals": [
{
"id": "font-crime",
"name": "Font Crime",
"score": 0.92,
"status": "scored",
"evidence": [
{
"summary": "1 font family ('Inter') across 34 components",
"files": ["src/app/layout.tsx:3"]
}
]
},
{
"id": "purple-plague",
"name": "Purple Plague",
"score": 0.84,
"status": "scored",
"evidence": [
{
"summary": "Purple hues dominate 73% of chromatic colors (41/56)",
"files": ["src/globals.css:12", "src/components/Hero.tsx:8"]
}
]
},
{
"id": "whitespace-wasteland",
"name": "Whitespace Wasteland",
"score": 0.78,
"status": "scored",
"evidence": [
{
"summary": "Spacing entropy 0.9 (very low); 2 unique values in 187 declarations",
"files": ["project-wide"]
}
]
},
{
"id": "shadow-realm",
"name": "Shadow Realm",
"score": 0.71,
"status": "scored",
"evidence": [
{
"summary": "Shadows on 74% of components (25/34)",
"files": [
"src/components/Card.tsx:5",
"src/components/Feature.tsx:12"
]
}
]
},
{
"id": "buzzword-bingo",
"name": "Buzzword Bingo",
"score": 0.81,
"status": "scored",
"evidence": [
{
"summary": "18 buzzwords detected (density 8.4); phrases: 'revolutionize your workflow', 'in today's fast-paced world'",
"files": ["src/app/page.tsx:15", "src/components/Hero.tsx:4"]
}
]
},
{
"id": "hero-syndrome",
"name": "Hero Syndrome",
"score": 0.9,
"status": "scored",
"evidence": [
{
"summary": "Generic hero template: h1 + paragraph + CTA button, content is non-specific",
"files": ["src/components/Hero.tsx:1"]
}
]
}
],
"recommendations": {
"deepScanSuggested": true,
"reason": "Slop Score exceeds 75 with multiple Tier 2 signals firing. Deep scan can evaluate whether content is truly generic."
}
}
Expected output:
Slop Score: 82 (Severe)
Confidence: High | Files: 34 scanned | Intent: None (8)
This project shows overwhelming signs of AI-generated styling. Nearly every signal is firing, and no design system or intentional customization was detected.
█████████░ Typography & Color 88
████████░░ Spacing & Effects 76
████████░░ Content 79
███████░░░ Structure 71
Top issues:
Font Crime -- 1 font family ('Inter') across 34 components
-> src/app/layout.tsx:3
Hero Syndrome -- Generic hero template: h1 + paragraph + CTA button, content is non-specific
-> src/components/Hero.tsx:1
Purple Plague -- Purple hues dominate 73% of chromatic colors (41/56)
-> src/globals.css:12, src/components/Hero.tsx:8
Buzzword Bingo -- 18 buzzwords detected (density 8.4); phrases: 'revolutionize your workflow', 'in today's fast-paced world'
-> src/app/page.tsx:15, src/components/Hero.tsx:4
Whitespace Wasteland -- Spacing entropy 0.9 (very low); 2 unique values in 187 declarations
-> project-wide
Shadow Realm -- Shadows on 74% of components (25/34)
-> src/components/Card.tsx:5, src/components/Feature.tsx:12
Consider --deep for content and structure analysis.
Scanner JSON (abbreviated):
{
"overall": { "slopScore": 45, "band": "Moderate", "confidence": "High" },
"intent": {
"score": 34,
"tier": "Partial",
"evidence": [
{
"type": "tailwind-theme",
"count": 8,
"description": "8 custom theme entries in tailwind.config.js"
},
{
"type": "css-vars",
"count": 5,
"description": "5 CSS custom properties in global scope"
}
],
"attenuations": {
"font-crime": 0.7,
"purple-plague": 0.6,
"border-radius-maximum": 0.8,
"shadow-realm": 0.9
}
},
"scope": { "filesScanned": 67 },
"categories": [
{ "id": "typography-color", "name": "Typography & Color", "score": 0.42 },
{ "id": "spacing-effects", "name": "Spacing & Effects", "score": 0.51 },
{ "id": "content", "name": "Content", "score": 0.38 },
{ "id": "structure", "name": "Structure", "score": 0.44 }
],
"signals": [
{
"id": "font-crime",
"name": "Font Crime",
"score": 0.49,
"rawScore": 0.7,
"attenuatedScore": 0.49,
"status": "scored",
"evidence": [
{
"summary": "1 font family ('Inter') across 42 components; some custom theme entries detected",
"files": ["src/app/layout.tsx:3"]
}
]
},
{
"id": "whitespace-wasteland",
"name": "Whitespace Wasteland",
"score": 0.55,
"status": "scored",
"evidence": [
{
"summary": "Spacing entropy 1.8 (moderate); 5 unique values in 312 declarations",
"files": ["project-wide"]
}
]
},
{
"id": "shadow-realm",
"name": "Shadow Realm",
"score": 0.45,
"rawScore": 0.5,
"attenuatedScore": 0.45,
"status": "scored",
"evidence": [
{
"summary": "Shadows on 52% of components (35/67)",
"files": [
"src/components/Card.tsx:12",
"src/components/Feature.tsx:8"
]
}
]
}
],
"recommendations": { "deepScanSuggested": false, "reason": "" }
}
Expected output:
Slop Score: 45 (Moderate)
Confidence: High | Files: 67 scanned | Intent: Partial (34)
Some AI-generated patterns are present, but custom theme entries and CSS variables indicate partial design intent. Scores have been attenuated for signals where design choices may be deliberate.
████░░░░░░ Typography & Color 42
█████░░░░░ Spacing & Effects 51
████░░░░░░ Content 38
████░░░░░░ Structure 44
Top issues:
Whitespace Wasteland -- Spacing entropy 1.8 (moderate); 5 unique values in 312 declarations
-> project-wide
Font Crime -- 1 font family ('Inter') across 42 components; some custom theme entries detected
-> src/app/layout.tsx:3
Shadow Realm -- Shadows on 52% of components (35/67)
-> src/components/Card.tsx:12, src/components/Feature.tsx:8
Run with --verbose for full details.
Scanner JSON (abbreviated):
{
"overall": { "slopScore": 15, "band": "Low", "confidence": "High" },
"intent": {
"score": 72,
"tier": "Full",
"evidence": [
{
"type": "tailwind-theme",
"count": 22,
"description": "22 custom theme entries in tailwind.config.ts"
},
{
"type": "css-vars",
"count": 18,
"description": "18 CSS custom properties in global scope"
},
{
"type": "design-token-file",
"count": 2,
"description": "Design token files detected: tokens/colors.ts, tokens/spacing.ts"
},
{
"type": "naming-convention",
"count": 1,
"description": "Consistent --color-*, --space-* naming pattern"
}
],
"attenuations": {
"font-crime": 0.4,
"purple-plague": 0.3,
"border-radius-maximum": 0.5,
"shadow-realm": 0.7
}
},
"scope": { "filesScanned": 98 },
"categories": [
{ "id": "typography-color", "name": "Typography & Color", "score": 0.12 },
{ "id": "spacing-effects", "name": "Spacing & Effects", "score": 0.18 },
{ "id": "content", "name": "Content", "score": 0.14 },
{ "id": "structure", "name": "Structure", "score": 0.1 }
],
"signals": [
{
"id": "font-crime",
"name": "Font Crime",
"score": 0.2,
"rawScore": 0.5,
"attenuatedScore": 0.2,
"status": "scored",
"evidence": [
{
"summary": "2 font families ('Inter', 'Playfair Display') across 52 components",
"files": ["src/app/layout.tsx:3"]
}
]
},
{
"id": "whitespace-wasteland",
"name": "Whitespace Wasteland",
"score": 0.22,
"status": "scored",
"evidence": [
{
"summary": "Spacing entropy 2.8 (healthy); 11 unique values in 445 declarations",
"files": ["project-wide"]
}
]
}
],
"recommendations": { "deepScanSuggested": false, "reason": "" }
}
Expected output:
Slop Score: 15 (Low)
Confidence: High | Files: 98 scanned | Intent: Full (72)
Minimal slop detected. A comprehensive design system is present with custom tokens, theme entries, and consistent naming conventions. This project shows strong evidence of deliberate design decisions.
█░░░░░░░░░ Typography & Color 12
██░░░░░░░░ Spacing & Effects 18
█░░░░░░░░░ Content 14
█░░░░░░░░░ Structure 10
No significant slop patterns detected.
Scanner JSON (abbreviated):
{
"overall": { "slopScore": 35, "band": "Moderate", "confidence": "Medium" },
"intent": {
"score": 68,
"tier": "Full",
"evidence": [
{
"type": "tailwind-theme",
"count": 18,
"description": "18 custom theme entries in tailwind.config.ts"
},
{
"type": "css-vars",
"count": 30,
"description": "30 CSS custom properties in global scope"
},
{
"type": "design-token-file",
"count": 1,
"description": "Design token file detected: theme.ts"
},
{
"type": "style-guide",
"count": 1,
"description": "STYLE_GUIDE.md detected"
}
],
"attenuations": {
"font-crime": 0.4,
"purple-plague": 0.3,
"border-radius-maximum": 0.5,
"shadow-realm": 0.7
}
},
"scope": { "filesScanned": 112 },
"categories": [
{ "id": "typography-color", "name": "Typography & Color", "score": 0.15 },
{ "id": "spacing-effects", "name": "Spacing & Effects", "score": 0.48 },
{ "id": "content", "name": "Content", "score": 0.32 },
{ "id": "structure", "name": "Structure", "score": 0.55 }
],
"signals": [
{
"id": "whitespace-wasteland",
"name": "Whitespace Wasteland",
"score": 0.52,
"status": "scored",
"evidence": [
{
"summary": "Spacing entropy 1.4 (low); 4 unique values in 520 declarations",
"files": ["project-wide"]
}
]
},
{
"id": "cookie-cutter-layout",
"name": "Cookie Cutter Layout",
"score": 0.61,
"status": "scored",
"evidence": [
{
"summary": "5 of 8 pages share identical section fingerprint: hero -> feature-grid -> testimonial -> cta-block -> footer",
"files": [
"src/app/page.tsx",
"src/app/pricing/page.tsx",
"src/app/about/page.tsx"
]
}
]
},
{
"id": "cta-mania",
"name": "CTA Mania",
"score": 0.48,
"status": "scored",
"evidence": [
{
"summary": "6 CTA buttons on pricing page, 5 on landing page",
"files": ["src/app/pricing/page.tsx:24", "src/app/page.tsx:18"]
}
]
}
],
"recommendations": {
"deepScanSuggested": true,
"reason": "Design system detected but structural repetition is high. Deep scan can evaluate whether layout similarity is intentional consistency or copy-paste."
}
}
Expected output:
Slop Score: 35 (Moderate)
Confidence: Medium | Files: 112 scanned | Intent: Full (68)
A design system is present with tokens, custom theme, and a style guide -- which is positive. However, some patterns appear intentional but repetitive. The structural similarity across pages and spacing monotony may reflect design system consistency taken too far rather than deliberate variety.
██░░░░░░░░ Typography & Color 15
█████░░░░░ Spacing & Effects 48
███░░░░░░░ Content 32
██████░░░░ Structure 55
Top issues:
Cookie Cutter Layout -- 5 of 8 pages share identical section fingerprint: hero -> feature-grid -> testimonial -> cta-block -> footer
-> src/app/page.tsx, src/app/pricing/page.tsx, src/app/about/page.tsx
Whitespace Wasteland -- Spacing entropy 1.4 (low); 4 unique values in 520 declarations
-> project-wide
CTA Mania -- 6 CTA buttons on pricing page, 5 on landing page
-> src/app/pricing/page.tsx:24, src/app/page.tsx:18
Consider --deep for content and structure analysis.
| Signal ID | Name | Category |
|---|---|---|
font-crime | Font Crime | Typography & Color |
purple-plague | Purple Plague | Typography & Color |
whitespace-wasteland | Whitespace Wasteland | Spacing & Effects |
shadow-realm | Shadow Realm | Spacing & Effects |
border-radius-maximum | Border Radius Maximum | Spacing & Effects |
gradient-overload | Gradient Overload | Spacing & Effects |
buzzword-bingo | Buzzword Bingo | Content |
hero-syndrome | Hero Syndrome | Content |
cookie-cutter-layout | Cookie Cutter Layout | Structure |
cta-mania | CTA Mania | Structure |
| Score | Band |
|---|---|
| 0-25 | Low |
| 26-50 | Moderate |
| 51-75 | High |
| 76-100 | Severe |
| Intent Score | Tier |
|---|---|
| 0-20 | None |
| 21-55 | Partial |
| 56-100 | Full |
All signals default to warn: 0.4, error: 0.7. Configurable via .sloprc.
npx claudepluginhub edwingao28/vibe-check --plugin vibe-checkDetects design system tokens and components in code, identifying drift with paired evidence blocks. Use when auditing design system consistency across a codebase.
Generates design systems and tokens from CSS/Tailwind/styled-components codebases, audits UI consistency across 10 dimensions, detects AI-generated patterns. Use for new projects, redesigns, PR reviews.
Generates design systems from codebase patterns, audits visual consistency across 10 dimensions, and detects generic AI-generated design patterns. Useful for new projects, redesigns, or styling PR reviews.