Imported from ivan-palatov/sound-generator (
AGENTS.md). Install upstream withnpx skills add ivan-palatov/sound-generator. Copyright stays with the author.
Agent instructions
Guidance for AI coding agents working in this repository.
Project summary
pnpm monorepo with two packages:
frontend/— React 19, TypeScript, Vite 8, TanStack Router, i18next. User-facing UI.backend/— Deno HTTP server. Proxies to MiniMax APIs, validates requests, persists history to JSON.
Do not add a third package or change the runtime (no Node backend, no Next.js) unless explicitly requested.
Commands
pnpm install # from repo root
pnpm dev # frontend + backend
pnpm dev:frontend # Vite only
pnpm dev:backend # Deno only (needs .env with MINIMAX_API_KEY)
pnpm build # frontend production build
pnpm lint # oxlint on frontend
pnpm format # oxfmt on frontend
Backend has no separate lint/format scripts; follow existing Deno/TS style in backend/.
Conventions
Scope and style
- Make minimal, focused diffs. Match surrounding code style.
- Do not add comments unless they explain non-obvious logic.
- Do not add tests unless requested or they cover meaningful behavior.
- Do not commit
.env,backend/data/history.json, ornode_modules/.
Frontend (frontend/src/)
- Routing — File-based routes under
routes/. Route tree is generated (routeTree.gen.ts); do not hand-edit it. - API calls — All HTTP logic lives in
api/client.ts. Components call these functions, not rawfetchelsewhere. - Errors — Backend returns
errorCode+ optionalerrorParams. Map codes to user strings inlib/translateError.tsand add keys to bothlocales/en/translation.jsonandlocales/ru/translation.json. - Types — Shared domain types in
types.ts. Keep in sync withbackend/types.tswhen changing request/response shapes. - i18n — User-visible strings go through
useTranslation()/t(). Never hardcode UI copy in components. - Lint/format — oxlint + oxfmt. Run
pnpm lintandpnpm formatafter frontend edits.
Backend (backend/)
- Entry point —
main.tsdefines routes and handlers. Business logic is split acrossminimax.ts,minimax-tts.ts,minimax-metadata.ts,*-parse.ts,history.ts,errors.ts. - Validation — Request parsing/validation in
cover-parse.tsandtts-parse.ts(multipart + JSON). Song validation inminimax.ts(validateSongRequest). - Errors — Throw
ApiErrorwith a typed code fromerrors.ts. Handlers returnapiErrorResponse()with appropriate HTTP status (400 for client errors, 422 for upstream/generation failures). - History — Every generation attempt creates a
HistoryEntry(including failures). Stored inbackend/data/history.json. - Env — Loaded via
--env-file=../.envindeno.jsontasks. Secrets only in.env, never in source.
API contract
- Frontend talks to
/api/*(proxied tolocalhost:8000in dev). - Generation endpoints return
{ entry }on success or{ entry, errorCode, errorParams }with status 422 when generation fails but history was saved. - Cover/TTS uploads use
multipart/form-datawith fieldaudio; JSON body is used when onlyaudioUrlis provided.
Common tasks
| Task | Where to change |
|---|---|
| New UI string | locales/en/translation.json, locales/ru/translation.json |
| New API error code | backend/errors.ts, handler status map in main.ts, frontend/lib/translateError.ts, locale files |
| New route/page | frontend/src/routes/, shared components in components/ |
| New model | backend/types.ts, frontend/src/types.ts, model selectors, validation in backend |
| New API endpoint | backend/main.ts handler + frontend/src/api/client.ts |
Pitfalls
- Duplicate types —
frontend/src/types.tsandbackend/types.tsmirror each other. Update both when changing shared shapes. - Wrong endpoint for model — Cover models must use
/api/cover/*, TTS models/api/tts/generate, song models/api/generate. - Generation vs validation errors — Validation fails before history is written (400). MiniMax/upstream failures still append a failed entry (422).
- Do not edit
frontend/src/routeTree.gen.ts— it is codegen output from TanStack Router plugin.
Further reading
See CONTEXT.md for architecture, endpoint reference, and workflow details.