Agent skill

UI Feature Dev

by scragnog in scragnog/HOT-Step-CPP

Guides adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns, API wiring, routing registration, Tailwind/i18n rules, and the Vite HMR dev loop.

MITAuto-check passedFrontend & Design

Install UI Feature Dev

skills CLI
$ npx skills add scragnog/HOT-Step-CPP --skill ui-feature-dev -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install scragnog/HOT-Step-CPP ui-feature-dev --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/scragnog/HOT-Step-CPP.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/ui-feature-dev .claude/skills/ui-feature-dev && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ui-feature-dev
GitHub stars
171
Token cost
~5.3k tokens
SKILL.md length
2,300 words
Files
2
Skills in repo
18
Repo updated
First seen
Licence
MIT

At a glance

Guides adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns, API wiring, routing registration, Tailwind/i18n rules, and the Vite HMR dev loop.

  • Works in 11 steps: Controls come from the shared primitives… → NEVER use a browser agent for visual… → Don't npm run build during dev. Vite HMR… → …
  • Creating a new studio/panel/view
  • SKILL.md covers When to use this skill, Golden rules (hard constraints), Dev loop (PowerShell, from… and Procedure: adding a new studio, plus 7 more sections
  • Calls npx, npm and git

What it does

UI Feature Dev is an agent skill from scragnog/HOT-Step-CPP. Guides adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns, API wiring, routing registration, Tailwind/i18n rules, and the Vite HMR dev loop. Use when creating a new studio/panel/view, adding UI controls or sliders, wiring UI to a server endpoint, or changing anything under ui/src/. NOT for solver/scheduler/guidance knobs — those are declared by Lua plugins in engine/plugins/ (see the lua-plugin-authoring skill), with zero ui/src/ changes.

Its SKILL.md is about 5.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `reference.md`).

It sits in Frontend & Design, covering CSS and styling and Internationalization. It works with React, Lua, C++ and Vite. The repository describes itself as: Turn dials. Summon bangers! NOW WITH MORE C++! Local AI music generation powered by GGML. The licence is MIT.

When your agent uses it

  • Creating a new studio/panel/view
  • Adding UI controls
  • Wiring UI to a server endpoint
  • Changing anything under ui/src/

Example prompts

  • “studios”
  • “Use the ui-feature-dev skill to guide adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns…”
  • “/ui-feature-dev”

Requirements

  • Node.js

Workflow steps

