AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Sb Health

skill-strongeron-storybook-workbench-sb-health · by strongeron

Check design-system health for a React+Vite app — raw hex, undefined/unused tokens, scale gaps, DESIGN.md drift, and (opt-in) property→token-family misuse. Use for 'is my design system healthy', 'find raw colors', 'check tokens', or a mixed design system.

No reviews yet
0 installs
37 views
0.0% view→install

Install

$ agentstack add skill-strongeron-storybook-workbench-sb-health

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-strongeron-storybook-workbench-sb-health)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Sb Health? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

sb-health — design-system health gate

The browser can't shell out, so the script runs the checks and writes JSON the wrapper renders. design-system-health.json is a rendered output (Health Docs + DesignSystemHealth/TokenMatrix), so refresh-usage.sh re-runs this check with the other rendered extractors — see CONTEXT.md §STORAGE MAP.

Run it

SKILL=${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}
CORE=${CLAUDE_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}
"$SKILL/scripts/validate-design-system.sh"       # → .storybook/design-system-health.json
# --emit-prompt  also outputs an LLM sub-agent prompt for semantic checks
#                (naming drift, semantic-vs-presentational, scale clarity)
"$CORE/scripts/scaffold-wrapper.sh" DesignSystemHealth   # → .storybook/wrappers/ (+ icons.tsx)

# Opt-in property→token-family check (off until a designer authors the rules file):
"$SKILL/scripts/check-property-tokens.py" --init   # scaffold design-system/lint/colors.json (+ schema)

What it checks

  • raw-color — hex/rgba/hsl literals in components (should be tokens). When the literal's value EQUALS

an existing token's resolved value (e.g. #005596 on a tile whose siblings use bg-secondary--secondary resolves to #005596), the fix is to adopt that exact token, not invent a new one — the finding names the matching token when it can resolve one, so the fix is "replace with --x", not "add a token".

  • undefined-token — components reference --foo that's not declared
  • scale-gap — spacing/type scale has unexpected jumps
  • unused-token — declared but never referenced (var, Tailwind utility, or custom @utility).

Read from sb-inventory's single source (.storybook/project-inventory.jsontokens.map), not re-scanned here, so health, inventory, and the token views never disagree. Run sb-inventory first; if the file is absent this check is skipped.

  • design-md — a DESIGN.md (Google Labs YAML-tokens-plus-markdown, an increasingly common way to

brief agents on a visual identity) is a claim, not ground truth — like AGENTS.md it drifts as the code changes, or was wrong from the start. The script finds it and cross-checks the colors it claims against the colors the code's CSS tokens actually declare, emitting design-md-drift for each claimed color the code doesn't define. Treat a present DESIGN.md as untrusted until reconciled.

  • property-token-family (opt-in) — a valid, declared token used on the wrong property family

(e.g. color: var(--color-container) — a container token used as text color). raw-color catches "no token at all"; undefined-token catches "token doesn't exist"; this catches "real token, wrong slot." Off until a designer authors design-system/lint/colors.json (see below), so the zero-config default is preserved. Findings are warning/info only — an opt-in never flips a green CI build red.

  • runs stylelint if configured

Report summary (errors/warnings/info counts) and the top findings. The DesignSystemHealth wrapper renders severity with the shared icon set (no emoji).

