v0.16.0

Released May 29, 2026 · All releases

Registry-driven sites. v0.16.0 turns the entity registry into pages and listings declaratively, delivers the three sibling registry-query runes (collection / relationships / aggregate — items / edges / numbers), and proves the system by scaffolding a real plan site from refrakt's own plan/ content. Builds directly on v0.15.0's embedding primitives (ref / expand).

Changes

  • v0.16.0 — Registry-driven sites.
  • Turns the entity registry into pages and listings declaratively, ships the three sibling registry-query runes (collection / relationships / aggregate — items / edges / numbers), and proves the system by scaffolding refrakt's own plan site from the plan/ content tree.
  • {% collection %} (SPEC-070) — the plural counterpart to ref / expand. Queries the registry with type + filter, applies sort / group / limit, and projects entities into list / grid / table layouts. Per-item body templates with $item bound; heading-delimited table columns; shared field-match grammar; shared formatter functions (humanize, date, number, currency, join); 3-zone body (preamble / template / fallback) with $count / $shown bindings; group-display="accordion" for collapsible groups.
  • {% relationships %} (SPEC-072) — graph-edge counterpart to collection. Renders an entity's edges grouped by kind (or type), generic over any domain's relationship vocabulary. Shares $item semantics with collection so card partials are reusable across both. Domain-aware ordering, accordion group display, body zones for empty state.
  • {% aggregate %} (SPEC-076) — number-projecting sibling. No-body form ({% aggregate type="work" filter="status:done" /%}) renders a single inline integer; body-zoned form iterates groups with $item bound to { key, count, value, percent, total, shown }. Optional value sub-filter (e.g. value="status:done") drives $item.percent for progress-bar ratios without a second query.
  • Plugin-contributed routes (SPEC-069) — new contributePages pipeline phase plus declarative entityRoutes in refrakt.config.json that generate one page per registered entity matching type + optional filter. embed() embeddability contract for cross-page composition.
  • Plan site scaffolding (SPEC-071) — refrakt's own plan site rebuilt from plan/ via entityRoutes + the registry-query runes. The bespoke plan build / plan serve commands are retired. Dashboard composition (aggregate header summary + per-status collection panels + empty-state hint runes) shipped as the canonical scaffold template.
  • Theme toggle (SPEC-073) — light / dark / auto toggle as both a chrome slot and a {% theme-toggle /%} rune, with shared behavior and prod-build CSS parity for the Cloudflare-style no-runes-bundle.
  • Accordion polish — leading rotating chevron via SVG mask, native <details> slide animation via ::details-content + interpolate-size, dividers-only outer treatment.
  • Badge restyle to a compact sentiment-tinted chip; sentiment via color-mix(in srgb, var(--meta-color) X%, transparent).
  • New "Registry" category in the rune catalog for the cross-page-query runes (xref / expand / collection / relationships / aggregate); seven previously-missing runes added to the catalog (xref, badge, gallery, showcase, bg, tint, blog).
  • refrakt.config.json schema — theme is now string | SiteThemeConfig (was just string); new SiteThemeConfig definition with package, presets, tokens, modes, and code.colorScheme. highlight flagged as legacy in favour of theme.presets (Lumina syntax presets contributing --rf-syntax-* overrides) + theme.code.colorScheme (forced light/dark code).
  • site/content/runes/aggregate.md — full reference page with live previews; sites.md updated for the theme object form.
  • Nav items containing an inline {% badge %} now sit as a flex row so the badge rides alongside the link instead of wrapping under it (link's display: block was claiming the full row).
  • Mobile docs toolbar long page titles now ellipsise instead of forcing horizontal page scroll (flex: 1 1 0 + max-width: 100%; overflow: hidden; on the toolbar).
  • Conversation rune's speakers="A,B" attribute now renders names as bold-inline prefix inside the bubble, matching the explicit > **Name**: form. Two related issues fixed: the extractor was missing the Markdoc inline wrapper around paragraph content, and the fallback path didn't inject a strong-prefix. The speaker-carrier span is now hidden via the correct data-field="speaker" selector.