# webavatar-core An npm-workspaces monorepo providing reusable core infrastructure — session management, auth tokens, realtime model connections — for future webavatar client projects, plus a SvelteKit template to branch those projects from. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the full picture; `docs/` holds per-subsystem deep-dives beyond that. ## Project structure - `packages/core/` — `@webavatar/webavatar-core`, published-package infrastructure every client project needs: session management, auth tokens, the realtime provider adapters, and the Vite dev-server integration. Curated entry points (`.`, `./client`, `./server`, `./vite`) — see the package's own README for what each exports. No SvelteKit-specific imports (`$env`, `$app`, etc.) and no dependency on `apps/template` — it's a portable package, not app code. - `packages/humanoid/` — `@webavatar/webavatar-humanoid`, an **optional package** (not every client project needs it) providing avatar-state derivation and animation-channel composition for 3D humanoid avatars. Depends on core's public contracts only as types (`import type`), never at runtime — its built JavaScript contains no reference to core at all. See [docs/HUMANOID.md](docs/HUMANOID.md) and the package's own README. - `apps/template/` — the SvelteKit application template client projects branch from: routes, project-owned persona/tools, deployment configuration (`server.js`, `vite.config.ts`), and the demo pages. This is what a client project copies out and installs the packages into — see its README's "Starting a client project" procedure. Within it: - `src/lib/project/`, `src/lib/server/project/`, `src/lib/client/project/` — code specific to whichever client project branches from the template (tool implementations, custom instructions, etc.). **Neither package imports from project code, only the reverse** — see [docs/TOOLS.md](docs/TOOLS.md) for the concrete example this convention was introduced for. - `src/lib/server/webavatar-core.ts` — the server-only wrapper (`export * from '@webavatar/webavatar-core/server'`) that SvelteKit routes and server modules import through, so SvelteKit's own `$lib/server` build-time guard covers them; `server.js` and `vite.config.ts` are the only two files allowed to import the package's `/server` and `/vite` entries directly. - `src/routes/` — thin route glue; delegates into the packages and project code rather than holding logic itself. - `src/routes/demo/` — verification scaffolding (the live smoke-test surface referenced under "Verifying changes" below), not a client project's own UI. Gated to dev-only (404s in production) so a branched project never needs to delete it to keep it out of a shipped build. - `docs/` — architecture and subsystem documentation (see "Documentation" below), at the repo root and shared across both packages and the template. ## Development - `npm run dev` / `npm run build` / `npm run preview` — standard SvelteKit commands, run from `apps/template` (or via `--workspace apps/template` from the root). `build` also compiles `src/lib/project/**` + `src/lib/server/project/**` standalone (`tsc -p tsconfig.server.json`) for production's custom `server.js` to import. - `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 (verified live)**: `apps/template`'s own `npm run dev` alone does **not** hot-reload `@webavatar/webavatar-core`/`@webavatar/webavatar-humanoid` source changes — those packages resolve through their built `dist/`, and nothing recompiles it unless the package's own `tsc --watch` is also running. Use the root `npm run dev` (builds once, then watches both packages alongside `apps/template`'s dev server) for working hot reload. Separately, the realtime WS relay's dev-mode plugin wiring (`@webavatar/webavatar-core/vite`) loads once at dev-server startup and is never hot-reloaded regardless — a full restart is required after editing it. See [docs/REALTIME_SESSION.md](docs/REALTIME_SESSION.md)'s "Dev-mode reload behavior" for the full picture. ## 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.