3. Skills

Skills are folders of Markdown and scripts that Claude Code loads when their description matches the task.

Skills are folders of Markdown and scripts that Claude Code loads when their description matches the task. UI Designer installs five of them under .claude/skills/ (AI-2). The skills are the main way the product teaches an agent to design well: what tools exist, in which order to use them, what the design system is, and the mistakes to avoid.

3.1 The five skills#

Skill Teaches Uses Needs (M)
ui-designer The ud CLI and ud mcp, use_figma on a .design file, UDX, the design loop (§4). The base skill; the others refer to it. all tools 0.1
ui-designer-design-system Building and extending a design system: variables with modes, styles, components, variants, properties, libraries, token export. use_figma, search_design_system, get_libraries, ud system, ud lint 0.4
ui-designer-from-code Designing from existing code: components, routes or a running page become frames that use the design system. Read/Grep/Glob, ud system, use_figma, generate_figma_design / ud import html 0.7 (0.8 for capture)
ui-designer-to-code Implementing a frame or component as code in the workspace with the code map and project conventions. get_design_context, Code Connect tools, get_variable_defs, ud codegen 0.6
ui-designer-review Reviewing a design: system consistency, accessibility, hierarchy, spacing, copy; findings as comments with fixes. ud lint, get_screenshot, search_design_system, ud comments 0.6

The skills ship from 0.1 and grow with the milestones. A skill never instructs a tool that the installed ud does not have: each skill’s SKILL.md has a “Capabilities” block generated at build time from the registry and ud plugin-api --json (CMD-14), and tells the agent to run ud_help (or ud help) when it is unsure.

3.2 Layout of a skill folder#

text
.claude/skills/ui-designer/
├── SKILL.md                    frontmatter (name, description) + the instructions
├── .ud-skill.json              install manifest: skill version and file hashes (§3.8)
├── references/                 loaded on demand, linked from SKILL.md
│   ├── cli.md                  ud commands and tools, one screen each
│   ├── plugin-api.md           the figma global as implemented: coverage, differences from Figma
│   ├── ud-plugin-api.d.ts      typings (subset of @figma/plugin-typings + the ud global); grep, do not load whole
│   ├── udx.md                  UDX markup (CLI-001 §7) with examples
│   ├── selectors.md            --query selectors (CLI-001 §6)
│   ├── design-loop.md          the loop of §4 with worked examples
│   └── gotchas.md              known mistakes, WRONG / RIGHT pairs
└── scripts/                    use_figma scripts, read with Read and passed as `code`, or run with --code-file
    ├── inventory.js            read-only: pages, top-level frames, components, variable collections
    ├── find-space.js           read-only: a free position to the right of existing content
    └── audit-frame.js          read-only: node counts, raw colours, unbound spacing, text without styles

Rules that hold for every skill:

  • SKILL.md stays under 400 lines. Detail goes to references/, which the agent reads only when needed.
  • Scripts are use_figma scripts, not shell scripts. They run in the QuickJS sandbox (CMD-11) on every surface, including the AI panel where Bash is not allowed. The agent reads the file and passes its text as code, or runs ud use_figma --code-file <path> from Bash. Scripts take parameters from a const PARAMS = {…} line at the top that the agent edits.
  • Read-only scripts are marked with // read-only on line 1, so the agent and reviewers can tell.
  • Description = trigger. The frontmatter description is what Claude Code matches against the task. It names the file type, the verbs and the cases where the skill must not be used.
  • No secrets, no URLs to SoftForge services, no absolute paths. Skills are committed with the project.

3.3 ui-designer#

Purpose. The base skill. It makes Claude a competent user of ud: find the file, read it compactly, use the design system, build in small transactions, look at the result, lint, fix, and report. Every other skill says “load ui-designer first”.

Frontmatter.

yaml
---
name: ui-designer
description: >-
  Use for any work on .design files (SoftForge UI Designer): creating, editing, inspecting or exporting
  screens, frames, components, text, layout, variables or prototypes, through the `ud` command or the
  `ui-designer` MCP server (tools use_figma, get_metadata, get_screenshot, search_design_system, ud_run,
  ud_render, ud_lint). Load it before the first use_figma call on a .design file, and whenever the user asks
  to design, mock up, lay out or change a UI in this repository. Do not use for figma.com files; those use
  the Figma MCP server.