11 steps, taken from the first numbered list in SKILL.md.

  1. Controls come from the shared primitives — read docs/dev/ui-design.md before adding any. A dropdown is StyledSelect, an on/off setting is…
  2. NEVER use a browser agent for visual verification — ask the human user for screenshots/feedback. The browser agent is too slow/unreliable…
  3. Don't npm run build during dev. Vite HMR means UI edits need no build and no restart. Type-check with npx tsc -b from ui\ (all tsconfigs…
  4. Node 20 to 24 LTS, 24 recommended. ui/package.json enforces "node": ">=20.0.0 <25.0.0".
  5. Registering a new studio requires FIVE edits (four in App.tsx: the import + viewFromUrl + urlForView + the renderContent branch, plus one…
  6. Any new generation parameter MUST be added to getGlobalParams() in ui/src/stores/globalParamsStore.ts (starts line 324) — that function is…
  7. Every string through t() (react-i18next) with a key in ui/src/i18n/locales/en.json; other locales fall back to English. Note: en.json…
  8. Git discipline (repo-wide): all work on master, never git add -A, never git add -f on gitignored paths — stage explicit paths only. Push…
  9. Cross-tier: if your UI feature needs engine (C++) changes, rebuild via dev-rebuild.bat at repo root, NEVER engine/build.cmd directly…
  10. Sideband rule for new generation params: server-side params outside the C++ AceRequest struct never survive the /lm round trip. Synth…
  11. When verifying generation params, never delete generated test audio — the user verifies results by ear. Hand over song IDs/URLs and ask…

What it can do on your machine

Read from SKILL.md and the folder at commit 91e92a8. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx
    • npm
    • git
    • tsc
    • node
    • cmake

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, npm and git, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

UI Feature Dev loads about 5.3k tokens when it runs. Until then it costs about 129 tokens; SKILL.md has 2,300 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~129
When it runs · the whole SKILL.md, loaded when a task matches
~5.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from scragnog/HOT-Step-CPP at commit 91e92a8, republished under its MIT licence (© scragnog). 2,300 words, ~5,276 tokens.

Download SKILL.mdSave it as .claude/skills/ui-feature-dev/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
ui-feature-dev
description
Guides adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns, API wiring, routing registration, Tailwind/i18n rules, and the Vite HMR dev loop. Use when creating a new studio/panel/view, adding UI controls or sliders, wiring UI to a server endpoint, or changing anything under ui/src/. NOT for solver/scheduler/guidance knobs — those are declared by Lua plugins in engine/plugins/ (see the lua-plugin-authoring skill), with zero ui/src/ changes.

UI Feature Development (React Studios)

The UI tier of HOT-Step CPP is a single-page React 19 app in ui/ (Vite 8, Tailwind 3.4, zustand 5, react-i18next, lucide-react icons). Every user-facing feature is a "studio" — a folder of components under ui/src/components/ mounted as a top-level view. There is no react-router: routing is hand-rolled history.pushState in App.tsx. All server calls are plain fetch() against relative /api/... URLs (no axios, no react-query).

Terms used below:

  • DiT — the diffusion transformer, the C++ engine's core music-generation model. The UI only ever references it as a model name string.
  • Studio — one feature area (Lyric Studio, Stem Studio, Cover Studio...), i.e. one folder under ui/src/components/ plus a branch in App.tsx.
  • hs-* — the localStorage key namespace used for persisted UI state.

When to use this skill

  • Adding a new studio/view/panel to the UI.
  • Adding a control (slider, toggle, dropdown) to an existing studio or the global parameter bar.
    • Exception: a knob for a solver/scheduler/guidance mode is NOT a UI task — Lua plugins declare their own UI params (docs/dev/plugins-authoring.md, lua-plugin-authoring skill). Wiring one into getGlobalParams() is the wrong implementation entirely.
  • Wiring the UI to a new or existing server API endpoint.
  • Debugging UI state, routing, persistence, or "my new param does nothing" issues.

Golden rules (hard constraints)

  1. Controls come from the shared primitives — read docs/dev/ui-design.md before adding any. A dropdown is StyledSelect, an on/off setting is Toggle, a parameter label is ParamLabel with info. Never a native <select> or <input type="checkbox">; node tools/docs/check-docs.mjs fails on a new one. WHY: the native widgets look nothing like the app (grey OS box, white text) and a knob with no explanation is a support question.
  2. NEVER use a browser agent for visual verification — ask the human user for screenshots/feedback. The browser agent is too slow/unreliable in this environment. It is acceptable ONLY for non-visual checks (hitting API endpoints). Workflow: make the change → confirm type-check is clean → ask the user "please check X on the /stem-studio page".
  3. Don't npm run build during dev. Vite HMR means UI edits need no build and no restart. Type-check with npx tsc -b from ui\ (all tsconfigs have noEmit: true — nothing is emitted). Only build right before user prod testing. WHY: builds are slow and pointless mid-dev; the dev server already serves source.
  4. Node 20 to 24 LTS, 24 recommended. ui/package.json enforces "node": ">=20.0.0 <25.0.0".
  5. Registering a new studio requires FIVE edits (four in App.tsx: the import + viewFromUrl + urlForView + the renderContent branch, plus one NavItem in Sidebar.tsx — see procedure below). Skipping viewFromUrl()/urlForView() gives a studio that renders but breaks on refresh/back-button.
  6. Any new generation parameter MUST be added to getGlobalParams() in ui/src/stores/globalParamsStore.ts (starts line 324) — that function is the SINGLE assembly point for the request body. A slider not wired there silently does nothing.
  7. Every string through t() (react-i18next) with a key in ui/src/i18n/locales/en.json; other locales fall back to English. Note: en.json nests everything under a top-level "translation" key.
  8. Git discipline (repo-wide): all work on master, never git add -A, never git add -f on gitignored paths — stage explicit paths only. Push only with explicit user approval, commit locally often. Never push a v* tag casually — it triggers a full multi-platform CI release build.
  9. Cross-tier: if your UI feature needs engine (C++) changes, rebuild via dev-rebuild.bat at repo root, NEVER engine/build.cmd directly, under any circumstances (Node auto-respawns ace-server; only dev-rebuild.bat performs the clean shutdown). Never cmake --clean-first (20+ min CUDA recompile).
  10. Sideband rule for new generation params: server-side params outside the C++ AceRequest struct never survive the /lm round trip. Synth requests are rebuilt by spreading the original aceReq and taking ONLY LM-generated fields from the echo (server/src/routes/generate.ts:312-328). Add new sideband params to aceReq before the LM phase; NEVER extend the LM-field pick-list into a copy-across whitelist (bug class fixed in 8ea519b/168dcb5).
  11. When verifying generation params, never delete generated test audio — the user verifies results by ear. Hand over song IDs/URLs and ask the user to listen, just as visual changes get a screenshot request.

Dev loop (PowerShell, from repo root)

powershell
.\dev.bat     # run it detached; the app then lives at http://localhost:3000

This starts BOTH tiers (verified dev.bat): the Node server via server\restart-loop.cmd on :3001 (tsx watch, auto-restart) and npx vite --port 3000 --host in ui\. Develop against **http://localhost:3000** — Vite proxies /api, /audio, and /references to :3001 (ui/vite.config.ts:10-24). LAUNCH.bat is the end-user prod launcher (Node :3001 serving prebuilt ui/dist/, server/src/index.ts:126) — agents never run it.

Checks while developing:

powershell
cd D:\Ace-Step-Latest\hot-step-cpp\ui
npx tsc -b          # type-check UI (project references — catches what a plain tsc --noEmit on one file misses)
npx eslint .        # lint

If you touched server/src/: cd D:\Ace-Step-Latest\hot-step-cpp\server; npx tsc --noEmit.

Only before handing to the user for prod testing: npm run build in ui\ (runs tsc -b && vite build).

Procedure: adding a new studio

Say the studio is "My Studio", slug my-studio.

  1. Create the folder ui/src/components/my-studio/ with an orchestrator MyStudio.tsx (PascalCase files, kebab-case folder). Export both named and default (export const MyStudio: React.FC = ... + export default MyStudio — see StemStudio.tsx:40,503). Layout convention (documented in-source at StemStudio.tsx:9-10): flex columns with border dividers, resizable right sidebar.
  2. Register the route in ui/src/App.tsx — add the import { MyStudio } ... at the top (cf. App.tsx:38), then three places:
    • viewFromUrl() (App.tsx:84-95): if (path.startsWith('/my-studio')) return 'my-studio';
    • urlForView() (App.tsx:98-116): if (view === 'my-studio') return '/my-studio';
    • renderContent() (App.tsx:652 onward): add a branch, wrapped in DiscoPulseWrapper (a beat-reactive visual wrapper) with a hue from the DISCO constants (App.tsx:279-289, e.g. DISCO.assistant = 175 cyan):
      tsx
      if (activeView === 'my-studio') {
        return (
          <DiscoPulseWrapper hue={DISCO.assistant} className="flex-1 overflow-hidden">
            <MyStudio />
          </DiscoPulseWrapper>
        );
      }

    Navigation flows through navigateTo() (App.tsx:391-401) → setActiveView + history.pushState; back/forward is a popstate listener (App.tsx:404-408). Only Lyric Studio persists a deep URL (hs-lastLyricStudioUrl) — copy that only if your studio has sub-routes.

  3. Add a nav item in ui/src/components/sidebar/Sidebar.tsx — copy an existing NavItem block (e.g. Stem Studio at Sidebar.tsx:111-117): icon (lucide-react), label={t('sidebar.myStudio')}, active={activeView === 'my-studio'}, onClick={() => onViewChange('my-studio')}, isExpanded={isOpen}.
  4. If it needs server endpoints: create server/src/routes/myStudio.ts, mount it in server/src/index.ts (app.use('/api/my-studio', ...) — see the mount block at index.ts:72-95), and create a per-studio client ui/src/services/myStudioApi.ts (see API layer below). Keep all endpoints under /api/... or the Vite proxy won't forward them in dev.
  5. Add i18n keys to ui/src/i18n/locales/en.json (under the "translation" root) for every user-visible string.
  6. Type-check, then ask the user to visually verify — never a browser agent.

State management — three coexisting patterns

Top-level docs say "Zustand" but only 2 of 8 files in ui/src/stores/ use zustand's create() (globalParamsStore.ts:9, vstChainStore.ts:6 — verified by grep). The majority pattern is a hand-rolled useSyncExternalStore module singleton. Match the pattern of the nearest existing store; don't introduce a fourth.

Pattern A — hand-rolled external store (majority; canonical example ui/src/stores/abCompareStore.ts, 101 lines). Module-level let _state, a Set of listeners, setState() that spreads + notifies, exported plain action functions (importable from non-React code), plus a useXxx() hook (useSyncExternalStore(subscribe, getSnapshot)) and a ref-cached useXxxSelector(selector) hook. Selector hooks are the preferred subscription style: useAudioGenQueueSelector(s => s.items.filter(...).length) (StemStudio.tsx:77-79). Used by: playbackStore, audioGenQueueStore, discoStore, streamingStore, abCompareStore, components/lyric-studio/playlistStore (studio-local stores may live inside the studio folder).

Pattern B — zustand + per-field localStorage (ui/src/stores/globalParamsStore.ts, 460 lines). create<any>()((set, get) => ({...})) — the any is deliberate (line 39-40). Every field initialises via readKey('hs-<name>', default) and every setter does set({...}); writeKey('hs-<name>', v) — per-key hs-* persistence, NOT zustand/persist middleware. getGlobalParams() (line 324-459, end of file) assembles ~100 knobs into a Partial<GenerationParams> request body with conditional gating — new generation params go here or nowhere. ui/src/context/GlobalParamsContext.tsx is a legacy compat shim; its own header (lines 1-8) says new code must import the store directly. Don't extend the context.

Pattern C — plain useState + localStorage inside the studio. StemStudio persists studio-local state via manual localStorage with hs-stem-* keys (StemStudio.tsx:43-46,97-104) or via usePersistedState(key, default) (ui/src/hooks/usePersistedState.ts:9). Cross-component/same-tab sync requires writePersistedState() (usePersistedState.ts:43-49), which manually dispatches a StorageEvent — native StorageEvents only fire cross-tab.

The generation queue store audioGenQueueStore.ts (992 lines) persists to IndexedDB (lireek-queue-store DB) with debounced 2 s writes because large queues blew localStorage's 5 MB cap (lines 65-73,126-133); on reload it resets in-flight items to pending + "Reconnecting…" (_sanitizeItems, lines 142-156).

Show full SKILL.md (1,024 more words)Show less

API layer — how the UI reaches the server

Two tiers, both in ui/src/services/:

  • Central client api.ts (406 lines): private get/post/patch/del<T> fetch helpers, BASE = '/api', optional Bearer token, uniform errors (non-OK → throw new Error(err.error || 'API error: <status>'), api.ts:10-64). Exports per-domain objects (songApi, generateApi, modelApi, adapterApi, settingsApi, ...).
  • Per-studio client files (model: stemStudioApi.ts, 220 lines): standalone exported async functions, own API_BASE = '/api/stem-studio', own types/constants, and a submit-then-poll helper waitForExtraction(jobId, onProgress, pollMs=1000) (stemStudioApi.ts:190-211). New studios with their own routes follow this shape.

Auth: single-user local app. AuthContext auto-logs-in on mount via authApi.autoLogin() (GET /api/auth/auto); components do const { token } = useAuth() and pass token to api methods. Newer endpoints (stem-studio, vst, settings) skip the token entirely — both styles coexist.

snake_case gotcha: the server returns SQLite snake_case rows. normalizeSong() (api.ts:76-114) maps to camelCase while keeping BOTH spellings (audioUrl and audio_url) and parses generation_params if it arrives as a JSON string. Any new endpoint returning songs must route through it or the player/library break.

Generation job protocol (verified api.ts:148-152, types.ts:266-281, polling loop audioGenQueueStore.ts:534-600):

POST /api/generate            → { jobId, status }
GET  /api/generate/status/:id → GenerationJob { status: 'pending|lm_running|synth_running|saving|succeeded|failed|cancelled',
                                                progress?, stage?, error?,
                                                result?: { audioUrls[], songIds[], masteredAudioUrl?, duration?, ... } }

Poll every 1.5 s. Progress may arrive as 0–1 OR 0–100 — normalise both, as audioGenQueueStore.ts:548-550 does. No websockets. Job status is polled (audioGenQueueStore); SSE exists in three places: logs (hooks/useEventSource.ts → TerminalPanel), model-download progress (components/model-manager/useDownloadStream.ts, its own EventSource), and streaming audio previews during generation (hooks/useStreamGeneration.ts → GET /api/generate/stream/:jobId).

Styling and i18n conventions

  • Tailwind v3 (not v4). ui/tailwind.config.js: darkMode: 'class', custom suno dark palette (#09090b bg / #121214 panel / #18181b card / #27272a hover-border) and brand pink #ec4899; font Inter. ui/src/index.css adds CSS-variable design tokens on top of the @tailwind directives.
  • Dual-theme classes are mandatory — always write light+dark pairs: border-zinc-200 dark:border-white/5, text-zinc-700 dark:text-zinc-300 (see StemStudio.tsx:271,289).
  • Accents: purple (focus:border-purple-500/40, #a78bfa labels) inside studios; brand pink for global CTAs.
  • Mixing Tailwind with a bottom-of-file const styles: Record<string, React.CSSProperties> object for one-off widgets is accepted convention (StemStudio.tsx:419-501) — not tech debt to "fix".
  • Resizable sidebars: hand-rolled mousemove handler, width via usePersistedState('hs-activitySidebarWidth', 320) — this key is shared across studios so sidebar width is consistent app-wide (StemStudio.tsx:76,244-262).
  • Icons: lucide-react everywhere.
  • i18n: const { t } = useTranslation(), namespaced keys per studio (t('stem.recentExtractions')), keys in locales/en.json under the "translation" root; ja/ko/ru/zh fall back to en. Helper scripts ui/add_strings.mjs and ui/generate_translations.mjs exist (purpose inferred from names — unverified, read before running). Some existing placeholders are hard-coded English (StemStudio.tsx:288,295); use t() anyway for new strings.

Key files

PathRole
ui/src/App.tsx (1437 ln)Root: hand-rolled routing (viewFromUrl/urlForView/navigateTo), renderContent(), DISCO hues, player wiring
ui/src/main.tsxEntry: StrictMode > AuthProvider > Suspense > App
ui/src/components/<studio>/One folder per studio; orchestrator component named after the studio
ui/src/components/shared/Section (in ActivitySidebar.tsx — props title, icon, count?, countColor?, defaultOpen?), Slider, EditableSlider, Toast, ConfirmDialog, StemMixer, DiscoPulseWrapper, ...
ui/src/components/sidebar/Sidebar.tsxLeft nav — one NavItem per studio
ui/src/stores/globalParamsStore.tszustand; all generation knobs; getGlobalParams() = sole request assembler (line 324)
ui/src/stores/abCompareStore.tsSmallest canonical hand-rolled store — copy this as a template
ui/src/stores/audioGenQueueStore.tsGeneration queue; IndexedDB persistence; submit/poll loop (line 534)
ui/src/services/api.tsCentral fetch client + normalizeSong() (line 76)
ui/src/services/stemStudioApi.tsModel per-studio API client (submit-then-poll)
ui/src/hooks/usePersistedState.tsPersisted useState + writePersistedState() same-tab sync
ui/src/context/AuthContext.tsxAuto-login, useAuth() → { user, token }
ui/src/context/GlobalParamsContext.tsxLEGACY compat shim — do not extend
ui/src/i18n/locales/en.jsonSource-of-truth strings (root key "translation")
ui/vite.config.tsDev proxy: /api, /audio, /references → :3001
ui/tailwind.config.jssuno palette, brand pink, darkMode: 'class'
server/src/index.tsRoute mounts (lines 72-95), serves ui/dist in prod
server/src/routes/stemStudio.tsModel server route paired with stemStudioApi.ts

Failure signatures

SymptomCause → fix
npm install/dev fails with dep/engine errorsCheck Node 20 to 24 range (ui/package.json engines field) and lockfile consistency.
New studio renders but URL resets to / on refresh, or back-button breaksAdded renderContent() branch but missed viewFromUrl() and/or urlForView() — all three + Sidebar are required.
API 404 in dev but works in prod (or vice versa)Route prefix not proxied — only /api, /audio, /references are in vite.config.ts. Keep endpoints under /api/....
Songs missing audio/cover in one studio onlyEndpoint bypassed normalizeSong() — raw snake_case leaked (api.ts:76-114).
Effects/API calls fire twice in devReact StrictMode double-invoke (main.tsx:9). Dev-only; make mount effects idempotent, don't "fix" with flags.
New slider has no effect on generationsValue not wired into getGlobalParams() (globalParamsStore.ts:324) — the only place the request body is assembled. If it reaches getGlobalParams() but never reaches /synth: the server chain is routes/generate.ts → translateParams() (server/src/services/generation/translateParams.ts:11) → aceReq; sideband params must join aceReq BEFORE the LM phase (Golden rule 9 — never whitelist across the LM echo).
Setting change in one studio doesn't reflect in anotherWrote localStorage directly instead of writePersistedState() — same-tab listeners need the manually-dispatched StorageEvent.
Progress bar jumps 0→100 or shows 5000%Server progress is 0–1 on some paths, 0–100 on others; normalise like audioGenQueueStore.ts:548-550.
Queue items stuck "generating" after reloadExpected behaviour: _sanitizeItems resets to pending+"Reconnecting…" and resumeQueue() re-submits (audioGenQueueStore.ts:142-156,610-621).
UI shows a raw key like stem.queueKey missing from i18n/locales/en.json.
npx tsc --noEmit on a file passes but npm run build failsbuild runs tsc -b across ALL project references — reproduce with npx tsc -b from ui\.
Generation fails and the UI just shows "failed"Debug server-side: newest logs/YYYY-MM-DD_HH-MM-SS/ folder → generations/gen_*.log, then ace_engine.log / node_console.log.

Institutional knowledge

  • VALIDATED (lead engineer, verbatim rule): Never use a browser agent for visual verification — ask the human user for screenshots/feedback. Browser agent is acceptable only for non-visual API checks.
  • VALIDATED: getGlobalParams() is the sole assembly point for generation request bodies; params bypass it → silently dropped. Confirmed by code and by commit 8ea519b ("adapter param plumbing bugs").
  • VALIDATED: the "Zustand" label in top-level docs is aspirational — 5 of the 8 files in ui/src/stores/ are hand-rolled useSyncExternalStore stores (a 6th, playlistStore, lives in components/lyric-studio/); 2 use zustand; playbackConverters.ts is pure helpers, not a store. Match your neighbours.
  • VALIDATED: queue persistence moved localStorage → IndexedDB because 600+-item queues exceeded the 5 MB localStorage cap (comment at audioGenQueueStore.ts:66-68).
  • VALIDATED: GlobalParamsContext.tsx is a migration shim by its own header — extend the store, not the context.
  • UNVERIFIED: exact behaviour of ui/add_strings.mjs / ui/generate_translations.mjs (files exist; purpose inferred from names — read before running).
  • NOTE: ui/README.md is the untouched Vite template — ignore it as documentation.

Deeper reading

  • reference.md (same folder) — full Stem Studio end-to-end dissection, store code templates, DISCO hue table, localStorage key namespaces.
  • CLAUDE.md (repo root) — cross-tier build/git rules.
  • FEATURES.md — feature catalogue.
  • docs/dev/plugins-authoring.md — if your UI feature exposes a new solver/scheduler/guidance knob, that's a Lua plugin, not C++ (plugins declare their own UI params).
  • engine/docs/ARCHITECTURE.md — engine request JSON, generation modes.
  • docs/plans/ — internal design docs. Gitignored, local-only — may be absent on a fresh clone.

© scragnog, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in .claude/skills/ui-feature-dev of scragnog/HOT-Step-CPP.

  • SKILL.md
  • reference.md

Open the folder on GitHubat commit 91e92a8

Compare with similar skills

UI Feature Dev next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

UI Feature Dev compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
UI Feature Dev this skillscragnog/HOT-Step-CPP171—~5.3kAutomated safety check: PassMIT
Frontend UI FunctionalvictorGPT/vibeusage131—~939Automated safety check: PassMIT
Tailwind V4 Shadcnever-works/ever-works1582 repos~3.8kAutomated safety check: PassMIT
Shadcn Tailwind UILiarMTTT/TavernWeave150—~1.7kAutomated safety check: PassCustom licence
Redesign My Landingpageinstructa/agent-skills139—~1.8kAutomated safety check: PassNone
Tailwind V4 Shadcnsecondsky/claude-skills227—~4kAutomated safety check: PassMIT

Similar skills

  • Frontend UI Functional

    victorGPT/vibeusage

    A skill your agent uses when building or refactoring functional React/Vite/Tailwind UI pages, templates, or component libraries that need consistent structure, tokenized styling, accessibility…

    131 GitHub stars~939 tokensUpdated 2 mo ago
    Frontend & DesignAuto-check passed
  • Tailwind V4 Shadcn

    ever-works/ever-works

    Production-tested setup for Tailwind CSS v4 with shadcn/ui, Vite, and React.

    158 GitHub starsUsed in 2 repos~3.8k tokens
    Frontend & DesignAuto-check passed
  • Shadcn Tailwind UI

    LiarMTTT/TavernWeave

    Build, restyle, or review accessible React interfaces that use shadcn/ui, Radix UI primitives, and Tailwind CSS.

    150 GitHub stars~1.7k tokensUpdated 3 days ago
    Frontend & DesignAuto-check passed
  • Redesign My Landingpage

    instructa/agent-skills

    Build, critique, and iterate high-converting marketing or product landing pages using React + Vite + TypeScript + Tailwind and shadcn/ui components, with all icons sourced from Iconify.

    139 GitHub stars~1.8k tokensUpdated 9 days ago
    Frontend & DesignAuto-check passed
  • Tailwind V4 Shadcn

    secondsky/claude-skills

    | Production-tested setup for Tailwind CSS v4 with shadcn/ui, Vite, and React.

    227 GitHub stars~4k tokensUpdated 9 days ago
    Frontend & DesignAuto-check passed
  • Creative Tim UI Blocks

    creativetimofficial/ui

    Helps install, generate and review Creative Tim UI blocks: shadcn/ui-based React and Tailwind sections that follow a restrained, production-minded design philosophy.

    12k GitHub stars~2.1k tokensUpdated 6 mo ago
    Frontend & DesignAuto-check: notes

More from scragnog/HOT-Step-CPP

All 18 skills in this repo
  • Ear Test Scoresheet

    scragnog/HOT-Step-CPP

    The standard way to run a listening test in HOT-Step - a local HTML score sheet next to the renders where Rob plays each track, scores it 1-5 on named criteria, and the page charts the two score…

    171 GitHub stars~1.9k tokensUpdated today
    Auto-check passed
  • Engine Performance

    scragnog/HOT-Step-CPP

    Explains where HOT-Step generation time goes (LM/DiT/VAE), how the TensorRT paths activate, how to benchmark from logs, and which knobs trade quality for speed.

    171 GitHub stars~4.9k tokensUpdated today
    Auto-check passed
  • Mm3 Backend

    scragnog/HOT-Step-CPP

    Maps HOT-Step's native MiniMax-Music3 backend — engine port modules, endpoints, server/UI integration, parity/fixture infrastructure, and the hard-won trap list.

    171 GitHub stars~4.5k tokensUpdated today
    Auto-check passed
  • Mm3 Lm Adapter Training

    scragnog/HOT-Step-CPP

    The validated recipe for training MiniMax-Music3 planner-LM style adapters (artist/album clones) with ace-train mm3-lm-train and the Training Studio.

    171 GitHub stars~4k tokensUpdated today
    Auto-check passed
  • Release Process

    scragnog/HOT-Step-CPP

    Runbook for cutting and publishing a HOT-Step CPP release via a v git tag that triggers the multi-platform CI build and drafts a GitHub Release.

    171 GitHub stars~5.1k tokensUpdated today
    Auto-check passed
  • Upstream Sync

    scragnog/HOT-Step-CPP

    Safely pulls upstream acestep.cpp changes into the HOT-Step engine fork without destroying its integration hooks.

    171 GitHub stars~5k tokensUpdated today
    Auto-check passed

Questions about UI Feature Dev

What does UI Feature Dev do?

Guides adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns, API wiring, routing registration, Tailwind/i18n rules, and the Vite HMR dev loop. UI Feature Dev is an agent skill from scragnog/HOT-Step-CPP. Guides adding or modifying UI features (React "studios") in HOT-Step CPP — studio-folder convention, store patterns, API wiring, routing registration, Tailwind/i18n rules, and the Vite HMR dev loop.

When should I use UI Feature Dev?

UI Feature Dev fits situations like: creating a new studio/panel/view; adding UI controls; wiring UI to a server endpoint; changing anything under ui/src/.

How do I install UI Feature Dev in Claude Code?

Run `npx skills add scragnog/HOT-Step-CPP --skill ui-feature-dev -a claude-code`. Or copy the skill folder (.claude/skills/ui-feature-dev in scragnog/HOT-Step-CPP) into .claude/skills/ui-feature-dev in your project. Claude Code loads it when a task matches its description.

How do I install UI Feature Dev in Codex?

Run `npx skills add scragnog/HOT-Step-CPP --skill ui-feature-dev -a codex`. Or copy the skill folder (.claude/skills/ui-feature-dev in scragnog/HOT-Step-CPP) into .agents/skills/ui-feature-dev in your project. Codex loads it when a task matches its description.

Can I use UI Feature Dev in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add scragnog/HOT-Step-CPP --skill ui-feature-dev -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ui-feature-dev, .gemini/skills/ui-feature-dev, .github/skills/ui-feature-dev and .opencode/skills/ui-feature-dev in your project.

What does UI Feature Dev need to run?

Going by SKILL.md and its folder, UI Feature Dev needs the command-line tools its instructions call (npx, npm, git, tsc, node and cmake). Our summary lists: Node.js.

Does UI Feature Dev access the network?

SKILL.md contains no URLs. Its commands use npx, npm and git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is UI Feature Dev safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does UI Feature Dev use?

UI Feature Dev is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does UI Feature Dev use?

About 5.3k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to UI Feature Dev?

Skills that share tags, products or a category with UI Feature Dev: Frontend UI Functional (victorGPT/vibeusage, 131 stars), Tailwind V4 Shadcn (ever-works/ever-works, 158 stars), Shadcn Tailwind UI (LiarMTTT/TavernWeave, 150 stars) and Redesign My Landingpage (instructa/agent-skills, 139 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains UI Feature Dev?

scragnog (a GitHub user) maintains it in scragnog/HOT-Step-CPP, which has 171 GitHub stars. The repository holds 18 skills in this directory. The repository was last updated on October 7, 2026.

Source: scragnog/HOT-Step-CPP on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.