# K1 Live Console React 19 + TypeScript + Vite frontend for the local K1 bridge. The console handles connection setup, source selection, transport status, latency metrics and handoff to the Foxglove 3D viewer. It does not emulate scanner operations or generate placeholder telemetry. ## Run locally ```bash cd apps/k1-viewer npm install npm run dev ``` The development server listens on `http://127.0.0.1:5173` and proxies `/api` to `http://127.0.0.1:8000`. Set `VITE_API_TARGET` in a local `.env` file to use a different backend address. Production artifacts are built with `npm run build`. The NODE.DC UI packages are consumed from the sibling `NODEDC_DESIGN_GUIDELINE` checkout through `file:` dependencies. Their source is not copied into this app. ## Backend contract | Method | Route | Body / purpose | | --- | --- | --- | | `GET` | `/api/health` | Local service health | | `GET` | `/api/state` | Authoritative console state | | `POST` | `/api/ble/scan` | `{ "duration_seconds": 6 }` | | `POST` | `/api/connect` | `{ "device_id", "ssid", "password" }` | | `POST` | `/api/session/live` | Optional `{ "host", "duration_seconds" }` | | `POST` | `/api/session/replay` | `{ "path", "speed", "loop" }` | | `POST` | `/api/session/stop` | Stop the active source | | `WS` | `/api/events` | State snapshots for live UI updates | `/api/state` and state-changing responses may return the snapshot directly or as `{ "state": { ... } }`. A snapshot exposes `phase`, `message`, `devices`, `selected_device_id`, `k1_ip`, `foxglove_ws_url`, `foxglove_viewer_url`, `source_mode` and `metrics`. The Wi-Fi password remains only in React memory, is sent in the JSON POST body, and is cleared after the backend acknowledges a successful connection. It is never written to local storage or included in a URL. ## Explicit unavailable states - Missing metrics render as an em dash; no synthetic values are used. - BLE scanning remains a real API action and reports HTTP/network errors visibly. - The Foxglove button is disabled until the backend supplies `foxglove_viewer_url`. - Replay cannot start without a backend-local capture path.