The first major release since v0.31.0. Five tag versions rolled up
into one release: the community widget marketplace, bundle support
for widget families, a low-battery overlay for device pushes, a Send
page polish pass, and a UI consistency rename.
Highlights
- Community widget marketplace (phase 1). A new
Settings → Widgets → Browse community widgets page backed by an
audit-only catalog at
dmellok/tesserae-widgets.
Users browse a card grid of community-contributed widgets and
install with one click. Behind the scenes the host fetches a
staticwidgets.jsonindex, downloads pinned release tarballs,
sha256-verifies, validates against the plugin schema, and drops
them intoplugins/<id>/alongside the bundled widgets. Trust
model is audit-only: every catalog entry passes through PR
review (capability sandbox + process isolation are tracked as
issues #2 /
#3). - Bundle entries for widget families. A single catalog entry
can install a multi-folder family (e.g.github_core+
github_releases+github_actions) atomically. The tarball
wraps every subplugin in a containing folder; the install path
auto-detects the layout and (when the entry declares
folders: [...]) verifies the tarball matches exactly. Uninstall
acts on the whole bundle as a unit. - Low-battery overlay on device pushes (Settings → Server → App).
When a battery-powered device reports a charge at or below the
threshold (default 15%, configurable 5–50%), a small Phosphor
warning chip paints in the top-right of the composition before
the per-renderer transform. Per-device, so a fan-out to a
mains-powered Pi + a low TRMNL only marks the TRMNL. - Send page polish. Live preview now follows the picked target
device's panel aspect (was previously pinned to the global virtual
panel, which made fit-mode previews misleading). The duplicate
Saved-dashboard tab is gone (Dashboards page already does that).
White flash on every page navigation in dark mode is fixed by
inlining thehtmlbackground +color-schemein<head>. - Plugins → Widgets in the UI + docs. The top-nav dropdown,
the Settings tab, the/plugins/index page, the wiki nav section
("Widget development"), and every "Settings → Plugins" breadcrumb
in the docs now say "Widgets" — matching how everyone already
talks about them. Code paths (/plugins/,plugins/,
plugin.json) stay since they're the technical contract.
Under the hood
- Catalog seed in-tree at
docs/marketplace-catalog-seed/:
copy-into-a-new-repo scaffold for the catalog repo with empty
widgets.json, schema,CONTRIBUTING.md, PR template, and a CI
workflow that fetches every tarball + verifies sha256 + checks
screenshots before any PR can merge. - Dev-reference widget bundle published as the catalog's first
bundle entry
(tesserae-devref-bundle).
Pairs an admin_corewith a display widget that exercises every
cell-option type (string,textarea,number,select,
multiselect,boolean,color,choices_from), server-side
fetch(),blueprint()admin pages, and theme-aware CSS. Read
the source as a worked example. - Wiki gains a Publish a widget through the
catalog
page covering submission end-to-end, plus updatedwidgets.md
coverage ofchoices_from(with the correct same-plugin
resolution rule),_corecompanion plugins, andserver.py
blueprint()admin pages. - Phosphor regular TTF vendored at
static/icons/phosphor/regular/Phosphor.ttffor server-side
image rendering (PIL can't read the woff2 web font; the
low-battery overlay needs this on disk). marketplace_index_urlsetting points at the catalog; set to
a fork or empty to disable the Browse page entirely.- 27 new test cases for the marketplace covering index fetch
failure modes, install rejections (sha256 mismatch, oversize
tarball, manifest collision, kind drift), happy path, bundle
handling, atomic rollback, legacy-record backward compat. 834
pass total; mypy --strict clean across the loader path.
See CHANGELOG.md
for the full breakdown.