add-ecosystem
Add a new ecosystem and base model to basemodel.constants.ts. Use when onboarding a new model…
Scaffold a new app in apps/<name> wired to the shared @civitai/* packages. Cherry-picks only the packages the app imports and wires each one's dependency, bundler transpile entry, env vars, and a server shim. Use when creating a new monorepo app or *.civitai.com spoke (SvelteKit
$ npx -y skills add civitai/civitai --skill scaffold-civitai-app --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/scaffold-civitai-appContext preview
The summary Claude sees to decide when to auto-load this skill.
Scaffold a new app in apps/<name> wired to the shared @civitai/* packages. Cherry-picks only the packages the app imports and wires each one's dependency, bundler transpile entry, env vars, and a server shim. Use when creating a new monorepo app or *.civitai.com spoke (SvelteKit
name: scaffold-civitai-app description: Scaffold a new app in apps/<name> wired to the shared @civitai/* packages. Cherry-picks only the packages the app imports and wires each one's dependency, bundler transpile entry, env vars, and a server shim. Use when creating a new monorepo app or *.civitai.com spoke (SvelteKit by default; Next.js supported). Defers to docs/packages/new-app-integration.md and each package README as the source of truth.
Stands up a new `apps/<name>` on the shared `@civitai/*` packages, adding **only** the packages the app actually needs. Each app cherry-picks; there is no base bundle.
**Source of truth** (read these, don't restate them from memory — they may have changed):
A new monorepo app: a moderator/admin tool, a `*.civitai.com` spoke, an internal dashboard. Not for adding a feature to an existing app.
Ask only what can't be inferred:
old Next shape.
confirm. Default for a gated data app: `@civitai/auth`, `@civitai/db`, `@civitai/db-schema`, `@civitai/brand`.
authenticated-but-unauthorized user (403, or redirect to `https://civitai.com`).
Copy the shape of `apps/moderator` — read those files and adapt names. Base files (no packages yet): `package.json` (`"type": "module"`, vite/svelte-kit scripts), `svelte.config.js` (adapter-node), `vite.config.ts` (process.env shim + empty `ssr.noExternal` to fill in §3), `tsconfig.json`, `postcss.config.cjs` (`module.exports = {}`), `.gitignore`, `src/app.html`, `src/app.d.ts`, `src/global.css`, `src/routes/+layout.svelte`, a landing `+page.svelte`.
Key bootstrap rules (full detail in the integration guide §3–4):
`transpilePackages`), **plus workspace peers** (`@civitai/db` ⇒ also `@civitai/db-schema`).
the packages read `process.env` directly and SvelteKit doesn't populate it.
For each package the user picked, apply its row: add the **dep(s)**, add to the **transpile list**, add the **env vars** (to both `.env` and `.env.example`), and create the **shim** under `src/lib/server/`.
| Package | Deps to add | Transpile list adds | Env (→ .env & .env.example) | Shim | |---|---|---|---|---| | `@civitai/auth` | `@civitai/auth` | `@civitai/auth` | `AUTH_JWT_ISSUER`, `AUTH_JWKS_URI`, `AUTH_INTERNAL_TOKEN` | `lib/server/auth.ts` (`createSpokeGuard`) + `hooks.server.ts` | | `@civitai/db` (Kysely) | `@civitai/db`, `@civitai/db-schema` | both | *(none — explicit conn strings)* `DATABASE_URL`, `DATABASE_REPLICA_URL` | `lib/server/db.ts` (`createKyselyClients`) | | `@civitai/db` (Prisma) | `@civitai/db`, `@civitai/db-schema` | both | `DATABASE_URL`, `DATABASE_REPLICA_URL`, `NOTIFICATION_DB_URL`, `NOTIFICATION_DB_REPLICA_URL` | `lib/server/db.ts` (`createPrismaClients`) | | `@civitai/redis` | `@civitai/redis` | `@civitai/redis` | `REDIS_URL` **and** `REDIS_SYS_URL` (both!) | `lib/server/redis.ts` (`createRedisClients`) | | `@civitai/clickhouse` | `@civitai/clickhouse` | `@civitai/clickhouse` | `CLICKHOUSE_HOST`, `CLICKHOUSE_USERNAME`, `CLICKHOUSE_PASSWORD` | `lib/server/clickhouse.ts` (`createClickhouseClient`) | | `@civitai/email` | `@civitai/email` | `@civitai/email` | `EMAIL_HOST`, `EMAIL_PORT`, `EMAIL_USER`, `EMAIL_PASS`, `EMAIL_FROM` (all optional) | `lib/server/email.ts` (re-export `sendEmail`) | | `@civitai/axiom` | `@civitai/axiom` | `@civitai/axiom` | `AXIOM_TOKEN`, `AXIOM_ORG_ID`, `AXIOM_DATASTREAM` (all optional) | `lib/server/logger.ts` (`createAxiomLogger`) | | `@civitai/telemetry` | `@civitai/telemetry` | `@civitai/telemetry` | *(none)* | `lib/server/metrics.ts` + a `/metrics` route | | `@civitai/brand` | `@civitai/brand` | `@civitai/brand` | *(none)* | `routes/favicon.svg/+server.ts` (`buildFaviconSvg`) | | `@civitai/db-schema` | *(peer of db; rarely alone)* | `@civitai/db-schema` | *(none)* | import `DB` / enums directly |
Shim snippets live in the package READMEs and the integration guide — read and adapt, don't invent.
Do **not** add transitive deps (`pg`, `kysely`, `jose`) — they resolve through the workspace packages. Add them only if the app imports them directly (e.g. `import { sql } from 'kysely'`).
`REDIS_SYS_URL` makes `loadRedisEnv` throw — caught as fail-open, so the cache is *silently* lost.
`@civitai/db` Prisma entry requires the full 4-var DB env set.
`@civitai/redis` into an auth-only app if you want real-time revocation (`isRevoke
Repo: civitai/civitai
Add a new ecosystem and base model to basemodel.constants.ts. Use when onboarding a new model…
Wire an existing ecosystem into the generation system. Adds generation support to…
Author a prompt-enhancement system prompt for a new ecosystem and register/update it on the…
Add a new trainable base model to BOTH trainers end-to-end — the in-app trainer (main Next.js…
Wire an existing ecosystem into the LoRA training system so it appears as a trainable base…
Deterministically drive a first-party Civitai App Block in the operator's browser and produce…