The dashboard
The dashboard is a single-page React application served by the Go binary on port 8080, and on 8443 with the server’s own certificate because the setup walkthrough uses Web Bluetooth and Bluetooth needs a secure context.
It is hash-routed: #/<section>/<tab> and, where a tab holds a collection,
#/<section>/<tab>/<item>. Routes from two earlier layouts still resolve, so old
bookmarks land on the right tab rather than the front page.
The shape is deliberately flat. Six sections in a sidebar — a strip across the top on a narrow screen — each one page with a tab bar. Collections are lists of rows you open and come back out of, not grids of cards. Beside the sidebar title sits a robot picker showing the current robot’s name over its serial, because one server can carry several.
No tabs. This is the robot.
At the top, a hero: his name and status, whether he is docked and charging and how full the battery is, which mode he is in, whether he is quiet or talking, and his eyes drawn as they are set right now. Beside it, the four things you actually reach for: Say, Mode, Quiet, and Open Live.
Below that, the last 24 hours of battery as a line with a plain-language verdict, and the last five events.
What he can see and do, right now.
- View — one paced camera player with his own detections drawn over it, and the people he knows.
- Teach — the same player, used to save labelled crops so the server-side recogniser can learn an object or a person. See Vision.
- Cube — status and connection, the cube’s lights, the games, and a live feed of taps.
- Drive — manual control, with a small copy of the camera player so he is not driven blind.
Everything drawn on his screen.
- Eyes — colour, and the eye builder: scale, spacing, angle, corner radii, lid position and bend, with a live preview.
- Screen — the expressions grid; animations as a list, where opening one gives you a player; and GIFs, which are letterboxed and streamed to his display frame by frame.
- Clock — the clock face and its options.
Who he is.
- Persona — the system persona text.
- Chatter — idle chatter, vision reactions, the camera glance, quiet hours and quiet mode.
- Memory — what he remembers, and what to forget.
- Mode — a list; opening one applies it. See Modes and sound sets.
- Friends — the people and animals the social engine knows, their styles and weights, and the rehearse control. See Social reactions.
The hardware.
- Settings — his name, sound and language including the wake word, place and time with the temperature unit, and accounts.
- Power — CPU speed and the battery in detail. See Power and battery.
- Profiles — behaviour presets as a list; opening one lets you edit its parameters and apply it.
- Firmware — what he is running, when he last updated, and the builds available on this server as rows with Install inline. See EmberOS firmware.
- Connection — where he talks to, and his firmware version.
Server
Section titled “Server”The parts that are not the robot.
- Providers — the transcription and language-model endpoints, the weather and GIF keys, and a Restart brain button.
- Events — the subscriber URLs, the Home Assistant bridge, and the activity table of what has actually been emitted.
- Logs — the server’s log.
- Add a robot — the Bluetooth walkthrough: connect, enter the pin, pick a saved network, install firmware from this server, find him on the network, point him at this server, pair, and finish onboarding. Also reachable from the plus button beside the title.
How it is built and served
Section titled “How it is built and served”The dashboard is built with Vite and the output is written into the Go server’s web root, where it is committed to the repository. That is why deploying the server deploys the dashboard, and why the machine running Ember never needs a JavaScript toolchain.
Its component primitives and design tokens are a small local set — badge, button, card, status dot, usage bar — using OKLCH colour, reimplemented rather than pulled from a package. The Bluetooth layer vendors Digital Dream Labs’ robot-side protocol library as ES modules with a typed wrapper over the top.