Home dashboards for Ryu — a customizable, constantly-updating grid of widgets.
The public home of
ryu-dashboards. Source, builds, and releases live here — binaries for every platform are attached to each release.This tree is generated from the Ryu monorepo, so commits pushed here directly are replaced on the next sync. Pull requests are welcome — open them here and they are ported into the monorepo, then flow back out. Ryu as a whole: https://github.com/amajorai/ryu
- Binary:
ryu-dashboardsfrom the Ryu releases. - Crate:
cargo install ryu-dashboards.
Apache-2.0 — see LICENSE.
The Home surface: a customizable, constantly-updating grid of widgets that assembles live views over monitors, meetings, quests, and other Core surfaces.
Structured like every other apps-store app — a backend capability crate plus its governance manifest — but with one deliberate exception: the UI is desktop-native (canvas tier), not a sandboxed companion iframe. See "Why canvas-tier" below.
| Path | What it is |
|---|---|
backend/ |
The ryu-dashboards Rust crate — the whole engine. |
(no ui/ here) |
The UI lives in the desktop app; see below. |
The Core plugin manifest for this app is
apps-store/dashboards/manifest.json
(id: @ryu/dashboards) — a governance shell with zero runnables, exactly like
research and teams. Install/enable/disable + the route gate govern the app; the
implementation stays in-crate. That root manifest.json (no embedded HTML UI) is the
app's ONLY copy — Core compiles it in via
include_str!("../../../../apps-store/dashboards/manifest.json") — so the app does
participate in the packaged_manifests_are_compiled_in_from_their_package_home guard.
An extracted Core capability crate. Core consumes it as a non-optional path
dependency (apps/core/Cargo.toml → ../../apps-store/dashboards/backend) — the
hardware device-dashboard renderer, the dashboard_builder MCP runnable, and the
background refresh loop all reach its types in every build. crates/ryu-hardware also
depends on it for e-ink/LCD panel rendering.
Sidecar-ization status (2026-07-18): OUT-OF-PROCESS. Served by the standalone
[[bin]] ryu-dashboards(kind:local,public_mount /api/dashboards, port 7997, started eager) via the generic ext-proxy loader; Core links zero dashboard code (no path-dep, no in-processnest_servicemount). The kernel weld —ryu-hardwarereachingDashboardEnginedirectly + the SSE broadcast into the hardware nudge loop — was inverted behind a minimalDashboardFeedtrait (crates/ryu-hardware/src/feed.rs, plain owned types), with the device-render logic moved into this crate'sdevice.rsas the single source of truth. Core'sDashboardFeedimpl, the nudge loop (reads the sidecar's/events?internal=1SSE, viewer cost-guard preserved), and thedashboard_builderMCP runnable all reach the sidecar over loopback viadashboards_client, so a decoupled node renders device dashboards byte-identically.
- SQLite store (
store.rs) — dashboards and their widget layout,rusqlite(bundled). - Widget-source resolution (
sources.rs) — the three cross-cutting couplings (Gateway URL/token for Composio, the agent runner for agent widgets, and the SSRF-guarded external fetch for HTTP widgets) are inverted through theDashboardsHosttrait, so the crate has zero dependency onapps/core. - Refresh loop (
refresh.rs) — background re-evaluation of live widget values. - Device-image renderer (
render.rs) —resvgrasterizes the widget SVG onto a pure-Rusttiny-skiapixmap (no headless browser, no system deps) and down-converts to 1-bit / rgb565 for hardware firmware. - HTTP surface (
api.rs) — the/api/dashboards/*router (list/create/read/update dashboards + widget CRUD) plus an SSE event stream of live widget values. Core nests it at/api/dashboardsbehind the App route gate.
Run its tests with cargo test -p ryu-dashboards.
The dashboard editor and renderer are desktop-native React, not a sandboxed companion:
apps/desktop/src/components/dashboard/—DashboardCanvas,DashboardGrid,WidgetCard,AddWidgetDialog,DashboardBuilderChat, and thewidgets/catalog.- Served as the desktop Home (
/home), the default landing surface.
Home is the app's front door. A sandboxed companion iframe (the shape used by quests,
monitors, mail, etc.) is the right call for a self-contained feature panel, but it would
wreck the Home dashboard UX: drag-to-arrange grid interactions, live in-process widget
rendering, and the deep integration with the shell (navigation, theming, the builder
chat) all want first-class desktop-native rendering. So Dashboards deliberately sits at
the canvas tier — the same tier as the workflow canvas (WorkflowCanvas) — with the
backend as a shared crate and the UI compiled into the desktop app.