docs/book/src/developing/web.md
The web dashboard at web/ is a Vite + React + TypeScript app. Its TypeScript API client is generated from the gateway's runtime OpenAPI spec, not hand-written.
cargo web build # production bundle into web/dist/
cargo web dev # vite dev server with HMR
cargo web check # typecheck only (gen-api + tsc -b)
cargo web gen-api # regenerate web/src/lib/api-generated.ts
cargo web install # npm install in web/
cargo web is an alias for cargo run -p xtask --bin web -- (defined in the cargo config). Every subcommand auto-runs npm install if web/node_modules/ is missing.
| Path | Generator | Tracked? |
|---|---|---|
web/src/lib/api-generated.ts | cargo web gen-api | gitignored |
target/openapi.json | cargo web gen-api | gitignored |
web/dist/ | cargo web build | gitignored |
cargo web gen-api renders the OpenAPI spec in-process from zeroclaw_gateway::openapi::build_spec(), writes it to target/openapi.json, and feeds that file to openapi-typescript. The same build_spec() serves /api/openapi.json at runtime, so build_spec() is the single contract source and the generated files are rebuilt on demand.
crates/zeroclaw-gateway/.cargo web check: gen-api regenerates api-generated.ts from the new spec, then tsc -b typechecks the dashboard against it. Any consumer that relies on a now-removed field fails to compile.web/src/ to match.cargo web build for the final bundle.CI does not run cargo web build: the lint/build/test jobs use a web/dist/.gitkeep placeholder so the gateway crate compiles without the bundle. Producing a release artifact that includes the dashboard is a separate step:
cargo web build
cargo build --release --features gateway
The gateway loads web/dist/ from the filesystem at runtime via static_files.rs, so the Rust compile and the web build are decoupled. Ship the populated web/dist/ alongside the binary for installs that should serve the dashboard.
| Tool | Install |
|---|---|
npm | https://nodejs.org/ or nvm install && nvm use from the repo root |
cargo | https://rustup.rs |
The repo root .nvmrc pins the Node major version used by release web builds.
Use it for local dashboard work so npm install, cargo web check, and
manual release builds all run against the same Node line.
cargo web fails fast with an install hint if npm is missing.
The dashboard targets evergreen browsers with support for both color-mix()
and structuredClone().