The JSON it writes (shape — read these fields, don't re-derive). Each finding is {kind, severity, message, file?, line?, fix?}; summary rolls up the counts:

{
  "findings": [
    { "kind": "raw-color",       "severity": "error",   "file": "Button.tsx", "line": 42, "message": "#3b82f6 literal", "fix": "use --color-primary" },
    { "kind": "undefined-token", "severity": "error",   "file": "Card.tsx",   "line": 11, "message": "--surface-2 not declared" },
    { "kind": "design-md-drift", "severity": "warning", "message": "DESIGN.md claims #1e90ff; no token declares it" },
    { "kind": "unused-token",    "severity": "info",    "message": "--legacy-accent declared, never referenced" },
    { "kind": "scale-gap",       "severity": "info",    "message": "spacing jumps 16px → 48px" },
    { "kind": "property-token-family", "severity": "warning", "file": "Card.css", "line": 3, "message": "background uses --color-content — not allowed for 'background*' (expects --color-container / --color-canvas)", "fix": "Use one of --color-container, --color-canvas, or remap with /* color-lint-alias: … */" }
  ],
  "summary": { "total": 6, "errors": 2, "warnings": 2, "info": 2, "checksRun": ["raw-color", "undefined-token", "..."] }
}

Property→token-family rules (opt-in, designer-owned)

The which-token-family-belongs-on-which-property logic is design intent, so it lives in a designer-editable rules file — not in the script. The designer owns the rules; the dev owns the linter. Scaffold it once (writes the file and a JSON Schema so it's self-documenting in any editor):

"$SKILL/scripts/check-property-tokens.py" --init    # → design-system/lint/colors.json (+ colors.schema.json)
// design-system/lint/colors.json — owned by the designer
{
  "$schema": "./colors.schema.json",
  "propertyTokens": {
    "color":       ["--color-content"],                                   // exact property
    "background*": ["--color-container", "--color-canvas", "--color-backdrop"], // family (trailing *)
    "box-shadow":  ["--color-border", "--color-shadow"],
    "border*":     ["--color-border"]                                     // values are token PREFIXES
  }
}

Only properties listed are governed (opt in one property at a time). Escape hatches, in order of preference — both are read from your source files:

/* color-lint-alias: --color-theme --color-container */  /* file-level prefix remap: a token is
                                                            semantically right but lives in the "wrong"
                                                            family — treat this prefix as that one */
color: var(--color-theme-fg); /* color-lint-ignore */    /* per-line suppression — counted, and the
                                                            report nudges a refactor past 10. The number
                                                            growing is the signal: mute fast, fix slowly. */

The rules file is itself a claim, not ground truth (same stance as DESIGN.md): if a rule allows a token-prefix that no declared token matches, the script emits property-rules-drift so a stale config can't silently pass — or silently mis-flag.

Triage order — severity is the verdict, not the count: fix error first (raw-color → map to an existing token; undefined-token → declare it or fix the typo), reconcile warning (design-md-drift → hand to design-md; property-token-family → swap to an allowed token, or if the token is genuinely right add a color-lint-alias; property-rules-drift → fix the rules file), and report info as-is (unused-token / scale-gap / property-lint-suppressions are signals to verify, never auto-fixes — see Never below). A repo with 0 errors and 20 info findings is healthy.

Never (and the non-obvious why)

  • NEVER delete an unused-token on sight — it is info, not error. A static scan can't see a

token consumed by a Tailwind utility (bg-[--brand]), a runtime var() built by string concat, or a sibling app in the monorepo. "Unused" means "I didn't find a reference," not "safe to remove."

  • NEVER treat scale-gap as a failure to fix — it's info. Real scales have intentional jumps (a

display size far above body); "smoothing" them invents tokens nobody asked for and breaks the rhythm a designer chose.

  • NEVER trust DESIGN.md as ground truth — it's a claim, like AGENTS.md/CLAUDE.md, and drifts.

Reconcile against design-md-drift first; an un-reconciled DESIGN.md will confidently lie about colors the code doesn't define.

  • NEVER "fix" a raw-color by inventing a new token — map it to an existing token. A fresh token

per literal just relocates the mess into the token layer (more undefined-token noise next run).

  • NEVER hand-recompute this JSON by re-grepping — the browser can't shell out, so the script is the

single source; cite its fields. Re-deriving by eye is how the counts drift from what the wrapper renders.

When to defer

For extraction (turning a messy codebase into tokens + components), this skill only measures. To actually extract, run /ds-runbook/ds-audit/ds-token-extract/ds-component-extract, then come back here to verify health and to sb-stories for capture.

For a DESIGN.md that drifted (or to author/regenerate one from the code's real tokens), hand off to the design-md skill — it composes, extracts, and deep-audits the Google Labs DESIGN.md format. sb-health only flags the drift; design-md reconciles or rewrites the brief.

Next

If health is poor and the project is in transition, fix tokens (or route to ds-* skills) before authoring stories. Otherwise append a finding and continue to sb-stories.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.