---

Files. As in §3.2. references/gotchas.md starts from the Figma Plugin API behaviour that UI Designer keeps on purpose (CMD-15) and adds what is ours:

Gotcha Rule in the skill
Colours 0–1 channels; paint color is {r,g,b}, opacity on the paint.
Paint arrays fills, strokes, effects are immutable: clone, change, reassign.
Fonts await figma.loadFontAsync(font) before any text change; style names are Figma’s ("Semi Bold"); ud fonts lists what exists.
Pages await figma.setCurrentPageAsync(page); the page context resets to the first page at the start of every call.
Sizing HUG only on auto-layout frames and their text children, FILL only on children of auto-layout frames: append first, then set. resize() resets sizing to FIXED, so call it first.
Positions in auto layout Derived by the core, not stored (LAY-9). Setting x/y on a flow child does nothing; use layoutPositioning = "ABSOLUTE" if it must float.
Top-level placement New top-level frames go to a free position (scripts/find-space.js), never (0,0).
Return values Return every created and changed id; console.log output is returned too but is not a substitute (CMD-10).
Ids Native ids look like nd-3f9a0c1e7b2d. nd:3f9a0c1e7b2d is accepted (CMD-3). Pass ids between calls as string literals; no state survives a call.
Raw values Never a hex colour or a pixel gap when ud system lists a variable for it; bind with setBoundVariable / setBoundVariableForPaint.
Unsupported members UnsupportedApiError names the member and the milestone that adds it (CMD-14). Use the alternative in the message, or ud.run(id, params).
Atomicity A failed call changed nothing (CMD-12). Fix the error and run the whole call again; there is never a half-built frame to clean up.

Outline of SKILL.md.

  1. What UI Designer is (five lines): a .design file in the repository, the Figma tool interface, the registry, the live editor.
  2. Find the file and the editor. ud where (or whoami + get_metadata with no nodeId); fileKey is a path; one open design can be left out.
  3. Choose a surface. MCP tools when the ui-designer server is connected (mcp__ui-designer__*), else ud in Bash. Never call the Figma server’s tools on a .design file.
  4. The design loop — the six steps of §4 in short form, with the rule “one section per use_figma call”.
  5. Reading compactly. get_metadata / ud tree --depth 2, ud inspect --fields, ud system; budgets.
  6. Writing. use_figma for structure and anything the Plugin API covers; ud_apply for a list of registry commands; ud insert --udx for a subtree written as markup. When to choose which (table).
  7. Design system first. Load the digest, search before building, bind variables, use text styles, instance components; build a local component for anything repeated.
  8. Looking and checking. get_screenshot after each composed section; ud_lint on the result; what to look for (clipped text, overlaps, placeholder text, wrong variant, wrong font).
  9. Pointing. ud select the result so the user sees it; mention node names, not just ids.
  10. Errors. The error codes (§5.8) and what to do for each.
  11. Capabilities. Generated block: tools and Plugin API members available in this version.
  12. References — table linking the files of references/ with “load when…”.

3.4 ui-designer-design-system#

Purpose. Build or extend the design system of a file: primitive and semantic variables with modes, text and effect styles, components with variants and properties, publishing as a workspace library, and token export to code (VAR-1 to VAR-9, CMP-1 to CMP-5).

Frontmatter.

yaml
---
name: ui-designer-design-system
description: >-
  Use with ui-designer when the deliverable is a reusable design-system asset in a .design file: variable
  collections and modes (colour, spacing, radius, typography tokens), text or effect styles, components,
  component sets with variants, component properties, a library to publish, or tokens to export to code
  (DTCG, CSS, Tailwind). Also for "turn these frames into components" and "add a dark mode". Not for
  composing a screen out of existing components; that is ui-designer.
---

Files.

text
ui-designer-design-system/
├── SKILL.md
├── .ud-skill.json
├── references/
│   ├── variables.md            collections, modes, aliasing primitives → semantic, scopes, code syntax
│   ├── components.md           component, set, variants, properties (boolean, text, instance swap, slot), naming
│   ├── styles.md               text ramps, effect styles, layout-grid styles
│   ├── libraries.md            publishing, consuming, updates (VAR-7, VAR-8)
│   ├── tokens.md               ud export tokens: DTCG, CSS, Tailwind, …; round trip with code
│   └── naming.md               slash groups, variant property names, what lint expects
└── scripts/
    ├── inventory-system.js     read-only: collections, modes, variable counts by type, styles, component sets
    ├── variant-grid.js         lays out a component set's variants in a labelled grid
    └── bind-audit.js           read-only: properties with raw values that a variable could replace

