Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when a component library needs a workshop — one story per concept, JSDoc summaries the manifest can carry, stories run as tests, and an opt-in MCP channel that replaces guessing with querying.
インストールする前に、エージェントに与えられる指示の中身を確認できます。
A story is not a demo. It is the component's executable documentation: the artefact an agent reads to learn what the component accepts, and the harness that catches a contrast or focus defect while the component is still in isolation. Stack-agnostic — the tool is Storybook, the discipline is not.
Lifted out of react-shadcn-ui § Component workshop, which
keeps a pointer here rather than a copy.
ONE CONCEPT PER STORY. NEVER A "SizesAndVariants" STORY.
EVERY COMPONENT EXPORT AND EVERY STORY CARRIES A JSDoc @summary.
A STORY THAT SHOWS AN ANTI-PATTERN IS TAGGED `!manifest` OR THE AGENT LEARNS FROM IT.
STORIES RUN. A STORY NOBODY RUNS IS A SCREENSHOT WITH EXTRA STEPS.
A shared component library exists or is being started, and one of: stories are being added, an agent needs an inventory of what the library already offers, an a11y regression should be caught in isolation rather than on a screen, or a Storybook MCP channel is available and nobody has decided whether to use it.
Skip it for a handful of one-off components with a single consumer — the setup and upkeep outweigh the return, and that judgement belongs to the reader rather than to this skill.
The state-coverage rows every reusable component owes become story names:
Default, Loading, Empty, Error, Disabled, Dark. One concept each.
A combined story — the canonical anti-pattern is SizesAndVariants — fails at both jobs it
has: a human cannot tell which knob caused what, and an agent reading it cannot learn a
single prop's effect because every value is co-present. Split it, one axis per story
(Storybook's own guidance on writing effective stories).
Stories render under the same semantic tokens as the app and the .dark class; a
hardcoded preview theme makes the workshop lie about what the component looks like in place.
Hover, Focus, Active, Keyboard and ReducedMotion join the set above, and they
carry one extra rule: each asserts a resolved computed style or a handler effect, never a
screenshot. A component that owes a state checklist and proves it with a pixel diff has
not proved it — a screenshot is a resting frame, and none of these five is a resting frame.
| Story | Drive | Assert |
|---|---|---|
Hover | userEvent.hover(el) | the resolved property the hover rule is supposed to change actually changed |
Focus | focus the element | the :focus styles resolve as intended |
Keyboard | userEvent.tab() until the element is active | a visible :focus-visible indicator resolves — programmatic focus does not set it in Chromium, so a .focus() call reports a real focus ring as absent |
Active | press and hold | what pressing adds on top of hover — a pointer cannot press without hovering, so asserting against the resting style makes one removed hover rule fail two stories |
ReducedMotion | emulate prefers-reduced-motion: reduce | what the surface presents instead of the motion, per accessibility-auditor § 2 — not that the media block exists |
The Active and Keyboard rows are not style advice. Both are measured failure modes from
building the probe that backs this set, recorded here so the next author does not rediscover
them: the first produced a duplicate finding for a single defect, the second reports a focus
ring that is present as missing.
Beside the state stories, each responsive component owes a row per declared breakpoint
(1440 / 768 / 375 / 320) asserting the layout property that is supposed to change there —
flex-direction, grid-template-columns, display. One row per breakpoint, not one per
property: a single media rule usually moves several properties at once, and one finding each
counts one defect several times.
Where a workshop is absent, this set is still assertable. These stories are a contract
about what is asserted, not about a particular runner — the ui_conformance_probe script
exercises the same five states and the same breakpoint rows against a file URL. It and its
sensitivity fixture live in the package repository and are not shipped to consumers,
which is why both are named rather than linked: a path to either resolves nowhere in an
install. The fixture is the evidence for the two sensitivity claims above — removing one
hover rule turns exactly the hover assertion red and nothing else, and removing one media
rule turns exactly the matching breakpoint row red.
@summary is required, and the reason is mechanicalThe manifest an agent reads truncates descriptions. A component whose summary is a paragraph arrives as a fragment, and the agent then infers the rest. So:
/** @summary A single-action button. Owns its own focus ring; never wrap in an anchor. */
export const Button = …
/** @summary Disabled — the click handler is not attached, not merely ignored. */
export const Disabled: StoryObj<typeof Button> = …
One sentence, front-loaded with the fact that changes a caller's decision.
The first step is not a story, it is an inventory. A library large enough to want a workshop
is large enough that the component being asked for already exists under another name, and a
second Badge is the failure this skill's own § Do NOT is trying to prevent elsewhere.
Read the existing stories — via the MCP channel below when it is available, by reading the files otherwise — and only then decide whether anything needs writing.
docs-list over a running Storybook.And.@summary on the export and on each story.
tags: ['!manifest'].Run the project's story test command (the Vitest addon's storybook test, or whatever
package.json declares — read it, do not assume a name), then read the a11y result.
Write findings into state.ui_review.a11y in the shape
react-shadcn-ui § Review pass already defines:
{violations: [{rule, selector, severity}, …], severity_floor?, accepted_violations?}
Use that shape exactly. The engine de-duplicates on it, so a finding written in a different shape is not a differently-formatted finding — it is a finding the engine counts twice.
Browser tooling stays a consumer dependency, the same posture as react-shadcn-ui: this
package installs no browser and runs none. Absent the tooling, say the a11y half did not run
rather than reporting zero violations — an unrun check and a clean check produce the same
number and mean opposite things.
One finding is decidable without a browser, and it ships beside this skill:
scripts/story_contrast_floor.ts computes the WCAG 2.1 contrast ratio between two colours a
story declares in its own args and emits the same (rule, selector, severity) shape. It is
not axe and not a substitute for § Validate — it sees no rendered page, so role, focus,
and computed-style defects are all outside it, and a colour arriving through a token
indirection is invisible to it. It exists because "we cannot run axe here" is not a reason to
check nothing, and a declared colour pair is decidable from the file.
scripts/story_contrast_floor.ts reads story files and computes arithmetic. No network, no
subprocess, no writes, and it never evaluates the story it reads — it matches declared literals
with a regex rather than importing the module, so running it over an untrusted repository
executes none of that repository's code. Importing a story to inspect its args would run
that file, which is the one thing a static checker must not start doing.
"Opt-in" is about the agent connecting, not about installing. A 2026-08-24
npx storybook@latest init --yes scaffold ships @storybook/addon-mcp and
@storybook/addon-a11y in devDependencies by default — recorded verbatim in
tests/fixtures/stack/storybook-current/, which is also the only source any
Storybook major stated here may come from (storybook@^10.5.10). So the addon
usually already exists; what stays optional is whether an agent reaches a
running instance. The same scaffold prints "installed but is not entirely set
up yet", so its presence is not evidence the channel works.
When the project has @storybook/addon-mcp and a running Storybook,
existing-ui-audit prefers the live tools —
docs-list, then docs-show for the components that matter — over the
hand-read inventory. The live read wins; the file read is the fallback, and the fallback
is never removed: an agent that cannot reach a running Storybook must still be able to
inventory the library. The tool names are version-bound and were re-derived from a throwaway
installation on 2026-09-13 — existing-ui-audit § 4b carries
the derivation and the version boundary; do not restate it here.
React-only while in preview. Storybook's own MCP FAQ (docs 10.5) states the documentation toolset supports React only during preview, so Vue, Angular, and Web Components take the file-read path. Stated here rather than discovered at runtime.
Two operative rules, restated from Storybook's suggested agent instructions rather than copied verbatim:
(rule, selector, severity)
shape.SizesAndVariants looks efficient and destroys both jobs — a human cannot attribute
the effect, and an agent cannot learn a single prop from it.@summary.tags: ['!manifest'] so it is excluded from the manifest and the agent never learns from
it (Storybook's own tag mechanism for curating what the manifest exposes).react-shadcn-ui — the React stack lane, and the (rule, selector, severity) shape § Validate writes into.existing-ui-audit — the inventory the MCP path accelerates.js-library-packaging — the package around the workshop.accessibility-auditor — the WCAG depth behind the a11y half.fe-design § Component Architecture — the stack-agnostic isolate-and-document principle.まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when defining or auditing the activation event — aha-moment selection, retention correlation, falsifiable definition. Triggers on 'what is our aha moment', 'redefine activation'.
日本語の概要は準備中です。原文の説明を表示しています。
Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'.
日本語の概要は準備中です。原文の説明を表示しています。
Adversarial critique — devil's advocate, stress-test, honest teardown ('poke holes', 'be brutal', 'was hältst du davon'); explicit request only. Routine code or design review → code-review.
日本語の概要は準備中です。原文の説明を表示しています。
Use when reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md. Understands the full .augment/, agents/, and copilot-instructions structure.
日本語の概要は準備中です。原文の説明を表示しています。
Use for an adversarial red-team / blue-team / auditor review of an AI agent's CONFIG + behaviour (rules, skills, MCP, hooks, permissions) — attack-chain → defensive-gap list, not a code audit.
日本語の概要は準備中です。原文の説明を表示しています。