# CLAUDE.md — HOT-Step CPP Orientation map for agents. Keep this short and navigational — point at the deep docs, don't duplicate them. ## What this is A desktop app for **local AI music generation** — a heavily-extended superset of [acestep.cpp](https://github.com/ServeurpersoCom/acestep.cpp) (a C++/GGML port of ACE-Step 1.5). Caption + lyrics in → stereo 48 kHz audio out, fully local. Ships as portable releases (Windows CUDA/Vulkan/CPU, Linux, macOS Metal). GitHub: `scragnog/HOT-Step-CPP`. ## Architecture (3 tiers) | Tier | Stack | Location | Role | |------|-------|----------|------| | **Engine** | C++17 / CUDA / GGML | [engine/](engine/) | Inference binaries: `ace-lm`, `ace-synth`, `ace-server`, `ace-understand`, `neural-codec`, `mp3-codec`, `quantize`. Pipeline: LM → DiT → VAE | | **Server** | Node / TypeScript / Express / better-sqlite3 | [server/src/](server/src/) | Orchestrates the engine, manages songs/jobs/SQLite, serves UI. Per-feature [routes/](server/src/routes/) + [services/](server/src/services/) | | **UI** | React 19 / Vite / Zustand / Tailwind | [ui/src/](ui/src/) | Browser frontend. Component folder per "studio" | ``` LAUNCH.bat → Node server (Express :3001) ├── serves React frontend (prebuilt ui/dist/) ├── /api/* → SQLite └── spawns child: ace-server.exe (C++ engine) on :8085 ``` | Service | Port | |---------|------| | Node server | 3001 (prod) | | Vite dev server | 3000 (dev, HMR) | | ace-server (C++ engine) | 8085 (default, `config.ts`) | ## Environment - **Windows 11 + PowerShell.** This repo's primary dev environment is Windows. The Claude Code harness also gives you a Bash (POSIX) tool — each takes its own syntax. In PowerShell use `;` not `&&`. - **Node 18–22 LTS only.** Node 24+ breaks dependencies (`engines` field enforces `<24`). ## Build & run rules (IMPORTANT — learned the hard way) - **C++ engine changes → `dev-rebuild.bat`, NEVER `engine/build.cmd` directly.** The Node server auto-respawns ace-server on crash; killing it without clean shutdown causes an infinite respawn + file-lock loop. `dev-rebuild.bat` handles clean shutdown + rebuild — it does **not** relaunch; start the app again yourself with `dev.bat`/`LAUNCH.bat`. - Recompile **immediately** after editing any `engine/src/` or `engine/tools/` file — don't wait to be asked. - **NEVER `cmake --build . --clean-first`** unless the GGML/CUDA layer itself changed — CUDA kernel recompilation is **20+ min**. For stale `.obj` issues, delete only `engine/build/acestep-core.dir/` and `engine/build/Release/acestep-core.lib`. - **Don't `npm run build` during dev.** Type-check with `npx tsc --noEmit`. Only build before user testing. - **`dev.bat`** = dev mode (Vite :3000 HMR + Node :3001, tsx watch auto-restart). **`LAUNCH.bat`** = prod. Use `dev.bat` for development. ## Git rules - **All work on `master`. No feature branches, ever.** - **Never `git add -A`** (re-adds gitignored dirs: `.agents/`, `checkpoints/`, `node_modules/`, etc.). **Never `git add -f`** on gitignored paths. Stage explicit paths. - **Push requires explicit user approval — always ask first.** - Commit to local git **often** (data has been lost before to uncommitted files). - **Releases:** push a `vX.Y.Z` tag → the `Release` workflow builds all platforms and drafts a GitHub Release. **Any pushed `v*` tag triggers a build** — use a `-CI-Test` suffix for throwaway compile checks, and don't push local feature tags matching `v*`. Full process + gotchas: [docs/RELEASING.md](docs/RELEASING.md). - Use `gh` CLI for GitHub ops (authenticated as `scragnog`). ## Upstream sync (fork hooks that break silently) The C++ engine is a patched fork of acestep.cpp. Three upstream files carry HOT-Step `#include` hooks that break if overwritten during a sync: | Upstream file | Hook | If lost | |---|---|---| | `pipeline-synth-ops.cpp` | `hot-step-sampler.h` (replaces `dit-sampler.h`) | **SILENT** — compiles, but all solvers/guidance/schedulers go dead | | `model-store.h` | `hot-step-params.h` | compile error | | `dit.h` | `adapter-merge.h` + `adapter-runtime.h` | compile error | After any sync: run `engine/verify-hooks.ps1`. Full process: `docs/plans/upstream-sync-workflow.md` *(local, gitignored)*. ## UI / browser verification - **Don't use the built-in browser agent to visually verify UI** — too slow/unreliable here. **Ask the user to check**; they provide screenshots/feedback. Browser agent is fine for non-visual tasks (hitting API endpoints). ## Debugging — logs App writes per-session logs to `logs/` at repo root: ``` logs/YYYY-MM-DD_HH-MM-SS/ ← one folder per session (name-sorted = time-sorted) ├── ace_engine.log ← C++ engine output ├── node_console.log ← Node server output └── generations/gen__.log ``` Start with the newest session folder. Generation failures → matching `gen_*.log` first, then cross-ref `ace_engine.log` + `node_console.log`. Startup/crash → `node_console.log` + `ace_engine.log`. ## Plugin system Solvers (17), schedulers (9), guidance modes, and postprocess are **hot-loadable Lua plugins** in [engine/plugins/](engine/plugins/) — drop a `.lua` in the right subdir, appears in the UI next launch, no C++ rebuild. Each plugin can declare its own UI params. Native C++ bridge via `apg()`; advanced plugins use `post_step()` for extra forward passes. **Adding a solver/scheduler/guidance = write a `.lua` plugin** (the old approach of editing `dit-sampler.h` is obsolete — the engine now routes through `hot-step-sampler.h`). Authoring guide: [docs/PLUGINS.md](docs/PLUGINS.md). ## Read-Y-for-X index | For… | Read | |------|------| | **Any maintenance task — start here** (per-domain procedures, gotchas, distilled institutional knowledge) | [.claude/skills/README.md](.claude/skills/README.md) — 13 fact-checked skills | | Full feature catalogue (100+) | [FEATURES.md](FEATURES.md) | | Engine internals, CLI, request JSON, generation modes | [engine/docs/ARCHITECTURE.md](engine/docs/ARCHITECTURE.md) | | **Training system** (dataset→preprocess→LM/DiT training→audition; ace-train, FSQ, ggml training gotchas) | [docs/TRAINING.md](docs/TRAINING.md) | | Writing a Lua plugin | [docs/PLUGINS.md](docs/PLUGINS.md) | | Build / install / releases | [README.md](README.md) | | Cutting & publishing a release (agent runbook) | [docs/RELEASING.md](docs/RELEASING.md) | | Internal design/investigation docs (perf, adapters, upstream sync, feature designs) | `docs/plans/` *(gitignored, local-only)* | | In-app assistant behaviour/KB | [server/src/data/assistant-knowledge.md](server/src/data/assistant-knowledge.md) | > **Doc convention:** committed contributor-facing docs = `README.md`, `FEATURES.md`, `docs/PLUGINS.md`, `engine/docs/ARCHITECTURE.md`. Internal planning/investigation docs live in `docs/plans/`, which is **gitignored** (local only). This file (`CLAUDE.md`) is committed.