Splits the SvelteKit app into three workspaces per docs/MONOREPO_MIGRATION_BRIEF.md:
- packages/core (@webavatar/webavatar-core): session management, auth tokens,
provider adapters, and the WS relay, with curated entry points (., ./client,
./server, ./vite) and a browser-stub guard on the server-only ones.
- packages/humanoid (@webavatar/webavatar-humanoid): avatar-state derivation
and animation-channel composition, depending on core only via type-only
imports (no runtime reference to core in its built output).
- apps/template: the SvelteKit application template, now importing both
packages by name, routed through a server-only wrapper and a build-time
guard (server-only-guard.ts) for the server/vite entries.
Also collapses the duplicated server.js/vite-plugin composition wiring into a
single createRealtimeRuntime factory (exported from packages/core/server),
adds ESLint boundary-enforcement rules and Gitea Actions workflows
(verify.yml, publish.yml), externalizes both packages in the production SSR
build for artifact parity with a real client install, and rewrites the
project documentation to match.
No runtime behavior or wire protocol changes. Registry publication stays
blocked on Gitea host/org placeholders not yet resolved — see the brief's
status banner for exactly what remains.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Extends the realtime session protocol with tool.call/tool.result/response.trigger
so the model can invoke functions that run either on our server or, relayed
through the session, in the browser (e.g. DOM interaction) — a single
outstanding-call counter lets a turn mix both without racing the model's
continuation. createToolRegistry enforces at startup that a client-only tool
can never accidentally be backed by server logic.
Also introduces a project/ namespace alongside core/, server/core/, and
client/core/, for code specific to whichever client project branches from
this template. Core never imports project; the two composition roots
(server.js, vite.config.ts) do the merge instead, so template updates can
still be pulled into a branched project without touching core files.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Provider-agnostic session layer for the base project: a shared client/server
wire protocol, a RealtimeProvider adapter interface, and an OpenAI Realtime
implementation of it, wired through a WebSocket relay (browser <-> our
SvelteKit server <-> OpenAI) so the API key never reaches the browser and
future providers/pipelines can be added without touching client code.
Switches the adapter to adapter-node and adds a custom server.js + dev-mode
Vite plugin, since SvelteKit has no native WebSocket support yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>