dashboard_open.
Dashboard files
Each dashboard lives under a lowercase kebab-case slug:dashboard.css is optional. Keep custom component code in dashboard.js so later edits preserve the complete view.
A current manifest uses API version 3:
slug must match. Embedder manages code hashes, CSS hashes, and timestamps after validated writes. An external code change is treated as a user edit, which protects it from an unreviewed agent overwrite.
Open dashboards appear in the Monitor’s add-tab menu. File changes reload an open dashboard after the project watcher settles. You can also delete a dashboard from that menu.
Bind live data
Declare every channel family the dashboard can read insubscriptions. An exact string matches one channel, and a trailing * matches a prefix.
Common Monitor channels are:
plot:<port>:<channel>for numeric plot batchesserial:<tabId>for serial linesserial-tabsfor serial tab connection and configuration stateserial-portsfor detected portstext:<port>:<channel>for text telemetrytrace:<sessionId>for trace eventscapture:<captureId>for capture manifests
embedder.history(spec), then update it with embedder.subscribe(spec, callback):
embedder.data instead of reading payload fields by guess:
plotPoints,plotValues, andlatestPlotPointserialLines,serialTabs, andserialPortstextPoint,traceEvents, andcaptureManifest
tabId, port, and channel from the payload itself.
Hardware scripts can publish numeric data with embedder_publish_plot(source, points). Dashboards receive it through plot:<source>:<channel> subscriptions without Teleplot firmware output.
Built-in component catalog
Start withembedder.ui.dashboard() and add only the components that support the operator’s task.
Readouts
metric: a current numeric valuestatus: a discrete state withneutral,success,warning,error, orinfotonegauge: a bounded value with optional thresholdsprogress: a percentagesparkline: a compact recent numeric trend
Plots and timelines
timeSeries: timestamped numeric tracesxy: arbitrary connected X/Y pointsscatter: unconnected X/Y pointslogic: digital signals over timespectrum: frequency-domain points with optional logarithmic axesband: a trace with low and high boundsstateTimeline: discrete states over timebarChart: categorical valueshistogram: a value distributionheatmap: two-dimensional magnitude cells
Data and custom content
table: object rowslog: serial lines or event messagesserialMonitor: the Monitor’s serial UI in a dashboard cardcard: static text or custom DOMdrawing: a responsive SVG or Canvas surface
Layout
group: related controls or readouts in one cardtabs: task-specific views that keep their child components mountedadd: attach a custom object that exposes anelement
Controls
button: a synchronous local UI actionaction: asynchronous work or a hardware action with pending, success, and error statestoggle: a Boolean selectionslider: a bounded numeric selectionselect: one choicemultiSelect: several choices
minWidth and minHeight values on every card, group, and drawing.
Include the serial monitor card
UseserialMonitor when the dashboard reads or controls a serial session:
allowsHardwareWrite to true if the card’s send and connection controls must be enabled. Without that flag, the card remains readable but its write controls are disabled.
Send events and hardware commands
embedder.emit({ name, payload }) reports a declared event to the agent’s next turn. It queues the event but does not wake the agent or perform an action. Declare the name in events and handle an accepted: false result in the UI.
Event payloads must be JSON-serializable and no larger than 64 KiB. The default event budget is 20 per turn and 60 per minute.
For device actuation, use an action control and embedder.hardware.send:
- The manifest has
allowsHardwareWrite: true. - The command uses the ID of an existing serial tab.
- You approve the dashboard’s current JavaScript hash.
- No conflicting hardware workflow owns the target.
dashboard.js outside Embedder invalidates the code-hash grant; a validated agent edit can carry an existing grant to the new hash.
Build a custom component
Use a custom component for a view the built-ins do not provide, such as a pie, radar, polar plot, compass, Smith chart, waterfall, spectrogram, eye diagram, or 3D surface. Create adrawing and append an SVG or Canvas element:
- Build the DOM once and expose small mutators such as
set,append, orclear. - Size from
drawing.surfacewithResizeObserver. - Bound every sample buffer.
- Ignore missing and non-finite values.
- Show an empty state until data arrives.
- Use the injected
--dash-*theme variables. - Clear timers or animation frames when replacing a component.
embedder.subscribe, embedder.history, embedder.state, and the declared bridge methods instead. Persisted dashboard state is limited to 64 KiB.
The iframe allows scripts but does not receive same-origin access. Manifest
subscriptions, event declarations, hardware grants, and the code hash form the
boundary between dashboard code and the Monitor host.