Outline of SKILL.md.

  1. Load ui-designer. Run ud system and scripts/inventory-system.js; never conclude “no variables” from local collections alone, also check get_libraries and search_design_system.
  2. Order of work: variables (primitives, then semantic aliases, then modes) → styles → base components → composite components → documentation (descriptions) → lint.
  3. Variables: explicit scopes always; code syntax for each platform the repository uses (read the repository’s CSS/Tailwind config first); one collection per concern.
  4. Components: auto layout inside; bind every value; properties instead of variant explosion (instance swap for icons); combineAsVariants then scripts/variant-grid.js; description on components and sets only.
  5. Verification per step: counts returned by each call; one screenshot of each component set; ud lint.
  6. Libraries: mark as library, check a consumer file picks it up (get_libraries from the consumer).
  7. Tokens: ud export tokens --format … into the path the repository uses; show the diff.

3.5 ui-designer-from-code#

Purpose. Create frames that match an existing implementation (AI-7): a component file, a route, or a running page, built from the design system rather than traced pixels.

Frontmatter.

yaml
---
name: ui-designer-from-code
description: >-
  Use with ui-designer to create or update designs in a .design file from existing code: "design this
  component", "put the settings page in the design file", "sync the design with the code", a route, a JSX/TSX,
  Vue, Svelte, HTML or custom-element file, or a page running on localhost. Reads the code, maps it to the
  design system's components and variables, and builds editable frames with auto layout. Not for writing
  code from a design (ui-designer-to-code).
---

Files.

text
ui-designer-from-code/
├── SKILL.md
├── .ud-skill.json
├── references/
│   ├── css-to-layout.md        flex/grid/padding/gap/size → auto layout, sizing, constraints (table)
│   ├── code-map.md             reading the code map (DEV-4) backwards: code component → design component
│   ├── fonts.md                finding the product's font in CSS/Tailwind/theme files; never default to Inter
│   ├── icons.md                importing SVG icons from the codebase (figma.createNodeFromSvg) at slot size
│   └── capture.md              generate_figma_design / ud import html as a visual reference (0.8)
└── scripts/
    ├── component-map.js        read-only: design components with their code-map entries
    └── compare-frames.js       read-only: size, spacing and colour differences between two frames

Outline of SKILL.md.

  1. Load ui-designer. Read the source: the entry component, its children, the styles, the tokens file.
  2. List the sections and, for each, the code components used; resolve each through the code map (get_code_connect_map or scripts/component-map.js), then search_design_system for the rest.
  3. Identify the font and the images. A running page (0.8): capture it with generate_figma_design (or ud import html) as a reference next to the build, never as the deliverable.
  4. Build the wrapper frame at the source’s viewport width; build section by section from instances and variables; repeated code components without a design counterpart become one local component.
  5. Compare: screenshot of the build next to the capture or the user’s screenshot; scripts/compare-frames.js; fix; delete the capture.
  6. Report which code components had no design component (candidates for ui-designer-design-system).

3.6 ui-designer-to-code#

Purpose. Implement a frame or component as code in the workspace (AI-8), using the code map (DEV-4), the generated snippets (DEV-2), the variables’ code syntax (VAR-5) and the project’s conventions.

Frontmatter.

yaml
---
name: ui-designer-to-code
description: >-
  Use with ui-designer to implement a frame, screen or component of a .design file as code in this
  workspace: "implement this design", "build the Login frame in React", "update the component to match the
  design", "generate the tokens". Uses get_design_context, the code map (Code Connect tools) and the
  project's existing components and conventions; output is a reviewed diff. Also for creating or fixing
  code-map entries between design components and code components.
---

Files.

text
ui-designer-to-code/
├── SKILL.md
├── .ud-skill.json
├── references/
│   ├── workflow.md             design context → plan → reuse → write → compare
│   ├── code-map.md             get/add_code_connect_map, suggestions, prop mapping syntax
│   ├── frameworks.md           React + Tailwind, React + CSS modules, custom elements (SoftForge page contract), SwiftUI, Compose
│   └── tokens.md               variables → CSS custom properties / theme keys; never hard-code a token's value
└── scripts/
    └── unmapped.js             read-only: instances in a frame whose component has no code-map entry

