From design-system-ops
Generates AI-optimized prose descriptions for UI components in six-section format (purpose, props, anti-patterns, composition, accessibility, examples) for Figma MCP server and LLM consumption.
npx claudepluginhub murphytrueman/design-system-opsThis skill uses the workspace's default tool permissions.
A skill for generating structured component descriptions optimised for consumption by LLMs via Figma's MCP server. Output is a six-section description that gives an AI agent the information it needs to understand, compose, and generate from a component accurately — without relying on implicit knowledge, visual inference, or team context.
Generates structured JSON metadata schemas for design system components encoding props, behavioral rules, composition constraints, prohibited combinations, and accessibility contracts for tooling like MCP servers, linters, and code generators.
Generates detailed UI component specifications for design systems, including anatomy, variants, props, states, behavior, accessibility, and usage guidelines.
Generates component API documentation with props tables, usage examples, and guidelines. Use when documenting component libraries, creating API references, or building component documentation for designers and developers.
Share bugs, ideas, or general feedback.
A skill for generating structured component descriptions optimised for consumption by LLMs via Figma's MCP server. Output is a six-section description that gives an AI agent the information it needs to understand, compose, and generate from a component accurately — without relying on implicit knowledge, visual inference, or team context.
This is the differentiating skill in Design System Ops. It encodes a methodology built through production use on a real AI-assisted design system and informed by the AI-readiness patterns in the knowledge notes.
The problem it solves: most component descriptions are written for human designers discovering the component for the first time. They use phrases like "use this to show important information" or "works great in cards". These descriptions are not useless — but they are not structured for LLM consumption. An LLM reading a component description needs to know what the component IS, what it takes, what it prohibits, how it relates to other components, and what failure modes look like. Human-readable descriptions skip most of this.
The six-section format is the product of watching AI agents misuse components that had perfectly fine human documentation. The sections are not arbitrary — each one addresses a specific class of LLM error.
Before producing output, check for a .ds-ops-config.yml file in the project root. If present, load:
integrations.figma — if enabled, auto-pull component data from Figma (see below)integrations.storybook — if enabled, pull prop definitions and story contextintegrations.documentation — if enabled, cross-reference existing documentation for accuracyFigma MCP (integrations.figma.enabled: true):
integrations.figma.file_keyStorybook (integrations.storybook.enabled: true):
integrations.storybook.urlGitHub (integrations.github.enabled: true):
If an integration fails, log it and proceed with manual input.
This skill works best with a Figma MCP connection but does not require one. Before proceeding, check what data sources are available:
If Figma tools are configured but fail (connection error, invalid node, nothing selected), note the error and fall back to manual input. Do not retry in a loop.
Check for an existing description first. When reading from Figma, always check whether the component already has a description. If it does:
If the existing description already follows the six-section format, say so: "This component already has a structured description. Want me to review it for completeness, or is there a specific section you want improved?"
Ask for or confirm the following (skip if auto-pulled via integrations above). If the component is in a connected Figma file, use the MCP server to read it directly:
If pulling directly from Figma via MCP: read the component node, its variants, layer structure, and any existing description text. If description text exists, show it to the user (see Step 0). Do not assume existing description text is accurate — it is a starting point, not a source of truth. But do not ignore it either — existing descriptions often contain institutional knowledge that should be preserved in the rewrite.
Write each section in plain prose. No bullet lists inside the description itself — AI agents parse prose better than nested lists in this context. Each section should be dense but not padded.
One to two sentences. What does this component do, and when should it be used? Write this as a contract statement, not a marketing line.
Bad: "A flexible card component for displaying content in a visually appealing way." Good: "A surface container for grouping related content that belongs together but does not require its own page. Use when content needs visual separation from surrounding context without implying navigational hierarchy."
Document every configurable prop. For each:
Format: prop-name | type | default | description
Do not skip props because they seem obvious. LLMs cannot infer defaults.
Example:
variant | "primary" | "secondary" | "ghost" | "destructive" | "primary" | Controls visual weight and colour treatment
size | "sm" | "md" | "lg" | "md" | Adjusts padding, font size, and min-touch-target
disabled | boolean | false | Prevents interaction and applies reduced-opacity treatment
loading | boolean | false | Replaces label with loading indicator and prevents further clicks
What should an AI agent NOT do with this component? List the three to five most common misuse patterns, each as a one-sentence prohibition with a brief reason.
These anti-patterns should be specific to this component, not generic design system guidance. Write them based on actual misuse patterns if known, or inferred from the component's structure and common analogues.
Example (Button):
If observed misuse patterns are not available from production data, infer likely anti-patterns from the component's API structure:
variant prop that includes "destructive" or "danger": Likely misuse — using the destructive variant for reversible actions, or using it as a visual emphasis tool rather than a semantic signal.size prop: Likely misuse — using large sizes in dense layouts, or mixing sizes inconsistently within the same context.disabled prop: Likely misuse — using disabled state to hide functionality rather than communicating why it is unavailable (missing aria-disabled with explanation).icon or iconOnly prop: Likely misuse — using icon-only variants without providing an accessible label, or choosing icons based on aesthetics rather than meaning.onClick or action props: Likely misuse — using a button-like component for navigation (should be a link), or attaching actions to non-interactive elements.Use these inferences as starting points. Mark inferred anti-patterns as "anticipated" in the description — they should be validated against real usage and upgraded to "observed" once confirmed.
How does this component relate to others? Document:
Be specific. "Can be used in cards" is not useful. "Can be placed inside Card as an action — always as the last child of Card.Footer, never inside Card.Body" is useful.
Document the accessibility contract for this component:
This is not a WCAG checklist. It is the specific accessibility behaviour of this specific component.
Why this section requires extra rigour. Accessibility is where AI-generated components fail most often. LLMs understand accessibility theory but routinely produce code that fails basic testing — missing keyboard handlers, incomplete ARIA attributes, focus management that traps or loses focus. The description must be prescriptive enough that an AI agent generating from it produces accessible output without additional guidance.
Specific requirements:
<button>, say so — an LLM may default to a <div> with role="button" which loses native keyboard behaviour.disabled attribute and aria-disabled behaviour, and state which one the component uses and why.aria-label with a description of the action, not the icon name.Two to three examples of correct usage. Each example must include three parts: the intent, the configuration, and the expected DOM output. The expected DOM output is what makes this section uniquely valuable for AI agents — it gives them a validation target, not just a generation prompt.
Example format:
Intent: [What the user is trying to accomplish]
Configuration: [Exact props/values needed]
Expected DOM output:
[The rendered HTML structure an AI agent should produce and can validate against]
Example (Button):
Intent: Primary action in a confirmation dialog. Confirms the destructive action.
Configuration: variant="primary", size="md", label="Delete account"
Expected DOM output:
<button
type="button"
class="btn btn-primary btn-md"
aria-label="Delete account"
>
Delete account
</button>
Intent: Secondary cancel action paired with the primary action above.
Configuration: variant="secondary", size="md", label="Cancel"
Expected DOM output:
<button
type="button"
class="btn btn-secondary btn-md"
>
Cancel
</button>
Intent: Icon-only close button in a modal header.
Configuration: variant="ghost", size="sm", iconOnly=true, icon="close", ariaLabel="Close dialog"
Expected DOM output:
<button
type="button"
class="btn btn-ghost btn-sm btn-icon"
aria-label="Close dialog"
>
<svg aria-hidden="true" class="icon icon-close">...</svg>
</button>
The expected DOM output does not need to be exhaustive — it should include the elements, attributes, and structure an AI agent would need to validate correctness. Include: semantic HTML elements, ARIA attributes, class names (if predictable), and any accessibility-critical attributes. Omit: internal implementation details, event handlers, and styling properties.
Deduplication rule: If information in the examples section repeats what was already stated in the Props or Accessibility sections, reference it rather than restating it. The examples section adds contextual usage — it should not be a third place where prop defaults or ARIA roles are listed. If an example uses variant="primary", do not re-explain what the primary variant does — the Props section already covered that.
Before formatting, review each section for redundancy. The six sections should be complementary, not overlapping. Apply these rules:
If any section exceeds 100 words and contains information duplicated elsewhere, trim it. The target is dense precision, not comprehensive coverage through repetition.
The final description should be written as a single continuous text block suitable for pasting into Figma's component description field. Structure it with clear section headers in plain text (e.g. PURPOSE, PROPS, ANTI-PATTERNS) so an LLM scanning the description via MCP can locate sections without parsing markdown.
Total length: 300 to 600 words. Long enough to be comprehensive, short enough that the full description fits within a reasonable token budget when loaded alongside other components.
In addition to the six-section text description, produce a structured JSON metadata object for machine consumption. This metadata serves MCP servers, linters, code generators, and testing frameworks that need to parse component information programmatically.
{
"component": "[exact component name]",
"category": "[navigation|form|feedback|layout|display|overlay]",
"version": "[component version if available]",
"status": "[alpha|beta|stable|deprecated]",
"challengeRating": [CR number or null],
"purpose": "[one-sentence purpose from Section 1]",
"props": [
{
"name": "[prop name]",
"type": "[type — e.g. 'enum', 'boolean', 'string', 'number', 'ReactNode']",
"values": ["[accepted values if enum]"],
"default": "[default value]",
"required": true|false,
"description": "[one-sentence description]"
}
],
"antiPatterns": [
{
"rule": "[short prohibition statement]",
"reason": "[why this is harmful]"
}
],
"composition": {
"canContain": ["[component names this can contain]"],
"canBeContainedIn": ["[component names this can be placed inside]"],
"typicallyUsedWith": ["[components commonly used alongside]"],
"constraints": ["[hard nesting or ordering constraints]"]
},
"accessibility": {
"role": "[primary ARIA role]",
"keyboardPattern": "[named pattern — e.g. 'button', 'dialog', 'combobox', 'tabs']",
"keyboardInteractions": {
"Tab": "[behaviour]",
"Enter": "[behaviour]",
"Space": "[behaviour]",
"Escape": "[behaviour]",
"ArrowKeys": "[behaviour or 'N/A']"
},
"focusManagement": "[description]",
"requiredAria": ["[required aria attributes]"],
"screenReaderAnnouncement": "[what is announced]"
},
"tokens": ["[token names this component binds to]"],
"composedOf": ["[system components rendered internally]"],
"examples": [
{
"intent": "[what the example demonstrates]",
"configuration": {
"[propName]": "[value]"
}
}
]
}
When to produce both formats:
Keeping text and JSON in sync:
purpose field should be the same text as the Purpose section's first sentenceprops array should exactly match the Props sectionBefore delivering the description, run a mental test: if an LLM received only this description and nothing else, could it:
If the answer to any of these is no, revise the relevant section before delivering.
Staff-level validation: If structured JSON metadata was produced, additionally verify:
props array (and vice versa)composition.canContain and composition.canBeContainedIn arrays are complete and accurateaccessibility.keyboardPattern matches a recognised pattern nametokens array lists actual token names from the system, not generic placeholdersIf the Figma Console MCP from Southleft is connected (check for figma_set_description tool availability), write the completed description directly into the Figma component's description field. This closes the loop — the description goes from generation to Figma in a single session, visible in Dev Mode immediately.
How to write back:
figma_set_description with the component's node ID and the full six-section text descriptiondescriptionMarkdown parameter with the markdown-formatted versionWhen NOT to write back:
When the standard Figma MCP is connected (read-only): The description cannot be written back automatically. Present the description in chat and note that the user will need to paste it into Figma's component description field manually. If the user asks "can you write this to Figma?", explain that the standard Figma MCP is read-only and recommend the Figma Console MCP from Southleft for write-back capability.