redongreen/uspec/create-voice

Claude Code and agent skill by redongreen/uspec

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Generate screen reader accessibility specifications for VoiceOver (iOS), TalkBack (Android), and ARIA (Web). Use when the user mentions "voice", "voiceover", "screen reader", "accessibility spec", "talkback", "aria", or wants to create accessibility documentation for a UI component.

Install

npx vskill@latest install redongreen/uspec/create-voice

SKILL.md

Create Voice Reader Specification

Generate a screen reader specification directly in Figma — focus order, platform-specific property tables, and announcement patterns organized by component state.

Execution contract (read first).

  • This file is instructions to RUN, not a document to edit. Invoking the skill = render the screen reader spec into Figma from the input .md.
  • Never edit this SKILL.md or any other skill file in response, even if one is open or focused in the editor. Modify a skill only when the user explicitly asks to change the skill itself.
  • The input component .md is a READ-ONLY source of truth. Never edit, append to, or "add a section" to it. The only artifact this skill produces is the Figma annotation. When the user asks to "create/add a section," "show," or "include" something, render it in the Figma annotation, never as an edit to the .md.
  • Never call AskQuestion, request confirmation, or pause for input (including before Figma writes, the expected output). On ambiguity, pick the most defensible option and continue.
  • Only two legal stops: (a) Step 0 fail-fast when no .md resolves; (b) one-line abort if the Figma MCP connection is dead.

MCP Adapter

Read uspecs.config.json → mcpProvider. Follow the matching column for every MCP call in this skill.

Operationfigma-consolefigma-mcp
Verify connectionfigma_get_statusSkip — implicit. If first use_figma call fails, guide user to check MCP setup.
Navigate to filefigma_navigate with URLExtract fileKey from URL (figma.com/design/:fileKey/...). No navigate needed.
Take screenshotfigma_take_screenshotget_screenshot with fileKey + nodeId
Execute Plugin JSfigma_execute with codeuse_figma with fileKey, code, description. JS code is identical — no wrapper changes.
Search componentsfigma_search_componentssearch_design_system with query + fileKey + includeComponents: true
Get file/component datafigma_get_file_data / figma_get_componentget_metadata or get_design_context with fileKey + nodeId
Get variables (file-wide)figma_get_variablesuse_figma script: return await figma.variables.getLocalVariableCollectionsAsync();
Get token valuesfigma_get_token_valuesuse_figma script reading variable values per mode/collection
Get stylesfigma_get_stylessearch_design_system with includeStyles: true, or use_figma: return figma.getLocalPaintStyles();
Get selectionfigma_get_selectionuse_figma script: return figma.currentPage.selection.map(n => ({id: n.id, name: n.name, type: n.type}));

`figma-mcp` requires `fileKey` on every call. Extract it once from the user's Figma URL at the start of the workflow. For branch URLs (figma.com/design/:fileKey/branch/:branchKey/:fileName), use :branchKey as the fileKey.

`figma-mcp` page context: use_figma resets figma.currentPage to the first page on every call. When a script accesses a node from a previous step via getNodeByIdAsync(ID), the page content may not be loaded — findAll, findOne, and characters will fail with TypeError until the page is activated. Insert this page-loading block immediately after getNodeByIdAsync:

javascript
let _p = node; while (_p.parent && _p.parent.type !== 'DOCUMENT') _p = _p.parent;
if (_p.type === 'PAGE') await figma.setCurrentPageAsync(_p);

This walks up to the PAGE ancestor and loads its content. Console MCP does not need this — figma_execute inherits the Desktop page context.

Inputs Expected

  • Component `.md` spec (required, user-provided path) — the source-of-truth component spec produced by {{skill:create-component-md}}. The user tells you where this `.md` lives — use the exact path they provide; the .md may live anywhere. This skill renders the Voice section from the `.md`; it does NOT re-extract anything from Figma. fileKey, nodeId, and compSetNodeId come from the .md's render-meta block.
  • Figma link (optional) — placement hint only (where to drop the rendered frame on the canvas). Never the source of structural facts.

There is no screenshot-only path. Without the component .md there is nothing to render — see Step 0's fail-fast contract.

Workflow

Copy this checklist and update as you progress:

Task Progress:
- [ ] Step 0: Require + parse the component `.md` (Voice body + render-meta + voice-render-meta carry). FAIL FAST if missing.
- [ ] Step 1: Read platform references (only as needed for slot-scenario reasoning — NOT for re-authoring announcements)
- [ ] Step 2: Verify MCP connection
- [ ] Step 3: Read template key from uspecs.config.json
- [ ] Step 4: Build render inputs from the parsed .md (guidelines, SECTIONS, focus order, FOCUS_STOPS, VARIANT_PROPS, BOOLEAN_DEFS, SLOT_INSERTIONS) — NO extraction
- [ ] Step 5: Re-derive per-entry variant props by matching state names to variantAxes (light reasoning)
- [ ] Step 6: (folded into Step 4 — the spec content is already authored in the .md)
- [ ] Step 7: Audit the assembled render inputs against the .md
- [ ] Step 8: Import and detach the Screen Reader template
- [ ] Step 9: Fill header fields (component name and guidelines)
- [ ] Step 10–11: Render state sections with artwork (one figma_execute per state/focus-order entry)
- [ ] Step 12: Visual validation (+ post-render check that every documented focus stop resolved a bbox)
Step 0: Require and parse the component .md (fail fast)