Outline of SKILL.md.

  1. Load ui-designer. Read CLAUDE.md and the folder the code will live in; find the framework and the styling approach from the repository, and pass them as clientFrameworks / clientLanguages.
  2. get_design_context for the node; get_variable_defs for its tokens; scripts/unmapped.js for gaps.
  3. Treat the returned code as a reference, not as output: replace generic markup with the project’s components through the code map; use token names, not values.
  4. Missing mappings: propose them with get_code_connect_suggestions, confirm, write with add_code_connect_map / send_code_connect_mappings.
  5. Write the code; run the project’s type check and tests if allowed; render the design and compare with the running result when a dev server exists.
  6. Report the files changed and the mappings added.

3.7 ui-designer-review#

Purpose. Review a design against its design system and good practice (AI-9): consistency, accessibility, hierarchy, spacing, copy. Findings become comments pinned to nodes (COL-3), each with an optional fix.

Frontmatter.

yaml
---
name: ui-designer-review
description: >-
  Use with ui-designer to review or critique a frame, flow or page of a .design file: design-system
  consistency, accessibility (contrast, touch targets, alt text, focus order), visual hierarchy, spacing and
  alignment, copy. "Review this screen", "is this accessible", "check the design before handoff". Leaves
  findings as comments on the nodes and proposes fixes; it does not change the design unless asked.
---

Files.

text
ui-designer-review/
├── SKILL.md
├── .ud-skill.json
├── references/
│   ├── checklist.md            the review checklist by category, with severity
│   ├── lint-rules.md           what ud lint checks (CMD-36), how to read and configure it
│   ├── accessibility.md        WCAG AA thresholds, target sizes, DEV-8 metadata
│   └── comments.md             comment format: category, severity, finding, suggestion, fix id
└── scripts/
    ├── contrast.js             read-only: text/background pairs with contrast ratios, resolved per mode
    └── spacing-scale.js        read-only: gaps and paddings off the spacing scale

Outline of SKILL.md.

  1. Load ui-designer. Read the frame (get_metadata, ud system), screenshot it.
  2. Run ud_lint and the scripts; then look at the screenshot for what rules cannot see (hierarchy, rhythm, copy, empty and error states).
  3. Write each finding as a comment on the node (ud comments add --node … --category accessibility), in the format of references/comments.md. Severity: error, warning, suggestion.
  4. For findings with a mechanical fix, prepare the fix as a use_figma script or ud_apply list, but run it only when the user asked for fixes (in the AI panel: as part of the proposal, §9.3).
  5. Summarise: counts by severity, the three most important findings, what was fixed.

3.8 Installation, update and versioning#

Installing. Two equivalent ways (AI-2):

  • The command “UI Designer: Let Claude Code Design in This Folder” (also offered by the AI panel when skills are missing).
  • ud skill --install in the workspace folder. --only ui-designer,ui-designer-review installs a subset; --global installs into ~/.claude/skills/ instead of the project. CLI-001 has the full reference.

Both do the same steps, and show what they will write before writing it:

  1. Write the five skill folders to .claude/skills/ from the copy bundled with the extension.
  2. Add the ui-designer server to the workspace’s .mcp.json (as ud mcp install, §5.1).
  3. Offer to add *.design merge=union to .gitattributes (COL-4) if it is missing.
  4. Offer (never force) a three-line paragraph for CLAUDE.md that says designs live in .design files and points at the skill.

Versioning. Each skill folder has .ud-skill.json:

json
{
  "skill": "ui-designer",
  "version": "0.7.0",
  "requires": { "ud": ">=0.7.0" },
  "installedAt": "2026-10-06T09:12:44.120Z",
  "files": {
    "SKILL.md": "sha256-9d2f…",
    "references/gotchas.md": "sha256-41ac…",
    "scripts/inventory.js": "sha256-0b7e…"
  }
}

The skill version is the extension version that shipped it. files holds the hash of each file as installed, so local edits can be told apart from old versions.

Updating. When the extension starts after an update, and on ud skill --install, each installed skill is compared with the bundled one:

