jubscodes/get-shit-pretty/gsp-brand-apply
Claude Code and agent skill by jubscodes/get-shit-pretty
- community
Checking that the SKILL.md file is still in the repository.
Install a brand theme into a shadcn codebase — use when: apply the brand to the code, install the theme, switch to brand X, refresh the theme
Install
npx vskill@latest install jubscodes/get-shit-pretty/gsp-brand-applySKILL.md
<context> The universal theme-install primitive. Reads a {brand}.theme.json (registry:theme) artifact and installs it into a shadcn codebase via shadcn apply --only theme. Surgical — only cssVars (and optionally fonts) change; components are untouched.
Spawns an ephemeral localhost HTTP server (serve-preset.js, colocated in this skill's bin/) because shadcn CLI's --preset flag accepts HTTP URLs only (file:// and bare paths are rejected).
Called explicitly by the user, or invoked by /gsp-brand-guidelines (after generation, with consent) and /gsp-brand-refine (after token regen). </context>
<objective> Install a brand's {brand}.theme.json into a target shadcn project's globals.css.
Input: brand name (positional arg) + optional --target <path> Output: Updated CSS file (path declared in {target}/components.json → tailwind.css) — cssVars only — plus log entry in {BRAND_PATH}/STATE.md Agent: None — inline Bash </objective>
<rules>
- Always use
AskUserQuestionfor user-facing questions — never raw text prompts - One decision per question — never batch multiple questions in a single message
</rules>
<process>
Step 0: Resolve brand
Parse the user's argument:
- If a brand name was passed (e.g.
/gsp-brand-apply lyra) →BRAND={arg}. - If no name was given → scan
.design/branding/for brand directories. - If exactly one → use it.
- If multiple → use
AskUserQuestion: "Which brand should I apply?" — list names as options. - If zero → error: "No brand found. Run
/gsp-brand-guidelinesfirst." Stop.
Set BRAND_PATH=.design/branding/{BRAND}. Set THEME_JSON={BRAND_PATH}/patterns/{BRAND}.theme.json.
If THEME_JSON does not exist → error: "Brand '{BRAND}' has no theme.json. Run /gsp-brand-guidelines {BRAND} to generate it." Stop.
Step 0.5: Pre-flight — preserve user work
shadcn apply --only theme is not strictly cssVars-only. Its preflight may also bump dependency versions in package.json (notably shadcn itself and @base-ui/react), regenerate package-lock.json, and rewrite components.json. We don't suppress this — there's no upstream flag (see issue tracker) — but we refuse to run when those files have uncommitted work, so the user can review the dep changes via git diff afterward.
If {TARGET} is inside a git repository, run:
If the exit code is non-zero (uncommitted changes exist in any of those three files), use AskUserQuestion:
- Question: "
{TARGET}has uncommitted changes inpackage.json,package-lock.json, orcomponents.json.shadcn applymay modify these (preflight bumps versions). Continue anyway?" - Options:
- A: "Cancel — I'll commit/stash first"
- B: "Proceed anyway — I accept potential conflicts with my pending work"
If A → exit cleanly. If B → continue.
If {TARGET} is not a git repo, skip this check silently — there's nothing to compare against.
Step 1: Resolve target
Parse --target flag if present.
If no flag:
- Read project config at
.design/projects/*/config.jsonand findapp_path. - If exactly one project config → use that
app_path. - If multiple → use
AskUserQuestion: "Which project's codebase?" — list project names + paths. - If zero project configs → error: "No project found. Pass
--target <path>explicitly." Stop.
Set TARGET={app_path} (default . if empty).
Verify {TARGET}/components.json exists. If not → error: "{TARGET} is not a shadcn project (no components.json). Run /gsp-scaffold first." Stop.
Step 2: Detect currently-installed brand (informational)
Resolve the CSS path: read {TARGET}/components.json and extract the value at .tailwind.css (a relative path from {TARGET}). Open {TARGET}/{cssPath}. Look for OKLCH cssVars in :root. Compare the --background light value against .design/branding/*/patterns/*.theme.json files in the workspace.
- If a match is found →
CURRENT={matched-brand-name}. - If file exists but no match →
CURRENT="custom or shadcn defaults". - If file missing →
CURRENT="(none — fresh project)".
This is informational only — surfaced in the confirmation message in Step 3.
Step 2.5: Detect custom token indirection
Scan the cssVars sections of {TARGET}/{cssPath} (:root and .dark blocks) for declarations of the form --<name>: var(--<other>); — these are custom indirection layers (e.g. --background: var(--brand-bg);).
shadcn apply --only theme will REPLACE those var() references with literal OKLCH values from the theme.json. The custom indirection is lost — the upstream tokens (e.g. --brand-bg) remain defined elsewhere in the file, but the shadcn cssVars no longer reference them.
If any var(--*) declarations are found in the cssVars blocks, use AskUserQuestion:
- Question: "
{cssPath}has {N} cssVar(s) using `var(--*)` indirection (e.g.{first-example}).shadcn applywill replace these with literal OKLCH values, breaking the indirection layer. Continue?" - Options:
- A: "Yes, replace with literal values"
- B: "No, cancel — preserve the indirection"
If B → append - {ISO-8601 timestamp}: apply cancelled — would have broken indirection in {cssPath} to {BRAND_PATH}/STATE.md under ## Apply log. Output "Apply cancelled — preserve your indirection layer manually if needed." Exit cleanly. If A → continue.
If no var(--*) indirection is found, skip this confirmation silently.
Step 3: Confirm (when overwriting a different installed brand)
If CURRENT is a recognized brand name AND it differs from BRAND:
Use AskUserQuestion:
- Question: "Currently installed: {CURRENT}. Replace with {BRAND}?"
- Options:
- A: "Yes, replace"
- B: "No, cancel"
If B → append - {ISO-8601 timestamp}: apply cancelled by user (target: {TARGET}) to {BRAND_PATH}/STATE.md under ## Apply log. Output "Apply cancelled" and exit cleanly. If A → continue.
If CURRENT is unrecognized or fresh, skip this confirmation and proceed silently.
Steps 4–6: Spawn preset server, run apply, kill server
Run Steps 4 through 6 as a single Bash call. SERVER_PID, PRESET_URL, and APPLY_EXIT are shell variables — they do not survive across separate Bash tool invocations.
Capture the bash output (especially the APPLY_EXIT=N line and any shadcn stderr) to use in Step 7.
Step 7: Verify or report failure
If APPLY_EXIT != 0:
- Surface the captured shadcn output to the user (concise — full stderr, plus a single-line summary).
- Append to
{BRAND_PATH}/STATE.mdunder## Apply log:- {ISO-timestamp}: apply FAILED — exit {code} on {TARGET}. - Stop. Do NOT auto-retry. Do NOT manually paste tokens as a fallback.
If APPLY_EXIT == 0:
- Resolve the CSS path: read
{TARGET}/components.jsonand extract the value at.tailwind.css(a relative path from{TARGET}). - Read
{BRAND_PATH}/patterns/{BRAND}.theme.jsonand extractcssVars.light.background(the brand's signature OKLCH value). - Open
{TARGET}/{cssPath}. Verify: - Contains
oklch( - Has both
:root {and.dark {blocks - Declares
--background,--foreground,--primary,--radius - Contains the exact `cssVars.light.background` value from the theme.json (this distinguishes a successful brand apply from shadcn's own nova defaults, which also satisfy the structural checks above)
- If any check fails → warn (do not error): "Apply reported success but expected tokens not found in
{cssPath}— the apply may have fallen back to defaults. Inspect manually." Continue to Step 8. - If all checks pass → continue to Step 8.
Step 8: Log success
Append to {BRAND_PATH}/STATE.md under a ## Apply log section. If the file or section doesn't exist, create it.
Step 9: Output
After apply, check whether package.json, package-lock.json, or components.json were modified by shadcn's preflight:
If the output is non-empty, list those files in the success block under a "Review" line so the user knows to inspect them. If empty (or the target is not a git repo), omit the Review line.
</process>
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckinggsp/skills/gsp-brand-apply/SKILL.md
Popularity
- Repository stars
- 35
- Repository forks
- 2
- Repository npm downloads, 7 days
- 59
- 7-day trend score
- 31
Stars and forks are for the whole GitHub repository, not this skill alone. Downloads are for the repository's npm package. Refreshed 17 May 2026, 5 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/jubscodes/get-shit-pretty/gsp-brand-apply)