Skip to content

v0.34.1 — Community widget marketplace

Choose a tag to compare

@dmellok dmellok released this 07 Jun 01:18

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
    static widgets.json index, downloads pinned release tarballs,
    sha256-verifies, validates against the plugin schema, and drops
    them into plugins/<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 the html background + color-scheme in <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 _core with 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 updated widgets.md
    coverage of choices_from (with the correct same-plugin
    resolution rule), _core companion plugins, and server.py
    blueprint() admin pages.
  • Phosphor regular TTF vendored at
    static/icons/phosphor/regular/Phosphor.ttf for server-side
    image rendering (PIL can't read the woff2 web font; the
    low-battery overlay needs this on disk).
  • marketplace_index_url setting 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.