This skill is a consumer of the `.md` source of truth. It does not re-extract from Figma and does not re-run the screen-reader reasoning layer — that work already happened in extract-voice/create-component-md and is baked into the .md's Voice section. Your job is to render that section into a Figma frame.

  1. Resolve the `.md` path. Use the exact path the user gave, else an attached or open .md in context. The .md may live anywhere; do NOT invent or guess a path. If neither resolves to an existing file, abort per item 2. Never pause to ask the user which file to use.
  2. Require the file. If no file exists at the resolved .md path, abort immediately with this exact single-line diagnostic and stop — do NOT fall back to extraction:

> This skill requires the component's Markdown .md spec (produced by create-component-md). Provide the path to it. (create-component-md needs a _base.json from the uSpec Extract plugin.)

  1. Parse the Voice section (## Voice / Screen reader) from the .md body:
  • Guidelines — the blockquote immediately under the confidence header → GUIDELINES.
  • Focus order — the ### Focus order table (columns # | Part | Announcement | Role | Properties | Notes). Each row → one focus-order table { focusOrderIndex: #, name: Part, announcement: Announcement, properties: [...] }. Absent for single-stop components.
  • Per-state platform tables — each ### State: {name} → a state entry; inside, the three #### VoiceOver (iOS) / #### TalkBack (Android) / #### ARIA (Web) sub-sections → SECTIONS; inside each, one table per ##### {focus-stop name} (or a single unnamed table) with the Announcement row + property rows → { name, announcement, focusOrderIndex, properties: [{property, value, notes}] }.
  • Slot insertions — the optional ### Slot insertions prose block (- In focus order preview: slot **{slotName}** populated with **{componentNodeId}**. Overrides: …).
  1. Parse the `render-meta` block (the fenced JSON between <!-- render-meta:start v=1 --> and <!-- render-meta:end -->):
  • COMP_SET_ID = component.compSetNodeId.
  • BOOLEAN_DEFS = reshape booleanDefs[] → { [key]: default }. Each key is the raw component-property key setProperties expects (it matches a render-meta.propertyDefs raw key); when in doubt, cross-check against propertyDefs and use the raw-key form.
  • variantAxes / variantAxesDefaults — for Step 5 state→variant mapping.
  • slotContents[] — for resolving slot insertion componentId targets.
  • fileKey, nodeId — for the Step 13 completion link and template placement.
  1. Parse the hidden `voice-render-meta` carry (the <!-- voice-render-meta v=1 … --> HTML comment at the end of the Voice body). It is a single JSON object { "focusStops": [ { "name", "focusOrderIndex", "layerName", "slotIndex" }, … ] }. Key it by name. This is the only source for each focus stop's live Figma layerName — findStopNode matches node.name === stop.name, so FOCUS_STOPS[].name MUST be the layerName from this carry, never the human-readable part name.

FORBIDDEN — do NOT re-extract. When the component .md is present (it always is past Step 0), you MUST NOT run the legacy extraction/tree-walk. Specifically:

  • Do NOT run any figma_execute / use_figma script that walks the component tree to rebuild elements, variantAxes, booleanDefs, slotDefs, or slotVisibility (the old Step 4 extractElement / extractChildren / resolvePreferredComponents extraction script is deleted — it does not exist in this skill anymore).
  • Do NOT re-derive announcements, merge analysis, focus-stop counts, or platform property rows — they are authored in the .md and copied verbatim.
  • The ONLY Figma calls this skill makes are: the template import (Step 8), the header fill (Step 9), and the unified per-entry render (Steps 10–11), which reads each focus stop's live bbox by name-match on the rendered instance. No other live reads are permitted.
Step 1: Read References (only as needed)

The announcements, merge analysis, and platform property rows are already authored in the .md — you do NOT re-derive them. Read the platform references only if you need to reason about a slot-scenario choice (e.g., which preferred fill realizes a documented focus stop) while building SLOT_INSERTIONS:

Skip this step entirely when the .md has no slot insertions.

Step 2: Verify MCP Connection

Read mcpProvider from uspecs.config.json and verify the connection (rendering requires a live Figma session):

If `figma-console`:

  • figma_get_status — Confirm Desktop Bridge plugin is active
  • If connection fails: "Please open Figma Desktop and run the Desktop Bridge plugin. Then try again."

If `figma-mcp`:

  • Connection is verified implicitly on the first use_figma call. No explicit check needed.
  • If the first call fails: "Please verify your FIGMA_API_KEY is set correctly in your MCP configuration."
Step 3: Read Template Key

Read the file uspecs.config.json and extract:

  • The screenReader value from the templateKeys object → save as SCREEN_READER_TEMPLATE_KEY
  • The fontFamily value → save as FONT_FAMILY (default to Inter if not set)

If the template key is empty, tell the user:

The screen reader template key is not configured. Run {{skill:firstrun}} with your Figma template library link first.
Step 4: Build render inputs from the parsed .md (no extraction)

Everything the render scripts need is already in the .md you parsed in Step 0. Assemble the render inputs directly — there is no extraction call here (see the FORBIDDEN directive in Step 0).

Build these values:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
249
Repository forks
29
7-day trend score
0

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/redongreen/uspec/create-voice/badge)](https://verified-skill.com/skills/redongreen/uspec/create-voice)

Something wrong with this skill or its page? Tell us.