xiaohongshu
xiaohongshu
dev-storybook
Comprehensive Storybook skill for Vue 3 - story creation, auditing, component discovery, visual testing, and CI integration. Merged from dev-storybook, storybook-audit, and storybook-master.
Full skill instructions
BUILD, AUDIT, and AUTOMATE Storybook stories for Vue 3 components with TypeScript. This comprehensive skill covers story creation, auditing existing stories for issues, component discovery and inventory, and CI/CD integration. Use when creating component documentation, fixing story compilation errors, auditing for display issues, or setting up automated testing workflows.
Trigger Keywords: "streamline", "streamlined", "match app", "looks different", "visual fidelity"
When user asks to "streamline" a Storybook story, they mean: Make the story look EXACTLY like the component appears in the actual app.
CRITICAL: In FlowState, "streamlined" specifically means using glass morphism instead of solid black backgrounds.
--glass-bg-solid, rgba(0,0,0,0.95))/* Streamlined = Glass Morphism */
background: rgba(30, 32, 45, 0.75);
backdrop-filter: blur(24px) saturate(180%);
The app's signature look is glass panels floating over a purple/indigo gradient. If a component looks like a flat black box, it's NOT streamlined.
When streamlining a story, verify ALL of the following:
| Check | Requirement | How to Fix |
|---|---|---|
| 1. Use Actual Components | Story imports and renders the REAL Vue component, not a mockup | Import from @/components/... |
| 2. App Background | Story background matches app's purple/indigo gradient | Use background: var(--app-background-gradient) |
| 3. Glass Morphism | Modals/overlays use semi-transparent bg with blur, NOT solid black | Use rgba(30, 32, 45, 0.75) + backdrop-filter: blur(24px) |
| 4. Design Tokens | All styling uses CSS variables, no hardcoded values | Replace #hex and rgba() with var(--token) |
| 5. Correct Props | Story passes the same props the component expects | Check defineProps in component |
| 6. Event Handlers | All emitted events have handlers | Add @event="handler" |
| 7. Mock Data | Data looks realistic, matches production patterns | Use actual Task/Project types |
1. IDENTIFY the component being streamlined
└── Find the actual .vue component file
└── Read its props, emits, and slots
2. COMPARE story vs app
└── What does the story currently show?
└── What does the actual app show?
└── List the differences
3. FIX each difference:
a. Background: Use var(--app-background-gradient)
b. Components: Import actual components, not mockups
c. Tokens: Replace hardcoded colors with CSS variables
d. Props: Match component's defineProps interface
e. Data: Use realistic mock data
4. VERIFY with user
└── Ask user to check Storybook matches app
CRITICAL: The app uses a purple/indigo gradient, NOT neutral gray.
// ❌ WRONG - neutral gray (doesn't match app)
background: var(--surface-primary);
background: hsl(0, 0%, 12%);
// ✅ CORRECT - app's purple/indigo gradient
background: var(--app-background-gradient);
The --app-background-gradient is defined in design-tokens.css:
--app-background-gradient: linear-gradient(135deg,
hsl(220, 13%, 9%) 0%,
hsl(240, 21%, 15%) 25%,
hsl(250, 24%, 12%) 50%,
hsl(260, 20%, 14%) 75%,
hsl(220, 13%, 11%) 100%);
Before (mockup, wrong background):
export const Default: Story = {
render: () => ({
template: `
<div style="background: #1a1a1a; padding: 20px;">
<!-- Hardcoded mockup HTML -->
<div class="fake-card">
<h2>Task Title</h2>
<button>Action</button>
</div>
</div>
`
})
}
After (streamlined, matches app):
import QuickSortCard from '@/components/QuickSortCard.vue'
import { useTaskStore } from '@/stores/tasks'
export const Default: Story = {
render: () => ({
components: { QuickSortCard },
setup() {
const mockTask = { id: '1', title: 'Real Task', priority: 'high', ... }
return { mockTask }
},
template: `
<div style="
min-height: 100vh;
background: var(--app-background-gradient);
padding: var(--space-8);
">
<QuickSortCard :task="mockTask" @update-task="..." />
</div>
`
})
}
Problem: Components using --glass-bg-solid or opaque black backgrounds look wrong because they block the app's purple gradient from showing through.
Solution: Use semi-transparent backgrounds with blur so the gradient is visible through the glass effect.
/* ❌ WRONG - Solid black, no glass effect */
background: var(--glass-bg-solid); /* rgba(0, 0, 0, 0.95) */
background: rgba(0, 0, 0, 0.95);
background: #121214;
/* ✅ CORRECT - Semi-transparent with blur (glass morphism) */
background: rgba(30, 32, 45, 0.75);
backdrop-filter: blur(24px) saturate(180%);
-webkit-backdrop-filter: blur(24px) saturate(180%);
border: 1px solid var(--glass-border-medium);
Glass Morphism Recipe:
| Property | Value | Purpose |
|---|---|---|
background | rgba(30, 32, 45, 0.75) | Semi-transparent dark with slight purple tint |
backdrop-filter | blur(24px) saturate(180%) | Blur + color boost for depth |
border | 1px solid var(--glass-border-medium) | Subtle edge definition |
box-shadow | inset 0 1px 0 rgba(255, 255, 255, 0.1) | Top highlight for polish |
When to use glass morphism:
| Issue | Symptom | Fix |
|---|---|---|
| Mockup instead of component | Story shows different UI than app | Import actual component |
| Wrong background color | Black/gray instead of purple gradient | Use var(--app-background-gradient) |
| Solid black modal | Modal looks flat, no depth | Use glass morphism with rgba() + backdrop-filter |
| Hardcoded colors | Colors don't match design system | Use CSS variables |
| Missing components | Card missing buttons/badges | Import child components |
| Wrong spacing | Elements too cramped/spread | Use var(--space-X) tokens |
NEVER use <style> or <script> tags inside runtime templates:
// ❌ WRONG - Causes Vue compilation error
template: `
<div>
<style>
.my-class { color: red; }
</style>
<MyComponent />
</div>
`
// ✅ CORRECT - Apply styles globally or use inline styles
template: `
<div>
<MyComponent />
</div>
`
ALWAYS verify component props before writing stories:
# Check component interface
grep -A 5 "interface Props" src/components/MyComponent.vue
grep -A 5 "defineProps" src/components/MyComponent.vue
Example fix:
// Component expects: { isOpen: boolean, taskIds: string[] }
// ❌ WRONG story args
args: {
isVisible: true, // Wrong prop name
selectedTasks: [] // Wrong prop name
}
// ✅ CORRECT story args
args: {
isOpen: true,
taskIds: ['1', '2', '3']
}
ALWAYS include required Vue imports:
import type { Meta, StoryObj } from '@storybook/vue3'
import { ref, reactive, computed } from 'vue' // Include all Vue APIs you use
import MyComponent from '@/components/MyComponent.vue'
Common missing imports:
ref - For reactive statereactive - For reactive objectscomputed - For computed propertieswatch - For watchersonMounted, onUnmounted - For lifecycle hooksimport type { Meta, StoryObj } from '@storybook/vue3'
import { ref } from 'vue'
import MyComponent from '@/components/MyComponent.vue'
const meta = {
component: MyComponent,
title: '📁 Category/MyComponent',
tags: ['autodocs'],
parameters: {
layout: 'centered', // or 'fullscreen'
docs: {
description: {
component: 'Component description here'
}
}
}
} satisfies Meta<typeof MyComponent>
export default meta
type Story = StoryObj<typeof meta>
export const Default: Story = {
args: {
// Component props here
isOpen: true,
title: 'Example'
},
render: (args) => ({
components: { MyComponent },
setup() {
const isOpen = ref(args.isOpen)
const handleClose = () => {
isOpen.value = false
}
return {
isOpen,
handleClose,
args
}
},
template: `
<MyComponent
v-bind="args"
:is-open="isOpen"
@close="handleClose"
/>
`
})
}
export const ModalExample: Story = {
parameters: {
layout: 'fullscreen' // Modal needs full screen
},
args: {
isOpen: true,
title: 'Modal Title'
},
render: (args) => ({
components: { MyModal },
setup() {
const isOpen = ref(args.isOpen)
return {
isOpen,
args,
handleClose: () => { isOpen.value = false },
handleConfirm: () => { console.log('Confirmed') }
}
},
template: `
<div style="width: 100vw; height: 100vh; background: var(--surface-secondary);">
<MyModal
v-bind="args"
:is-open="isOpen"
@close="handleClose"
@confirm="handleConfirm"
/>
</div>
`
})
}
Problem: Too many similar stories create confusion and make components harder to understand.
Solution: Use focused, well-documented stories with clear purpose.
Every component story file should follow this organization:
export const Default: Story = {
args: {
variant: 'default',
hoverable: false,
// ... all props with defaults
},
render: (args) => ({
components: { MyComponent },
setup() {
return { args }
},
template: `
<MyComponent v-bind="args" style="width: 320px;">
<div style="padding: var(--space-2);">
<h3 style="margin: 0 0 var(--space-2) 0; font-size: 16px; font-weight: 600;">
Default Component
</h3>
<p style="margin: 0; font-size: 14px; color: var(--text-secondary);">
Usage guidance explaining when/where to use this component.
</p>
</div>
</MyComponent>
`
})
}
Purpose: Interactive playground for testing all prop combinations via Controls panel.
export const Variants: Story = {
parameters: {
docs: {
description: {
story: `**Visual variants for different contexts:**
- **Variant A**: When to use this variant
- **Variant B**: When to use this variant
- **Variant C**: When to use this variant`
}
}
},
render: () => ({
components: { MyComponent },
template: `
<div style="display: flex; gap: var(--space-6); flex-wrap: wrap;">
<MyComponent variant="a" style="width: 280px;">
<div style="padding: var(--space-4);">
<h4>Variant A</h4>
<p>Use when [specific context]</p>
</div>
</MyComponent>
<MyComponent variant="b" style="width: 280px;">
<div style="padding: var(--space-4);">
<h4>Variant B</h4>
<p>Use when [specific context]</p>
</div>
</MyComponent>
</div>
`
})
}
Purpose: Show all visual variants side by side with usage guidance.
Anti-pattern: Don't create separate stories for each variant (VariantA, VariantB, VariantC). Consolidate!
export const Effects: Story = {
parameters: {
layout: 'fullscreen',
docs: {
description: {
story: `**Effects for interaction and visual hierarchy:**
- **Hoverable**: Use when components are clickable
- **Glass**: Use on colorful/gradient backgrounds
- **Elevated**: Use to emphasize important content`
}
}
},
render: () => ({
components: { MyComponent },
template: `
<div style="padding: var(--space-8); display: flex; flex-direction: column; gap: var(--space-8);">
<!-- Hoverable -->
<div>
<h3>Hoverable Component</h3>
<p>Use when components are clickable. Hover to see the effect.</p>
<MyComponent hoverable style="width: 320px; cursor: pointer;">
Content here
</MyComponent>
</div>
<!-- Glass Effect (SHOW IN REALISTIC CONTEXT) -->
<div>
<h3>Glass Effect</h3>
<p>Use on colorful or gradient backgrounds.</p>
<div style="padding: var(--space-8); background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: var(--radius-xl);">
<MyComponent glass style="width: 320px;">
Glass effect shown on actual gradient!
</MyComponent>
</div>
</div>
</div>
`
})
}
Purpose: Show effects/states in realistic visual contexts (e.g., glass on gradient, not plain background).
Critical: Always show effects where they actually make sense visually.
export const WithSlots: Story = {
parameters: {
docs: {
description: {
story: `**Component supports slots for structured content:**
- **Header**: For titles, actions, or badges
- **Footer**: For metadata, timestamps, or action buttons
- Use slots to create consistent, structured layouts`
}
}
},
render: () => ({
components: { MyComponent },
template: `
<div style="display: flex; gap: var(--space-6); flex-wrap: wrap;">
<!-- Header only -->
<MyComponent style="width: 300px;">
<template #header>
<h3>Header Content</h3>
</template>
Main content
</MyComponent>
<!-- Footer only -->
<MyComponent style="width: 300px;">
Main content
<template #footer>
Footer actions
</template>
</MyComponent>
<!-- Both -->
<MyComponent style="width: 300px;">
<template #header>Header</template>
Main content
<template #footer>Footer</template>
</MyComponent>
</div>
`
})
}
Purpose: Show slot usage patterns side by side.
export const TaskCardExample: Story = {
parameters: {
docs: {
description: {
story: 'A realistic example showing how to combine variants, effects, and slots for production use.'
}
}
},
render: () => ({
components: { MyComponent },
template: `
<MyComponent hoverable elevated style="width: 380px;">
<template #header>
<!-- Complex header with badges, title, etc. -->
</template>
<div style="display: flex; flex-direction: column; gap: var(--space-4);">
<!-- Rich content with metadata, progress, etc. -->
</div>
<template #footer>
<!-- Actions and metadata -->
</template>
</MyComponent>
`
})
}
Purpose: Show production-ready example combining multiple features.
EVERY story must include usage guidance. Never show a variant without explaining when to use it.
const meta = {
component: MyComponent,
title: '🧩 Components/🔘 Base/MyComponent',
tags: ['autodocs'],
parameters: {
layout: 'centered',
docs: {
description: {
component: `Component description explaining its purpose.
**When to use:**
- Specific use case 1
- Specific use case 2
- Specific use case 3`
}
}
},
argTypes: {
variant: {
control: 'select',
options: ['default', 'outlined', 'filled'],
description: 'Visual style variant',
table: {
type: { summary: 'string' },
defaultValue: { summary: 'default' }
}
}
}
}
export const Variants: Story = {
parameters: {
docs: {
description: {
story: `**Visual variants for different contexts:**
- **Default**: Standard style (use for X)
- **Outlined**: Transparent background (use for Y)
- **Filled**: Solid background (use for Z)`
}
}
}
}
// Glass effect on gradient
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: var(--space-8);">
<MyComponent glass>
Now the glass effect actually makes sense!
</MyComponent>
</div>
// Elevated card on page
<div style="padding: var(--space-8); background: var(--surface-primary);">
<MyComponent elevated>
Extra shadow creates depth on the page
</MyComponent>
</div>
// Glass effect on plain background (can't see blur!)
<MyComponent glass>
Glass effect is invisible here
</MyComponent>
// Elevated without context (shadow purpose unclear)
<MyComponent elevated>
Why is this elevated?
</MyComponent>
Always include comprehensive argTypes with descriptions:
argTypes: {
variant: {
control: 'select',
options: ['default', 'outlined', 'filled'],
description: 'Visual style variant',
table: {
type: { summary: 'string' },
defaultValue: { summary: 'default' }
}
},
hoverable: {
control: 'boolean',
description: 'Add hover effects (elevation & transform)',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' }
}
}
}
Before creating multiple similar stories, ask:
Target: 5-7 focused stories per component, NOT 12+ redundant stories.
template: `
<div style="padding: 20px; background: var(--surface-primary);">
<MyComponent />
</div>
`
template: `
<div style="
padding: var(--space-4);
background: var(--surface-primary);
border-radius: var(--radius-lg);
">
<MyComponent />
</div>
`
Modify the component's scoped styles directly in the .vue file instead of trying to override in stories.
Cause: Attempting to use <style> or <script> tags in runtime template
Fix: Remove the tags and use inline styles or global component styles
// Before (causes error)
template: `<div><style>.foo{}</style><Component /></div>`
// After (works)
template: `<div style="..."><Component /></div>`
Cause: TypeScript path resolution in story files
Fix: This is usually a TypeScript check error only. Storybook will still work because Vite handles the paths. You can ignore or configure tsconfig.json to include story files.
Cause: Missing Vue import
Fix: Add import { ref } from 'vue'
Cause: Component expects different props than story provides
Fix:
grep -A 5 "defineProps" src/components/MyComponent.vuenpm run storybook # Start on port 6006
npm run build-storybook # Build static site
Stories are auto-discovered from:
src/**/*.stories.tssrc/**/*.stories.tsxdecorators: [
() => ({
template: '<div style="width: 100%; height: 100vh;"><story /></div>'
})
]
const createMockStore = (overrides = {}) => ({
state: {
items: [],
...overrides
},
getItem: (id: string) => mockData.find(item => item.id === id),
updateItem: (id: string, data: any) => {
console.log('Updated:', id, data)
}
})
export const WithMockStore: Story = {
render: () => ({
setup() {
const store = createMockStore({ items: mockItems })
return { store }
}
})
}
CRITICAL: Ensure design tokens use neutral grays (no blue tint)
Blue-tinted grays (WRONG):
--gray-950: 218, 33%, 12%; /* Hue 218 = Blue! */
--gray-900: 217, 33%, 17%; /* High saturation = Color tint! */
Neutral grays (CORRECT):
--gray-950: 0, 0%, 12%; /* Hue 0, Saturation 0% = Neutral */
--gray-900: 0, 0%, 17%; /* No color tint */
Check for blue tint:
grep "gray-9" src/assets/design-tokens.css
.stories.tsDefault, WithData, ErrorStateparameters.docs.descriptionargTypes to make props interactiveexport const Default: Story = { /* Basic usage */ }
export const Loading: Story = { /* Loading state */ }
export const Error: Story = { /* Error state */ }
export const WithData: Story = { /* Populated with data */ }
export const Empty: Story = { /* Empty state */ }
export const Interactive: Story = { /* Full interaction demo */ }
This section provides systematic auditing capabilities for detecting and fixing common Storybook issues.
Activate auditing capabilities when user mentions:
CRITICAL: Before attempting fixes, ask clarifying questions to understand the exact issue.
When user reports a Storybook issue, ask:
Issue Type Clarification:
Component Context:
Error Details:
User reports Storybook issue
├── "cut off" / "clipped" / "can't see"
│ └── Ask: "Docs page or Canvas?" + "Component type?"
│ └── Likely: iframe height issue → Check 1
│
├── "error" / "won't render" / "database"
│ └── Ask: "Console error message?"
│ └── Likely: Store dependency → Check 2
│
├── "doesn't match" / "wrong props"
│ └── Ask: "Which props are incorrect?"
│ └── Likely: Props mismatch → Check 4
│
├── "Cannot find name 'ref'" / "Cannot find name 'computed'"
│ └── Ask: "Which Vue APIs are you using in setup()?"
│ └── Likely: Missing imports → Check 7
│
├── "buttons don't work" / "can't close modal"
│ └── Ask: "What happens when you click [button]?"
│ └── Likely: Missing event handlers → Check 8
│
└── Unknown
└── Run full audit, then ask about findings
Issue: Docs pages cut off modals, popups, or dropdowns
Detection:
# Find stories with potentially low iframe heights
grep -rn "iframeHeight" src/stories/ | grep -E "iframeHeight: [0-5][0-9]{2},"
# Find stories without explicit height
grep -L "iframeHeight" src/stories/**/*.stories.ts
Component Type Guidelines:
| Component Type | Minimum Height | Notes |
|---|---|---|
| Simple components | 400px | Buttons, inputs, badges |
| Context menus | 600px | May have submenus |
| Dropdowns | 500px | Check max items |
| Modals (small) | 700px | Confirmation dialogs |
| Modals (large) | 900px | Forms, settings |
| Full-page overlays | 100vh | Use fullscreen layout |
| Components with submenus | 900px+ | Cascading menus need more |
Fix Pattern A: Iframe Height (Standard):
parameters: {
layout: 'fullscreen',
docs: {
story: {
inline: false,
iframeHeight: 900, // Adjust based on component type
}
}
},
Fix Pattern B: Inline Relative Container (Robust for Storybook 8/10):
parameters: {
layout: 'fullscreen',
docs: {
story: { inline: true }
}
},
decorators: [
() => ({
template: `
<div class="story-container" style="
background: var(--glass-bg-solid);
height: 850px;
width: 100%;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
">
<story />
</div>
`
})
]
Issue: Stories import real Pinia stores which initialize PouchDB → causes database errors
Detection:
# Find stories importing stores
grep -rn "from '@/stores" src/stories/
grep -rn "useTaskStore\|useTimerStore\|useCanvasStore\|useUIStore" src/stories/
Fix Options (in order of preference):
Option A - Props Only (best for presentational components):
// Pass data via props, no store needed
const mockTask: Task = {
id: '1',
title: 'Test Task',
status: 'planned',
priority: 'high',
}
export const Default: Story = {
args: {
task: mockTask,
onEdit: () => console.log('edit'),
onDelete: () => console.log('delete'),
}
}
Option B - Fresh Pinia Decorator (for components requiring store):
// Create decorator: src/stories/decorators/freshPiniaDecorator.ts
import { createPinia, setActivePinia } from 'pinia'
export const freshPiniaDecorator = (story: any) => {
setActivePinia(createPinia())
return story()
}
Issue: Runtime templates contain <style> or <script> tags causing Vue errors
Detection:
grep -rn "template:.*<style>" src/stories/
grep -rn "template:.*<script>" src/stories/
Issue: Story args don't match component prop definitions
Detection:
# Get component props
grep -A 30 "defineProps" src/components/[ComponentName].vue
# Get story args
grep -A 15 "args:" src/stories/[ComponentName].stories.ts
Common Mismatches:
| Story Arg | Actual Prop | Fix |
|---|---|---|
isVisible | isOpen | Use isOpen |
selectedTasks | taskIds | Use taskIds |
onClose | @close emit | Add handler |
Issue: Modals/overlays using layout: 'centered' causing cutoff
Detection:
grep -l "Modal\|Overlay\|Dialog\|Popup\|Drawer" src/stories/**/*.ts | \
xargs grep -L "layout: 'fullscreen'"
Issue: Stories or decorators use hardcoded colors instead of CSS design tokens
Detection:
# Find hardcoded hex colors in stories
grep -rn "#[0-9a-fA-F]\{3,8\}" src/stories/ --include="*.ts" --include="*.vue"
# Find hardcoded rgba values
grep -rn "rgba\s*(" src/stories/ --include="*.ts" --include="*.vue"
Token Categories to Use:
| Purpose | CSS Variable |
|---|---|
| Priority High | var(--color-priority-high) |
| Priority Medium | var(--color-priority-medium) |
| Priority Low | var(--color-priority-low) |
| Glass background | var(--glass-bg), var(--glass-bg-solid) |
| Glass border | var(--glass-border) |
| Modal/Dropdown bg | var(--modal-bg), var(--dropdown-bg) |
| Text primary | var(--text-primary) |
| Surface colors | var(--surface-primary), var(--surface-secondary) |
Issue: Stories use Vue APIs without importing them
Fix Pattern:
// Add all used Vue APIs
import { ref, computed, watch, onMounted } from 'vue'
Issue: Stories don't provide handlers for critical events
Critical Events Checklist:
For Modal/Overlay components:
@close - User closes modal@confirm - User confirms action@cancel - User cancels actionFor Form components:
@submit - User submits form@cancel - User cancels formRun this bash script for a complete audit:
echo "=== STORYBOOK AUDIT REPORT ==="
echo ""
echo "=== 1. Store Dependencies ==="
grep -rn "from '@/stores" src/stories/ 2>/dev/null | head -20 || echo "None found"
echo ""
echo "=== 2. Low Iframe Heights (<600px) ==="
grep -rn "iframeHeight: [0-5][0-9]{2}," src/stories/ 2>/dev/null || echo "None found"
echo ""
echo "=== 3. Template Style/Script Tags ==="
grep -rn "template:" src/stories/ 2>/dev/null | grep -E "<style|<script" || echo "None found"
echo ""
echo "=== 4. Modals Without Fullscreen ==="
for f in $(find src/stories -name "*.stories.ts" 2>/dev/null); do
if grep -q "Modal\|Overlay\|Dialog" "$f" && ! grep -q "fullscreen" "$f"; then
echo "$f: NEEDS FULLSCREEN"
fi
done
echo ""
echo "=== 5. Hardcoded Colors (Token Violations) ==="
grep -rn "#[0-9a-fA-F]\{3,8\}" src/stories/ --include="*.ts" 2>/dev/null | head -15 || echo "None found"
echo ""
echo "=== Audit Complete ==="
onMounted for centeringlayout: 'fullscreen'var(--glass-bg-solid)inline: true with fixed height (600px-800px)This section provides automated component discovery, story generation, and CI integration.
Smart Source Scanning:
Usage:
python3 scripts/phase1_discovery.py
Output Files:
storybook-inventory.csv: Complete component inventorymissing-stories-report.md: Undocumented components reportcomponent-update-map.json: Component-to-story mappingStory Generation:
Usage:
python3 scripts/phase2_generation.py --auto-fix
Visual Test Harness:
CI Enforcement:
Create .storybook/skill-config.yml:
discovery:
component_paths:
- "src/components/**/*"
story_paths:
- "src/**/*.stories.*"
ignore_patterns:
- "*.test.*"
- "node_modules/**"
generation:
autodocs: true
controls: true
accessibility_testing: true
testing:
visual_testing:
enabled: true
tool: "chromatic"
accessibility:
enabled: true
standards: ["WCAG2.1AA"]
ci:
enforce_coverage: true
fail_on_missing_stories: true
Located in scripts/ directory:
run_storybook_master.py - Main orchestrator for all phasesphase1_discovery.py - Component discoveryphase2_generation.py - Story generationThis skill learns from successful fixes. When a solution works:
Document the solution by asking user:
Update the skill with user approval:
Before/after examples are available in examples/ directory:
before-after-modal-iframe.md - Iframe height fix for modalsbefore-after-contextmenu-height.md - Height fix for cascading menusbefore-after-store-dependency.md - Store dependency fixbefore-after-template-style.md - Template style tag fixbefore-after-props-mismatch.md - Props matching component definitionsbefore-after-missing-imports.md - Missing Vue imports fixbefore-after-event-handlers.md - Missing event handlers fixBest practices reference available in references/storybook-best-practices.md.
When to use this skill: Creating or fixing Storybook stories, resolving story compilation errors, documenting Vue 3 components, setting up component showcases, auditing stories for issues, automating component discovery.
CRITICAL: Before claiming ANY issue, bug, or problem is "fixed", "resolved", "working", or "complete", the following verification protocol is MANDATORY:
REQUIRED: Use the AskUserQuestion tool to explicitly ask the user to verify the fix:
"I've implemented [description of fix]. Before I mark this as complete, please verify:
1. [Specific thing to check #1]
2. [Specific thing to check #2]
3. Does this fix the issue you were experiencing?
Please confirm the fix works as expected, or let me know what's still not working."
Remember: The user is the final authority on whether something is fixed. No exceptions.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience