# webavatar-core Base SvelteKit project meant to be branched off for future webavatar client projects. It provides reusable core infrastructure — session management, auth tokens, realtime model connections — so client projects don't reimplement the basics from scratch. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full picture; `docs/` holds per-subsystem deep-dives beyond that. ## Project structure - `src/lib/core/` — shared client+server contracts (types, protocols). No SvelteKit-specific imports (`$env`, `$app`, etc.) — must stay portable. - `src/lib/server/core/` — server-only implementation. SvelteKit enforces this boundary at build time; browser code cannot import from here, even transitively. - `src/lib/client/core/` — thin browser-side wrappers around the shared contracts. Transport only, no business logic. - `src/lib/project/`, `src/lib/server/project/`, `src/lib/client/project/` — mirrors the three directories above, but for code specific to whichever client project branches from this template (tool implementations, custom instructions, etc.), instead of reusable template infrastructure. **Core never imports from project, only the reverse** — see [docs/TOOLS.md](docs/TOOLS.md) for the concrete example this convention was introduced for. - `src/lib/humanoid/`, `src/lib/client/humanoid/` — an **optional package** (not `core`, not `project`; see "Module layering" in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)) providing avatar-state derivation and animation-channel composition for 3D humanoid avatars. Nothing in `core`/`project` imports from it — a project only pulls it in if it's building a humanoid avatar. See [docs/HUMANOID.md](docs/HUMANOID.md). - `src/routes/` — thin route glue; delegates into the above rather than holding logic itself. - `docs/` — architecture and subsystem documentation (see "Documentation" below). ## Development - `npm run dev` / `npm run build` / `npm run preview` — standard SvelteKit commands. `build` also compiles `src/lib/core/**` + `src/lib/server/core/**` standalone (`tsc -p tsconfig.server.json`) for production's custom `server.js` to import — see [docs/REALTIME_SESSION.md](docs/REALTIME_SESSION.md) for why that's needed. - `npm run check` — type-check (`svelte-check`). `npm run lint` / `npm run format` — prettier + eslint. `npm run test:unit` — vitest. - Copy `.env.example` to `.env` and fill in `OPENAI_API_KEY` / `REALTIME_TOKEN_SECRET` before running anything that touches the realtime session layer. - **Gotcha**: `src/lib/server/core/**` is only loaded via `vite.config.ts`'s plugin list, not through the app's normal module graph — so it's **not** part of Vite's HMR. Restart `npm run dev` after editing anything there; a hot-reload will silently keep running the old code, which reads as a mysterious bug if you don't know this. ## Documentation This project is documented for both humans and agents, and keeping it that way is part of the development process, not a follow-up task: - **Architecture and subsystem docs live in `docs/`.** [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) is the high-level map, with a table linking to per-subsystem deep-dives (e.g. [`docs/REALTIME_SESSION.md`](docs/REALTIME_SESSION.md)). When you build a new subsystem, or make a decision that isn't obvious from reading the code (a tradeoff, a "we chose X over Y because Z", a constraint that shapes how client projects can deploy or extend this), add or update the relevant doc under `docs/` and link it from `docs/ARCHITECTURE.md`'s table — as part of the same change, not a separate pass later. - **This file stays focused on orientation, conventions, and process — not deep architecture.** If you're about to write a paragraph explaining _why_ something is built a certain way, that belongs in a `docs/` file; link to it from here instead of inlining it. - **Write down what was hard to find out, not what's easy to re-derive.** Decision rationale and gotchas discovered the hard way (like the OpenAI event-naming mismatch documented in `docs/REALTIME_SESSION.md`, only found by testing live) are worth the words. Code structure, file layout, or anything obvious from reading the source usually isn't — don't document what the code already says clearly. ## Verifying changes Type-checking and unit tests don't prove a feature actually works, especially anything touching an external API's wire protocol — assumptions baked into the implementation end up baked into tests of that implementation too, so they can pass while the feature is genuinely broken. For UI changes, use the feature in a real browser before calling it done. For the realtime session layer specifically, that means an actual round trip against OpenAI via `/demo/realtime`, not just `npm run check` passing — see "Verifying changes" in [docs/REALTIME_SESSION.md](docs/REALTIME_SESSION.md). ## Svelte MCP server You have access to the Svelte MCP server, with comprehensive Svelte 5 and SvelteKit documentation. Use the available tools as follows: ### 1. list-sections Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths. When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections. ### 2. get-documentation Retrieves full documentation content for specific sections. Accepts single or multiple sections. After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task. ### 3. svelte-autofixer Analyzes Svelte code and returns issues and suggestions. You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned. ### 4. playground-link Generates a Svelte Playground link with the provided code. After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project.