| name | token-validator |
| description | Detects hardcoded visual values (colors, spacing, typography, border-radius) where design tokens should be used. Suggests matching token replacements with confidence scores. |
| user-invocable | false |
| version | 1.0.0 |
| allowed-tools | Read, Glob, Grep |
Token Validator
You detect hardcoded visual values in UI code and suggest design token replacements.
Quick Start
- Load token definitions from configured sources
- Scan target files for hardcoded values
- Match values to tokens with confidence scoring
- Output findings with replacement suggestions
Instructions
Step 1: Load Token Definitions
Read react-craft.config.yaml and look for token source configuration under design_system.token_sources.
Supported formats (in priority order):
DTCG (.tokens.json) — W3C Design Tokens Community Group format (primary):
{
"color": {
"primary": { "$value": "#2CA01C", "$type": "color" },
"text": {
"primary": { "$value": "#333333", "$type": "color" }
}
},
"spacing": {
"sm": { "$value": "8px", "$type": "dimension" },
"md": { "$value": "16px", "$type": "dimension" }
}
}
CSS Custom Properties:
:root {
--acme-color-primary: #2CA01C;
--acme-spacing-md: 16px;
}
Storybook MCP manifest tokens section (fallback):
Queried from the Storybook MCP server if token files are not configured.
If token sources aren't configured, check for .tokens.json files in the project root and src/tokens/ directory. If nothing is found, warn the user and stop:
"No token sources found. Configure design_system.token_sources in react-craft.config.yaml or add a .tokens.json file to your project root."
Build a lookup table: { value -> token_name, category }.
Step 2: Scan for Hardcoded Values
Scan target files for these patterns:
Colors
- Hex:
#333, #333333, #33333380
- RGB/RGBA:
rgb(51, 51, 51), rgba(51, 51, 51, 0.5)
- HSL:
hsl(0, 0%, 20%)
- Named colors in style context:
color: black, background: white
Spacing & Sizing
- Pixel values in style context:
padding: 16px, margin: 8px, gap: 24px
- Rem values:
1rem, 0.5rem
- Numeric values in spacing props:
p={4}, m={8}, gap={16}
Typography
- Font sizes:
font-size: 14px, fontSize: '14px'
- Font weights:
font-weight: 700, fontWeight: 'bold'
- Font families:
font-family: 'Helvetica'
Border Radius
border-radius: 4px, borderRadius: '8px'
Step 3: Filter False Positives
DO NOT flag these:
- Values inside SVG elements (
<svg>, <path>, <circle>)
- Values inside third-party library config files
- Values in test files and Storybook stories
- Values in comments
- Numeric values that aren't styling (array indices, IDs, counts, dimensions for canvas/SVG)
- Values of
0, 1px (too generic to be tokens)
- Values inside template literals that compute dynamic values
- z-index values
- Animation durations and timing functions (unless duration tokens exist)
Context-aware filtering:
- Only flag values that appear in style-related contexts:
- CSS/SCSS properties
style attributes or objects
- Tailwind arbitrary values
[#333]
- CSS-in-JS (styled-components, emotion)
- Component styling props (
color=, bg=, p=, etc.)
Step 4: Match Values to Tokens
For each hardcoded value found:
- Exact match — Value matches a token exactly -> confidence 95-100%
- Near match — Value is close to a token (e.g.,
#334 vs token #333333) -> confidence 60-80%
- Category match — Value is in the right category but no close token (e.g.,
#FF0000 is a color but no matching token) -> confidence 30-50%, suggest nearest token
- No match — Value has no reasonable token -> don't report (it may be intentional)
Step 5: Output Findings
[SEVERITY] file:line — hardcoded-[category]
Found: hardcoded value `[value]`
Replace with: `var(--[token-name])` (or framework equivalent)
Confidence: [percentage]
Auto-fixable: [yes if confidence > 90% and single unambiguous match]
Output Format
## Token Validator Results
### src/components/TaxCategoryPicker.tsx
[E] line 23 — hardcoded-color
Found: `color: '#333333'`
Replace with: `var(--acme-color-text-primary)` — exact match
Confidence: 98%
Auto-fixable: yes
[W] line 45 — hardcoded-spacing
Found: `padding: '12px'`
Replace with: `var(--acme-spacing-sm)` (8px) or `var(--acme-spacing-md)` (16px) — no exact match
Confidence: 50%
Auto-fixable: no (ambiguous — developer should choose)
### Summary
- Scanned 1 file, found 2 hardcoded values
- 1 exact token match (auto-fixable)
- 1 approximate match (needs review)
Guidelines
- Prefer precision over recall — a missed hardcoded value is better than a false positive
- When multiple tokens match, list all options and let the developer choose
- Respect the styling paradigm from config (CSS custom properties vs Tailwind vs SCSS)
- For Tailwind projects, suggest class equivalents instead of
var() syntax
- Always report the confidence level — developers use this to prioritize