Installed files vs. manifest hashes Bundled version Action
unchanged newer Replace silently; one notification lists the updated skills.
edited locally newer Diff prompt: “Skill ui-designer was edited in this folder. Update to 0.8.0?” with Show Diff (VS Code diff editor, local vs. new, per file), Update (the local version is kept as SKILL.md.local next to it), Keep Mine (recorded in the manifest as skipped: "0.8.0"; asked again at the next version).
any same or older Nothing.
missing folder — Nothing (the user removed it); the AI panel offers to reinstall when it needs it.

From the CLI, ud skill --install refuses to overwrite a locally edited file and exits with code 3 (conflict), printing the diff; --force overwrites and keeps .local copies.

Served copies. The same files are served by ud mcp as resources (skill://ui-designer/<skill>/SKILL.md and skill://ui-designer/<skill>/references/<file>), so MCP clients without a skills folder can read them, and the AI panel uses the bundled copy when nothing is installed (§6.3).

3.9 Compatibility with Figma’s skills#

Figma’s skills (figma-use, figma-generate-design, figma-generate-library, figma-code-connect) work unchanged against ud mcp (CMD-9). They teach the Plugin API rules that UI Designer keeps (CMD-15) and the discovery → build → screenshot workflow that §4 also follows. Both families can be installed at the same time.

What a Figma skill sees that differs, and how ud handles it:

Area Figma UI Designer Effect on a Figma skill
fileKey 22+ character key from a figma.com URL path of a .design file, a doc-… id or a ud:// link (CMD-2); may be left out with one open design Skills pass whatever the user gave; a figma.com URL is refused with a hint to ud import figma. The schema ud mcp publishes has no key pattern (§5.2).
nodeId 1:2 nd-3f9a0c1e7b2d, also nd:3f9a0c1e7b2d, name paths (CMD-3) Skills that turn node-id=1-2 into 1:2 produce nd:… from a ud:// link, which is accepted.
Screenshots short-lived URL + curl, base64 on request PNG written to a local file; the result has its path and a single-use loopback url (http://127.0.0.1:<port>/…) served by the editor when bridged or by ud mcp while it runs; url: null from one-shot headless ud get_screenshot (§5.9); the image inline when enableBase64Response is true (always in the AI panel) Skills that curl the URL work while a server runs; otherwise they read path.
Assets temporary URLs; upload_assets returns an upload URL local files in <name>.design.assets/ (CMD-5) upload_assets takes paths (or URLs outside --proposal); over MCP it also returns loopback POST URLs (§5.9), so Figma’s upload flow works unchanged. download_assets writes files and returns path plus the same kind of url. imageHash values are content hashes (sha256-…).
Library and component keys Figma keys opaque strings that name a workspace library file and node (CLI-001 §3) importComponentByKeyAsync(key) and friends work with keys from search_design_system.
skillNames logging parameter accepted, written to the local agent log only (§11.3) none
Errors safeToRetryWithoutCanvasRead always true: a failed call changed nothing (CMD-12) Skills retry directly, as intended.
Parallel calls one use_figma per page in parallel accepted; mutating calls on one document are queued and run one after the other, each atomic Same results; slightly slower fan-out.
Unsupported tools FigJam, Slides, shaders, generative plugins, generate_image, export_video, Weave, html_to_figma not listed by ud mcp (CMD-6) Figma’s skills already fall back when a tool is missing (e.g. no generated placeholder images).
figma.notify throws “not implemented” in use_figma throws the same none
Plugin API conveniences used by figma-use (figma.createAutoLayout, node.query, node.set, node.placeholder, await node.screenshot()) available implemented as part of the Plugin API coverage (CLI-001 §4); placeholder shows the shimmer on the canvas, screenshot() returns the image inline none, once covered (see the coverage table for the milestone)

Which skill wins. Our descriptions trigger on .design files and the ui-designer server; Figma’s trigger on Figma and figma.com URLs. When a task matches both (e.g. “build a screen” in a repository with .design files), ui-designer is the one that tells the agent which server to call: tools of the ui-designer server (mcp__ui-designer__use_figma) for .design files, tools of the Figma server (mcp__figma__use_figma) only for figma.com files. Figma’s skills remain valid guidance for the Plugin API in either case; where they disagree with references/gotchas.md (only for the rows above), ours applies.