# `@suaveplan/api-openapi-ui-scalar` — Scalar UI adapter for the `/docs` endpoint **Package**: `@suaveplan/api-openapi-ui-scalar` **Status**: PROPOSED **Type**: new-package **Stage**: 8 — see umbrella `openspec/changes/api-plugin-foundation/` ## Why Per design doc §7 the default `/docs` UI is Scalar — modern, fast, low-bundle, supports OpenAPI 3.1 natively. Wrapping it in its own package keeps the surface clean: operators that prefer Swagger or ReDoc swap the package, not the host config logic. ## What changes - ADDED: `createScalarUiHandler({ openapiUrl, theme, title })` — returns an HTTP handler that serves the Scalar HTML shell pointing at the host's `/openapi.json` URL. Configurable theme / title / default-open-section / search. - ADDED: Per-plugin variant `createPerPluginScalarUiHandler({ openapiUrlForPlugin, plugin })` — used by the host to mount `/docs/{plugin}`. - ADDED: `ScalarUiOptions` Zod schema — validates host config when this UI is selected as `host.openapi.ui = "scalar"`. - ADDED: A static-asset strategy — Scalar's runtime bundle is shipped CDN-or-bundled per `host.openapi.uiAssets` (`"cdn" | "bundled"`); bundled mode embeds the asset under `dist/assets/` for air-gapped hosts. - ADDED: Error codes (`OPENAPI_UI_SCALAR_*`): `ASSETS_MISSING`, `INVALID_OPTIONS`. ## Out of scope - Modifying Scalar itself — this is a thin shell. - Authoring OpenAPI documents — that's `api-openapi`. - Swagger or ReDoc — sibling packages. ## Source mapping Genesis-original. Source of design intent: `docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`. | Requirement | Design doc section | |---|---| | Default `/docs` UI is Scalar | §7 | | Pluggable UI (`api-openapi-ui-{scalar,swagger,redoc}`) | §7 | ## Verification approach - `src/handler/handler.test.ts` — handler returns HTML with the right Scalar bootstrap config; `openapiUrl` is embedded; CSP-friendly nonce supported. - `src/per-plugin/per-plugin.test.ts` — per-plugin variant points at `/openapi.json?plugin=` (or the host-configured filter URL). - `src/assets/assets.test.ts` — `"cdn"` vs `"bundled"` modes resolve the right asset URL; missing bundled asset raises `OPENAPI_UI_SCALAR_ASSETS_MISSING`. - `tests/dep-graph.test.ts` — runtime deps include `api-types`, `error`, `zod`, the Scalar runtime. ## Migration impact None — additive only. `api-host` selects this when `host.openapi.ui = "scalar"`.