unify-design
unify-design
Most vibe-coder web projects start with a template, get rushed into production, and end up with two versions of every button, three shades of "primary blue", spacing values that were eyeballed to the nearest pixel, and a navigation bar that doesn't match between two of the pages. None of those are bugs on their own, but together they make the product look like it was assembled from three different apps.
This skill treats the project's brand identity (BI) — colors, spacing, typography, radii, shadows, breakpoints, and the handful of components that appear on every page — as the single source of truth. Everything else in the codebase is expected to reference it. When the code drifts, this skill finds the drift and pushes the values back into tokens.
What this skill is: a design-system auditor and a token extractor. It establishes the source of truth when it's missing, finds every place the source of truth is bypassed, and rewrites those places to reference the tokens.
What this skill is not: a brand designer (it uses the project's existing BI or scaffolds opinionated defaults), a visual regression tester (Chromatic and Percy already do that), a component-library rewriter (it respects the framework the project already uses), or a figma-to-code converter.
State assumptions — before acting
Before starting the procedure, write an explicit Assumptions block. Don't pick silently between interpretations; surface the choice. If any assumption is wrong or ambiguous, pause and ask — do not proceed on a guess.
Required block:
Assumptions:
- Framework: <Tailwind v3 | Tailwind v4 | CSS Modules | styled-components | Emotion | MUI | Chakra | vanilla CSS + custom properties>
- Tokens file: <present at <path> | missing (scaffold step required)>
- Brand defined: <primary color + display font known | undefined (operator must provide — cannot guess)>
- Requested action: <audit only | scaffold tokens file | drift fix (single file) | multi-file consolidation (hand off to refactor-verify)>
Typical items for this skill:
- The framework (Tailwind v3 / Tailwind v4 / CSS Modules / styled-components / Emotion / MUI / Chakra / vanilla CSS with custom properties)
- Whether a tokens file exists and where it lives — absence triggers the scaffold step
- Whether the brand is defined (primary color + display font known) — absence blocks scaffolding; the skill asks the operator for the two values it cannot guess
Stop-and-ask triggers:
- Tokens file is missing AND brand is undefined — scaffolding would invent a brand; ask for primary color and display font first
- Multiple framework idioms coexist (e.g., Tailwind + styled-components in the same project) — never consolidate across frameworks without operator decision on which idiom wins
Silent picks are the most common failure mode: the skill runs, produces plausible output, and the operator doesn't notice the wrong interpretation was chosen. The Assumptions block is cheap insurance.
When to trigger
Direct operator asks:
- "make this match the design system" / "unify the buttons"
- "why do these two pages look different"
- "extract these colors to tokens" / "these spacings are all over the place"
- "too many hardcoded values" / "디자인 통일해줘" / "토큰으로 뽑아줘"
- "design system audit" / "BI audit" / "brand consistency"
Situational:
- Before a public launch. Inconsistencies read as amateurish to a first-time visitor more than any single missing feature does.
- After porting from a template. Templates ship with hardcoded values everywhere. Unwinding them is the difference between "feels like yours" and "feels like a cloned demo."
- After three or more AI-generated UI sessions. Each session tends to reinvent spacing and colors because the model doesn't remember the prior session's choices. Drift accumulates quietly.
- When two operators are working on different pages. Two humans plus two AI sessions equals four slightly different blues within a week.
The three things this skill does
1. Establish the BI source of truth
If the project has a tokens file, use it. If it doesn't, scaffold one. The scaffold is opinionated, not arbitrary — the operator can adjust, but the defaults come from something real.
Detect the framework first. The tokens file lives wherever the framework expects it:
| Framework marker | Where tokens live | Notes |
|---|---|---|
tailwind.config.ts / tailwind.config.js |
theme.extend block (Tailwind v3) |
Also update content: globs so JIT sees the new files |
@tailwindcss/postcss + @import "tailwindcss" in CSS |
@theme { ... } in app/globals.css or src/styles/globals.css (Tailwind v4) |
v4 is CSS-first; no JS config by default |
tailwind.config.ts + CSS with @theme |
warn — mixed v3/v4, pick one | v3 theme.extend and v4 @theme produce silent conflicts |
theme.ts + ThemeProvider from styled-components / @emotion/react |
a single lib/theme.ts module exported as the shared theme object |
|
createTheme from @mui/material |
lib/theme.ts returning the result of createTheme({ ... }) |
|
extendTheme from @chakra-ui/react |
lib/theme.ts returning extendTheme({ ... }) |
|
| Plain CSS / CSS Modules | src/styles/tokens.css with :root { --name: value; } |
Single source everyone imports first |
| SCSS | src/styles/_tokens.scss with $name: value; |
Same principle, SCSS variables |
| Vanilla Extract | src/styles/tokens.css.ts exported as vars |
Scaffolded defaults — only used when the project has nothing. Each scale is opinionated on purpose so the operator doesn't have to invent one:
// Spacing — 4px base, powers of ~1.5
spacing: {
0: '0',
px: '1px',
0.5: '2px',
1: '4px',
2: '8px',
3: '12px',
4: '16px',
5: '20px',
6: '24px',
8: '32px',
10: '40px',
12: '48px',
16: '64px',
20: '80px',
24: '96px',
}
// Typography scale — major third (1.25)
fontSize: {
xs: ['12px', { lineHeight: '16px' }],
sm: ['14px', { lineHeight: '20px' }],
base: ['16px', { lineHeight: '24px' }],
lg: ['18px', { lineHeight: '28px' }],
xl: ['20px', { lineHeight: '28px' }],
'2xl':['24px', { lineHeight: '32px' }],
'3xl':['30px', { lineHeight: '36px' }],
'4xl':['36px', { lineHeight: '40px' }],
'5xl':['48px', { lineHeight: '1' }],
}
// Radius — conservative, on-brand
borderRadius: {
none: '0',
sm: '2px',
DEFAULT: '6px',
md: '8px',
lg: '12px',
xl: '16px',
'2xl':'24px',
full: '9999px',
}
// Semantic color slots — operator fills with actual hex values
colors: {
primary: { 50: '#...', 100: '#...', /* 200–900 */ },
neutral: { 0: '#ffffff', 50: '#...', /* ... */, 1000: '#000000' },
success: { 500: '#...' },
warning: { 500: '#...' },
danger: { 500: '#...' },
// no "brand" aliases until the operator picks one — "primary" covers it
}
Do not invent hex values the operator did not choose. If the scaffold needs a color palette and the project has no logo or guidance, prompt the operator for one color ("what's the one color you want the product to feel like?") and derive the palette from it with a consistent scale — e.g., OKLCH stepping, or a tool like color-generate — not by making up six random hexes.
Typography goes through the same scaffold. Default to one display typeface and one text typeface, both from Google Fonts or the project's existing import. Do not introduce a third.
2. Audit for drift against the BI
Once the tokens file is authoritative, every other file in the codebase is expected to reference it. The audit flags every place that bypasses it.
Audit patterns — run across src/, app/, components/, pages/, skipping node_modules, .next, dist, build, public, and the tokens file itself.
# Hardcoded hex colors outside the tokens file
git grep -nE '#[0-9a-fA-F]{3,8}\b' -- \
'*.tsx' '*.ts' '*.jsx' '*.js' '*.vue' '*.svelte' '*.css' '*.scss' '*.html' \
':!*tokens*' ':!*theme*' ':!*tailwind.config.*'
# Hardcoded rgb() / hsl() / oklch()
git grep -nE '(rgba?|hsla?|oklch|oklab)\(' -- \
'*.tsx' '*.ts' '*.jsx' '*.js' '*.css' '*.scss' \
':!*tokens*' ':!*theme*'
# Tailwind arbitrary values — the escape hatch that bypasses the theme scale
git grep -nE '\b(w|h|p|m|pt|pb|pl|pr|px|py|mt|mb|ml|mr|mx|my|gap|top|right|bottom|left|text|bg|border|rounded|shadow|z|inset)-\[' -- \
'*.tsx' '*.jsx' '*.html'
# Magic pixel / rem values inside JSX style props or CSS
git grep -nE '\b[0-9]+(\.[0-9]+)?(px|rem|em|vh|vw)\b' -- \
'*.tsx' '*.ts' '*.jsx' '*.js' '*.vue' '*.svelte' \
':!*tokens*' ':!*theme*' ':!*.config.*' ':!*stories*'
# Inline style objects (usually a sign of a one-off that should be a token)
git grep -nE 'style=\{\{' -- '*.tsx' '*.jsx'
Classify every hit. A grep match is a candidate, not a finding. Each candidate gets one of four classifications:
| Classification | Meaning | Action |
|---|---|---|
| DRIFT — trivial | Hardcoded value equals an existing token (e.g., #3B82F6 when --color-primary-500 is exactly #3B82F6) |
Replace with the token name. Safe, zero-risk. |
| DRIFT — near-match | Hardcoded value is close to a token but not equal (e.g., #3b82f7 vs #3B82F6) |
Almost always a copy-paste error. Replace with the token. Ask the operator once if the difference was intentional. |
| DRIFT — missing token | Hardcoded value has no matching token (e.g., a #ff6b35 accent that exists nowhere in the palette) |
Two options: add the value to the tokens file (if it's reused >2 times) or replace with the closest existing token (if it's a one-off accident). |
| INTENTIONAL | The hardcoded value is context-specific and correct (a brand image overlay, a third-party iframe border, a placeholder gradient) | Label it explicitly with a comment: /* unify-design:ignore — this is a one-off product photo gradient */. Counted as reviewed, not flagged again. |
Component-level audits — not just individual values. Some drift is structural:
- Multiple
Button.tsxfiles — find every file namedButton.*or that exports aButtoncomponent. Diff the prop shapes. If two buttons differ only in padding or color, they're the same component with two hardcoded variants; consolidate. - Multiple navigation components — find every
<nav>tag. If two pages have different navigation structures, flag for consolidation unless they're intentionally different (e.g., an authenticated vs. marketing nav). - Duplicate card / modal / form shells — same pattern. The giveaway is three files with nearly identical JSX scaffolding and different class names.
- Inconsistent page-level layout — different pages wrap their content in different max-width or padding. Usually means the project is missing a
<PageShell />or<Container />. - Logo sprawl — multiple copies of the logo as separate files (
logo.png,logo-dark.png,logo-small.svg,Logo2.tsx, etc.) with no consolidation. Pick one SVG source and wrap it in a<Logo />component withvariantandsizeprops.
3. Fix drift by extracting to tokens
For every DRIFT finding, the skill produces a concrete diff proposal. Small, local fixes apply directly (with the operator's approval). Fixes that touch more than a few files hand off to refactor-verify — the token rename or component consolidation becomes a refactor node with symbol-level verification.
Pattern — hardcoded color to token:
<button
- className="bg-[#3B82F6] text-white px-[12px] py-[6px] rounded-[8px]"
+ className="bg-primary-500 text-neutral-0 px-3 py-1.5 rounded-md"
>
Pattern — duplicate button components to one:
- // components/PrimaryButton.tsx
- export const PrimaryButton = ({ children }) => (
- <button className="bg-primary-500 text-white px-4 py-2 rounded">{children}</button>
- );
-
- // components/CTAButton.tsx
- export const CTAButton = ({ children }) => (
- <button className="bg-primary-600 text-white px-5 py-2.5 rounded-md">{children}</button>
- );
+ // components/ui/Button.tsx
+ type ButtonVariant = 'primary' | 'cta' | 'secondary' | 'ghost';
+ type ButtonSize = 'sm' | 'md' | 'lg';
+ export const Button = ({ variant = 'primary', size = 'md', children }) => (
+ <button className={cn(buttonBase, variantStyles[variant], sizeStyles[size])}>
+ {children}
+ </button>
+ );
Then hand off to refactor-verify to rename every import site from PrimaryButton / CTAButton to Button with the right variant, with call-site closure verified.
Pattern — inline style to token class:
- <div style={{ padding: '14px', backgroundColor: '#F9FAFB', borderRadius: 8 }}>
+ <div className="p-3.5 bg-neutral-50 rounded-md">
If p-3.5 doesn't exist in the scale, either add it (3.5: '14px') or round to the nearest token (p-4 = 16px, p-3 = 12px). The skill asks once per unique value, not once per usage — a single decision covers every 14px in the repo.
Output format
# Design unification audit — <scope> — <date>
## BI source of truth
- Framework: <Tailwind v4 | Tailwind v3 | CSS Modules | styled-components | MUI | Chakra | vanilla>
- Tokens file: `<path>` (✅ exists / ⚠ missing, scaffold proposed)
- Palette size: <N colors across M semantic slots>
- Spacing scale: <N tokens>
- Typography scale: <N tokens>
## Summary
- Total candidates scanned: <N>
- DRIFT — trivial: <N> (auto-replaceable)
- DRIFT — near-match: <N> (needs one confirmation, then replaceable)
- DRIFT — missing token: <N> (operator decides: add to tokens or replace)
- INTENTIONAL — already labeled: <N>
## Top drift hotspots (files with >5 drift findings)
1. `src/app/(marketing)/page.tsx` — 23 drift findings (19 hardcoded px values, 4 hex colors)
2. `src/components/Hero.tsx` — 11 drift findings (1 color, 10 spacing)
3. `src/app/pricing/page.tsx` — 9 drift findings (3 near-match colors, 6 spacing)
## Duplicate components
- **Button**: 3 variants across `PrimaryButton.tsx`, `CTAButton.tsx`, `OutlineButton.tsx`. Consolidate to one `Button` with `variant="primary" | "cta" | "outline"`. Hand off to `refactor-verify` for the rename + import-site update.
- **Card**: 2 variants in `FeatureCard.tsx`, `PricingCard.tsx`. Same JSX shell, different padding. Consolidate with `padding` prop.
- **Logo**: 4 files (`logo.png`, `logo-dark.svg`, `Logo.tsx`, `BrandMark.tsx`). Pick the SVG, wrap in one `<Logo />`.
## Proposed tokens to add
- `spacing.3.5: '14px'` (appears 12 times across 4 files)
- `colors.accent.500: '#FF6B35'` (appears 3 times, no matching token; operator confirms it's a brand color)
## Fixes applied (this session)
- <list of files edited with before/after context>
## Fixes pending operator approval
- <list of files with the proposed diff, one-sentence rationale>
## Hand-offs
- Multi-file refactor (Button consolidation, Card consolidation) → `refactor-verify`
- New env-var for theme-switching (dark mode) → `manage-secrets-env` if one is added
- Documentation of the token system in `CLAUDE.md` → `write-for-ai`
Things not to do
- Don't invent a brand. If the project has no BI at all, scaffold opinionated defaults and ask the operator for one real value (primary color, display font) before proceeding. Never write arbitrary hex values into a tokens file and call it done.
- Don't rewrite history or restructure the repo. Token extraction is an in-place refactor, not a rearrangement of the directory tree.
- Don't migrate frameworks. If the project is on styled-components, use its theme object; don't propose switching to Tailwind. Respect the project's framework choice.
- Don't touch anything outside
src//app//components//pages//styles/. Config files, build scripts, CI workflows, and backend code are out of scope. - Don't fix every drift finding at once. Scope every run to one area (one page, one component tree, one color concern) unless the operator explicitly asks for a full sweep. A 400-file unified diff is impossible to review.
- Don't count
.storybook/or*.stories.*files as drift sources. Stories are intentionally hardcoded — they're documentation, not production code. - Don't count
tailwind.config.*,*tokens*,*theme*, orglobals.cssas drift sources. Those files contain the source of truth; they're supposed to have literal values. - Don't silently replace near-match colors.
#3b82f7vs#3B82F6is close, but only the operator knows whether it was intentional. Ask once. - Don't break contrast or accessibility. Every color replacement must preserve WCAG AA contrast. If a replacement drops a color to a lower contrast tier, flag it and ask.
- Don't add features the operator did not request. While fixing drift in one component, if you notice an unused Button variant or an accessibility gap in an adjacent component, report it as a hand-off suggestion — do not fix it in the same commit. Cross-component consolidations are a separate scope and a separate operator approval; silent expansion corrupts the tokens-change blast radius.
Sweep mode — read-only audit
When invoked from /vibesubin (the umbrella skill's parallel sweep), this skill runs in read-only audit mode. Do not scaffold the tokens file, do not edit components, do not consolidate duplicates. Produce a findings-only report.
- BI source of truth: present / missing / stale.
- Drift counts by file, sorted by hotspot.
- Duplicate component candidates (Button, Card, Nav, Logo) with file lists.
- Stoplight verdict: 🟢 design is consistent and token-driven / 🟡 drift in a few files, no structural duplication / 🔴 multiple duplicate components, tokens file missing or ignored, visible cross-page inconsistency.
- One-line "fix with" pointer indicating
/unify-designwill scaffold and extract when invoked directly.
How to tell: the task context from the umbrella will include a sweep=read-only marker or an explicit "produce findings only, do not edit" instruction. Obey it. If the operator invokes this skill by name, the full procedure applies and editing is expected.
Harsh mode — no hedging
When the task context contains the tone=harsh marker (usually set by the /vibesubin harsh umbrella invocation, but can also come from direct requests like "don't sugarcoat" / "brutal review" / "매운 맛" / "厳しめ"), switch output rules:
- Lead with the worst structural drift. First line of the report is the single most visible inconsistency — "the primary button has three different implementations in this repo and two of them ship on the same page", "
#3B82F6,#3b82f7, and#4A90E2all exist in this codebase and none of them are tokens", "there is no<Logo />component — the logo is pasted into 6 files as raw<img>tags." No preamble. - No "might want to consider" softening. Drop "could benefit from", "worth thinking about", "some consolidation would help". Replace with directive verbs: "consolidate the three button components now", "extract these 23 hardcoded spacings to tokens before the next push", "fix the palette before launch — four near-match blues will show up in one design review."
- Drift hotspots get named victims. Balanced mode says "several files have high drift counts". Harsh mode says "
src/app/pricing/page.tsxhas 23 drift findings — it was clearly pasted together in one session and never revisited. Fix this page first." - Inconsistencies become consequences. "Two of your pages use different navigation structures. A first-time visitor who lands on
/pricingand then navigates to/docswill think they ended up on a different product." - No "mostly consistent with a few polish items" closures. If the audit found any duplicate component or any missing tokens file, the verdict line commits: "Do not ship this until the button is consolidated and the tokens file exists."
- Missing BI source gets urgency framing. "There is no tokens file. Every change you've made to this project has been a silent vote for a different shade of blue. Scaffold the tokens file now; argue about the palette after."
Harsh mode does not invent drift, exaggerate counts, or become rude. Every harsh statement must cite the same file, line, or grep output the balanced version would cite. The change is framing, not substance.
Layperson mode — plain-language translation
When the task context contains explain=layperson (from /vibesubin explain, /vibesubin easy, "쉽게 설명해줘", "일반인도 이해되게", "explain like I'm non-technical", "非開発者でも分かるように", "用通俗的话解释"), add a plain-language layer to every finding this skill emits. Combines freely with tone=harsh. Full rules at /plugins/vibesubin/skills/vibesubin/references/layperson-translation.md.
Three dimensions per finding
Every finding gets three questions answered in plain language, in the operator's language (Korean / English / Japanese / Chinese):
- 왜 이것을 해야 하나요? / Why should you do this? — "한 사이트 안에서 primary blue가 3가지, button이 2개 구현, padding이 5가지 다른 숫자로 박혀 있으면 사용자에게는 '급조한 느낌'이 먼저 닿습니다."
- 왜 중요한 작업인가요? / Why is it an important task? — "디자인 drift는 처음엔 안 보여요. 10개 화면 늘어나면 통일하는 비용이 10배가 되고, 결국 그냥 안 통일하게 됩니다. 지금이 제일 싼 시점."
- 그래서 무엇을 하나요? / So what gets done? — "tokens 파일을 찾거나 만들고(색·간격·타이포·그림자), 하드코딩된 hex·arbitrary Tailwind 값·중복 컴포넌트(Button/Card/Nav)를 찾아 tokens로 되돌립니다. 프레임워크(Tailwind v3/v4 / styled-components / MUI 등)는 프로젝트의 것을 따릅니다."
Severity translation
- 🔴 no-source → "tokens 파일 자체가 없음 — 아무 기준이 없는 상태"
- 🟡 drift-heavy → "tokens는 있는데 절반 이상이 무시됨"
- 🟢 unified → "대부분 tokens 참조 — 소수 call site만 정리"
Box format
Wrap each finding in the box format from the shared reference. Header uses urgency phrase and the finding number. Footer names the hand-off skill.
What does NOT change
Findings, counts, file:line references, evidence, and severity are identical to balanced/harsh output. Only the wrapping and dimension annotations are added.
Hand-offs
- Multi-file token rename or component consolidation →
refactor-verifywith the rename/merge plan, call-site closure verified against the old and new names - Documentation of the token system, component library, or BI decisions →
write-for-aito produce aDESIGN.mdor to updateCLAUDE.mdwith the invariants ("always referencecolors.primary, never a literal hex") - Adding Stylelint or ESLint rules to catch future drift in CI →
setup-cifor the workflow integration, plus astylelint.config.jswith rules likecolor-no-hexanddeclaration-property-value-allowed-list - Logo files, brand assets, or oversized images found during the audit →
manage-assetsfor bloat triage (PNGs that should be SVG, unused font files, logo duplicates sitting inpublic/) - Component deletions (after consolidation, the old
PrimaryButton.tsxis dead) →fight-repo-rotto confirm unused, thenrefactor-verifyto delete safely - Secrets-adjacent work (API keys for a theme-switching service, environment-specific brand configs) →
manage-secrets-env
Framework-specific notes
Tailwind v3
Tokens live in tailwind.config.ts under theme.extend. Arbitrary values like w-[432px] bypass the theme — flag every instance. Custom plugins that generate utility classes (e.g., tailwind-variants, cva) count as part of the token source if they reference theme().
Tailwind v4
Tokens live in CSS via @theme { --color-primary-500: ...; }. No tailwind.config.js by default. Don't mix v3 theme.extend and v4 @theme in the same project — the conflict is silent and one will win unpredictably. If you find both, warn the operator and pick one.
styled-components / Emotion
The theme object in lib/theme.ts is the source of truth. Components access it via props.theme or the useTheme hook. Hardcoded values inside styled.div\...`template literals are drift. Replace with${props => props.theme.colors.primary[500]}`.
Material UI
createTheme builds the theme. The palette, spacing, typography, and shape sections are the tokens. Components accept sx props that should reference theme values: sx={{ p: 2 }} (= theme.spacing(2)), not sx={{ p: '16px' }}.
Chakra UI
extendTheme wraps Chakra's defaults. The operator's custom tokens extend the theme. Chakra's style props should reference theme values: <Box p={4} bg="primary.500" />, not <Box p="16px" bg="#3B82F6" />.
CSS Modules / vanilla CSS
:root { --color-primary-500: #3B82F6; } in src/styles/tokens.css, imported first in layout.tsx / _app.tsx / index.html. Components use var(--color-primary-500). Hardcoded hex values in any .module.css file that doesn't reference a var() are drift.
References and templates
references/token-scaffolds.md— per-framework starter tokens file with opinionated defaults (spacing scale, typography scale, radius scale, shadow scale; palette slots that the operator fills with real values). Kept intentionally minimal.
The grep patterns, classification rules, and fix templates are inlined in this SKILL.md rather than split into references — the audit is the primary deliverable and the analysis needs to live in one readable file. Framework-specific notes (Tailwind, styled-components, MUI, Chakra, vanilla CSS) are inlined above for the same reason.
More from subinium/vibesubin
manage-secrets-env
Opinionated defaults and full lifecycle playbook for secrets and environment variables. Decides where a secret or env-specific value lives (constant, .env, CI secret, env var), scaffolds .env.example and .gitignore, and manages the lifecycle end to end — add, update, rotate, remove, migrate between buckets, audit cross-environment drift, provision new environments. High-stakes companion to project-conventions. Language-agnostic.
4setup-ci
Teaches CI/CD from first principles to a non-developer, then scaffolds a working test + deploy pipeline. Handles the common hosts (GitHub Actions, GitLab CI, CircleCI, Travis, Jenkins) and common deploy targets (SSH to VM, Vercel, Netlify, Fly.io, Cloud Run, Docker registries). Asks what the operator has before generating anything — never assumes.
3audit-security
Runs a deliberately small, hand-curated security sweep across a repo. Finds secrets committed to git, SQL/shell injection patterns, XSS sinks, path traversal, dangerous deserialization, missing cookie flags, wildcard CORS, and tracked credential files. Triages every finding as real / false-positive / needs-review before reporting. Language-agnostic, no heavyweight scanner required.
3refactor-verify
Proves a behavior-preserving code change (refactor, rename, split, merge, extract, inline, or delete of confirmed-dead code) is actually complete. Plans the change as a dependency tree, executes it from the leaves up, and after each step proves 1:1 semantic equivalence through four independent checks — exported symbol-set diff, per-node AST diff, full behavioral test suite, and call-site closure via find-references. Runs before claiming any such change is done. Works for any language with a test runner and a way to grep for symbols.
3manage-assets
Finds oversized files, binary bloat, and accidental artifact commits in a repo — large files currently tracked, large blobs hiding in git history, LFS migration candidates, asset directories growing without a policy, duplicate binaries. Pure diagnosis — never edits, never deletes, never rewrites history. Hands off to manage-secrets-env if secrets are found inside blobs, to refactor-verify if history rewriting is required, to fight-repo-rot if assets are unused. Language-agnostic.
3vibesubin
The vibesubin command and vibe. Runs every code-hygiene specialist in the plugin across a repository in parallel and synthesizes their findings into a single prioritized report. Process skills like `/ship-cycle` and host-specific wrappers like `/codex-fix` are direct-call only and not part of the sweep. Invoke by name (/vibesubin) for a full sweep, or let it route a vague request to the right sub-skill when the operator isn't sure where to start. Read-only by default; fixes apply only after the operator approves items from the report. Two optional output modifiers — `tone=harsh` for direct, no-hedging framing, and `explain=layperson` for plain-language translation (3-dimension box format with "왜 해야 / 왜 중요 / 무엇을 할지" per finding); the two combine. When two specialists give contradictory advice on the same file, the umbrella emits a skill-conflict block (gap / reason / basis per side) instead of silently picking one.
3