Sb audit
Periodic Storybook audit — naming-drift survey, archived/decision-board review, lifecycle tagging, usage refresh. Use for 'audit my Storybook', 'find drift', 'show pending decisions', or a periodic catalog health check.From its SKILL.md
npx -y skills add strongeron/storybook-workbench --skill sb-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 8 commands, including `$SKILL/scripts/audit-drift.sh` and 7 more.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
6.7 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it
sb-audit — drift survey + decision board
The periodic gate. Surveys the catalog, seeds the ledger, names consolidation candidates.
Run it
SKILL=${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}
CORE=${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}
"$SKILL/scripts/audit-drift.sh" # naming drift across stories
"$SKILL/scripts/audit-archived.sh" # L1/L2/L3 preservation surveillance (HEAVY warning)
"$CORE/scripts/find-stories-by-tag.sh" decision:pending # stale decisions needing a nudge
"$CORE/scripts/extract-component-usage.sh" # REFRESH real prop-usage → component-usage.json (auto, no hand-edits)
"$SKILL/scripts/audit-controls.sh" . # Controls-panel coverage: component stories missing argTypes + manager showPanel
"$CORE/scripts/refresh-usage.sh" --docs . # ONE-COMMAND refresh: components + tokens + routes + health JSON + re-stamp per-component usage MDX
# App flow + component lists: re-run the repo-local app-graph extractor if present, then VALIDATE it
[ -f .storybook/scripts/extract-app-graph.mjs ] && node .storybook/scripts/extract-app-graph.mjs # refresh app-graph.json + component-pages.json
[ -f .storybook/app-graph.json ] && node -e 'const g=require("./.storybook/app-graph.json"); const by={}; for(const e of g.edges) by[e.attribution]=(by[e.attribution]||0)+1; console.log("flow edges by attribution:", by, "| unresolved:", g.unresolvedEdges.length); for (const u of g.unresolvedEdges) console.log(" UNRESOLVED", u.provenance, "→", u.to, "—", u.reason)'
Sequence — don't run all six cold. Start with audit-drift.sh (cheap, names consolidation
candidates). The HEAVY audit-archived.sh L1/L2/L3 scan only earns its cost once the catalog is
sizable — skip it under ~20 chosen stories (nothing to prune yet). Run audit-controls.sh +
extract-component-usage.sh when you're checking coverage; refresh-usage.sh --docs is the
all-in-one rendered refresh — run it last, not alongside the individual extractors it supersedes.
One-command usage refresh. refresh-usage.sh runs all four extractors (inventory/token map,
component prop-usage, routes, design-system health — every rendered file; see CONTEXT.md
§STORAGE MAP) and — with --docs — re-stamps every <Name>.usage.mdx. The autodocs
import the JSON, so a Storybook rebuild after this reflects current reality with no hand-editing. Trigger
it three ways: per-script (here, or call one extractor directly), every audit (this step), or in CI before
storybook build. The usage prop on StateGrid/StateMatrix reads the same JSON to badge each
variant cell with its real call-site count (declared-but-unused → struck through).
Auto-refresh usage (no human authoring). Re-running extract-component-usage.sh here keeps
component-usage.json current as the app changes; the usage-profile.mdx autodocs read that JSON at
build time, so the "real usage in this app" tables update themselves on the next Storybook build. Wire
the same one-liner into CI for repos that want it always fresh. If usage shifted (a variant that was
declaredButUnused is now shipped, or vice-versa), flag the affected stories' usage:unused tags as a
drift finding.
Decide (ask yourself)
- Drift — 17 names for "empty state" → consolidation candidate; 1 cluster → noise, ignore.
- Archive —
audit-archived.shflags >20 chosen stories → prune to the durable ledger seeded fromtemplates/design-decisions.md($SKILL/scripts/prune-to-ledger.sh); otherwise leave it. - Pending decisions — stale
decision:pending→ remind stakeholders. - Controls coverage —
audit-controls.shflags component stories that passargsbut wire neitherargTypesnor a controls-disable (so they expose no usable Controls panel), and warns if.storybook/manager.tsdoesn'tshowPanel. Fix by wiringargTypes(unions → select, flags → boolean, group viatable.category, hide non-serializable props) — or disabling controls on render-only stories — per the Controls pattern in sb-stories (its without-mcp reference, §13). - Flow / app-graph drift — the validate step above prints edges-by-attribution + every
UNRESOLVED. IfunresolvedEdgesgrew, or a new entry's reason is "dynamic dispatch" / a nav idiom the extractor doesn't parse, that's a real edge being dropped — the app added a navigation pattern the script misses. Work the under-extraction loop in sb-flows (flow-capture.md), extend the repo-localextract-app-graph.mjs, re-validate. Never accept a silently shrinking map: an edge with no source is unresolved, not absent. (Same JSON also feeds the component lists — a component that lost allparents/pagesis a dead-component or import-trace finding.)
Load references/galleries-and-tags.md when scaffolding a TagGallery,
references/lifecycle-tags.md for archive/deprecation, references/propagate-workflow.md
when a prune candidate appears, references/anti-patterns.md when reviewing AI-generated stories
(the full list — mega-stories, inline mocks, CSF2, pseudo-class misuse) — pick based on what surfaced, don't load all four.
Ledger (durable memory you steer)
Append findings to .storybook/audit/findings.md (timestamped, append-only). Log-only rule: a
real prod issue out of scope for the story pass (unassociated <label>, sub-AA contrast, headless
crash) gets a LOG-ONLY: marker — record it, keep moving, don't touch app code unless asked. After
seeding the ledger, prompt to commit it (git add .storybook/audit/) — an uncommitted ledger is
one git clean from gone.
Next
/sb-hub → usually a sb-stories consolidation pass or a sb-ship for a graduated Explore.
What ships with it: 14 files
120.7 KB alongside SKILL.md, 7 of them executable
agents/
- openai.yaml730 B
references/
- anti-patterns.md15.0 KB
- galleries-and-tags.md16.4 KB
- lifecycle-tags.md12.4 KB
- propagate-workflow.md17.8 KB
scripts/
- audit-archived.shruns8.4 KB
- audit-controls.shruns4.5 KB
- audit-drift.shruns4.3 KB
- extract-component-usage.shruns11.3 KB
- find-stories-by-tag.shruns3.3 KB
- prune-to-ledger.shruns7.2 KB
- refresh-usage.shruns3.5 KB
templates/
- design-decisions.md1.8 KB
- CONTEXT.md14.1 KB
Gives 0 of the 12 instructions most audit compliance skills give in ~1.4k tokens
Counted across 960 of the 1,589 authors here whose files we hold, read 2026-09-06
- Read product marketing context before asking questionsin 29 of 960, across 11 files
- Rank findings by severityin 29 of 960, across 22 files
- Generate audit reportin 22 of 960
- Run the audit scriptin 20 of 960, across 19 files
- Generate a prioritized action plan reportin 19 of 960, across 11 files
- Ensure one H1 per pagein 15 of 960, across 5 files
- Ensure sitemap exists and is accessiblein 14 of 960, across 4 files
- Verify alt text on all imagesin 12 of 960, across 3 files
- Determine the audit scope before startingin 12 of 960, across 4 files
- Verify important pages allowed in robots.txtin 11 of 960, across 2 files
- Detect business type from homepage signalsin 11 of 960, across 7 files
- Delegate specialized tasks to subagentsin 11 of 960, across 7 files
Said here and by no other author read
- Run audit-drift.sh for naming drift
- Run audit-archived.sh for preservation surveillance
- Run find-stories-by-tag.sh for stale decisions
- Run extract-component-usage.sh for prop usage
- Run audit-controls.sh for controls-panel coverage
- Run refresh-usage.sh for rendered refresh
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.