ds-guard
Skill4 starsChanged 16 days agoMITView on GitHub
Automatically run after any edit to a .css, .tsx, .ts, .jsx, or .js file that touches styling, and before every commit that touches styles or components. Checks the diff against the design system tokens and living style guide. Trigger on: new CSS rules, className changes, style props, "check this against the design system".
In this repository34 other files it gives its agents.
- abstraction-finderSkill
- analyze-issueSkill
- backlog-routingSkill
- band-aid-finderSkill
- browser-debugger-cliSkill
- ci-fix-with-memorySkill
- code-health-auditSkill
- comment-reaperSkill
- cyoaSkill
- dead-code-cleanupSkill
- doc-rotSkill
- drupal-mental-modelSkill
- evidence-checkSkill
- github-screenshotSkill
- issue-maintenanceSkill
- kissSkill
- plain-language-auditSkill
- post-mergeSkill
- prioritize-issuesSkill
- project-bootstrapSkill
- project-pulseSkill
- pr-review-fix-pipelineSkill
- routeSkill
- ship-issueSkill
- skill-paritySkill
- tdd-implementSkill
- test-fixSkill
- test-reaperSkill
- test-workflowSkill
- update-routingSkill
- visual-crawlSkill
- visual-qa-pipelineSkill
- worktree-enhancedSkill
- wrap-it-upSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 6 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈6
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 18
Do NOT wait for the user to ask.
- Very specific: line 51
Look for src/lib/theme/themes/*.css, tokens.css, design-tokens.*, or similar
- Distinctive: line 55
If no token files are found, ask the user where the design system is defined before proceeding.
- Distinctive: line 89
If the project is still on Tailwind, skip this check — confirm with user first
- Distinctive: line 98
When the diff touches the living style guide, flag:
- Distinctive: line 130
Never introduce new token names — only use tokens already in the inventory.
- Distinctive: line 134
Do not change token definitions themselves — only usages.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
When to invoke (auto-trigger)
Invoke this skill automatically whenever:
- Any
.cssfile is edited - A
.tsx/.jsxfile is edited and the diff containsclassName,style=, or CSS custom properties - A new component is created
- A new CSS class is introduced
Do NOT wait for the user to ask. Run as part of the normal post-edit flow for any styling change.
The trigger depends on this description matching. To make the reminder deterministic, you can add your own PostToolUse hook in settings.json; this repo does not ship one. The hook has to print JSON with hookSpecificOutput.additionalContext: plain text on stdout only shows in the transcript view and never reaches the model. It fires after every Edit, Write, or MultiEdit, not just styling edits, so the reminder still leaves it to the model to decide whether the edit touched styling. Minimal example:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"PostToolUse\", \"additionalContext\": \"If this edit touched styling (.css, className, style=), run the ds-guard skill.\"}}'"
}
]
}
]
}
}Effort gating: at high/xhigh/max run the full audit against the token inventory and showcase (Steps 1+); at lower effort a quick spot-check of the diff's hardcoded values is enough.
DS Guard — Design System Enforcement
Purpose
Audit a diff or set of files to ensure every styling decision goes through the project's design system token layer. Catch violations before they land.
Step 1 — Discover the token inventory
Find the project's token source files:
- Look for
src/lib/theme/themes/*.css,tokens.css,design-tokens.*, or similar - Extract all defined
--*custom property names - Note the token namespaces in use (e.g.
--color-*,--space-*,--font-*,--radius-*)
If no token files are found, ask the user where the design system is defined before proceeding.
Step 2 — Discover the living style guide (canon, if one exists)
Look for a living style guide — a page that renders the real production components as the reference, so it can't drift from the app. Projects also call it a pattern library, component catalog, design-system page, showcase, or Storybook. Do NOT assume one exists. Common locations: src/app/design-system/, src/pages/ds/, src/app/ds*/, /design-system*, storybook stories/ dirs.
If a living style guide exists, treat it as canon:
- Any component pattern, spacing, color usage, or variant shown there takes precedence over what the diff introduces.
- A diff that introduces a new pattern absent from it → flag it (add it to the living style guide first, or reuse an existing pattern).
- A diff that contradicts it (e.g. a button style differing from the canon button) → violation.
If none exists, skip the canon-relative checks (this step and the "Living-style-guide-local component skinning" check below) — the token-hygiene checks still apply. Don't invent one or demand one; you may note its absence once if the project looks like it would benefit, but never block a diff for lacking it.
Step 3 — Read the diff
git diff HEAD or git diff --staged — look at every changed .css, .tsx, .ts, .jsx, .js line that contains styling.
Step 3 — Check for violations
Hardcoded values (always a violation)
- Hex colors:
#fff,#1a1a1a,#3b82f6, etc. - Named colors:
red,blue,white,black, etc. in CSS properties - Literal
rgb()/hsl()/oklch()values that aren't inside a token definition file - Hardcoded
pxspacing values for margin/padding/gap/width/height when a--space-*token exists for that role - Hardcoded
font-familystrings when--font-*tokens are available - Hardcoded
border-radiusvalues when--radius-*tokens are available
Off-system tokens (check against discovered inventory)
var(--color-something)where--color-somethingis NOT in the token inventory — likely a typo or stale namevar(--space-7)where the token set only goes to--space-6— off the scale
Tailwind utility classes (violation if project has migrated off Tailwind)
classNamestrings containing utility classes:text-sm,bg-gray-100,p-4,flex,gap-2,rounded-md, etc.cn()/clsx()calls mixing utility classes with BEM classes- If the project is still on Tailwind, skip this check — confirm with user first
Inline styles (flag, don't auto-fail)
style={{ color: '...' }}orstyle={{ padding: '...' }}— flag for review; inline styles bypass the token layer but are sometimes necessary
Living-style-guide-local component skinning (canon violation)
(Only applies if the project has a living style guide — see Step 2. Skip otherwise.) Step 2 treats it as canon — but that only holds if it RENDERS the real production components AND their styling lives in production (so the app inherits it). The inverse failure is the living style guide re-skinning a real component with guide-local classes: the guide looks right while the app's own component ships unstyled. This is a violation even when every value is on-token (so the checks above pass it cleanly).
When the diff touches the living style guide, flag:
- A component-specific styling prop (e.g.
overlayClassName,contentClassName,panelClassName,footerClassName, or other*ClassNameprops the project's primitives expose) passed to an imported production component — those props exist only on the real components, so using them here means a component is being skinned guide-locally. - A
classNameon an imported production component pointing to a class defined only in the guide's own stylesheet. - A section that hand-builds a look-alike (raw elements + bespoke classes) for something that already exists as a real component.
Fix: move the base styling into the PRODUCTION component (token-driven) so the app and the guide render the same thing; the guide then renders the real component unskinned. If the project has a deterministic canon check (a CI lint scanning the guide for these props), don't bypass it; if it has none, recommend adding one.
The app must never be the canon source for component styling, primitives, or layout — canon lives in the component and flows downstream to both the showcase and the app.
Step 4 — Report
List violations ordered by severity:
Error (must fix): hardcoded color values, off-system var() references, Tailwind classes in a post-Tailwind codebase
Warning (should fix): hardcoded spacing/radius/font values, inline styles
Info (consider): magic numbers close to token values (e.g. 0.875rem when --font-size-sm exists)
Format: file:line — description — suggested token
Example:
src/app/workshop.css:142 — hardcoded color `#3b82f6` — use var(--color-accent)
src/components/Foo.tsx:28 — Tailwind class `text-sm` — use var(--font-size-sm) or .text-technical
src/app/bar.css:9 — unknown token var(--color-muted) — did you mean var(--color-text-muted)?Step 5 — Fix
For each error-level violation, apply the fix directly. For warnings, propose the change and wait for confirmation. For info-level, report only.
Rules
- Never introduce new token names — only use tokens already in the inventory.
- A value of
transparent,inherit,currentColor,0does not need a token. 1px solidborder widths don't need a token unless the DS defines one.- Exceptions require an explicit comment explaining why the hardcoded value is intentional.
- Do not change token definitions themselves — only usages.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

