v0.6.0: Add support for UIX fork
[v0.6.0] — 2026-07-03
Adds first-class support for UIX, the
card-mod-derived HA integration, alongside card-mod — read, generate, and
warn about cross-compatibility correctly regardless of which one (or neither)
is installed. Verified against real running instances of both engines in
Docker (tools/sandbox/run.sh and tools/sandbox/run-uix.sh), not just
source-reading or unit tests. Fixes #20.
Added
- UIX detection —
isUixInstalled()probes for UIX'suix-nodecustom
element, independent of the existing card-mod probe. The "card-mod not
detected" warning now only shows when neither engine is found. - Reads
uix:style blocks with the sameuix:>card_mod:precedence
UIX itself uses, so a card styled underuix:(by hand, or by UIX's own
tooling) reads back correctly into the panel — including entities-card
rows, which carry independentcard_mod:/uix:blocks from the card
itself. - Generates the right key automatically — output stays
card_mod:by
default (UIX fully supports it as a fallback), switching touix:only
when UIX is installed and card-mod is not. This mirrors a real constraint:
UIX's own installer refuses to set up alongside acard-mod.jsLovelace
resource, so "both installed" isn't a state its own tooling lets you reach
— defaulting tocard_mod:whenever card-mod is present is the safe
choice, not a guess. - Reverse-compatibility warnings — if a card's styling (or an individual
entities-card row's) lives only underuix:and UIX isn't installed, the
panel warns about that specific card/row instead of silently rendering
unstyled, with a one-click "copy to card_mod" fix for plain CSS.uix:
content using macros/billets gets a clear incompatibility warning instead
(worded differently depending on whether card-mod or UIX is the active
engine) — those features have no card-mod equivalent and can't be safely
regenerated by the studio, so there's no valid "fix" to offer, just a
heads-up. - UIX sandbox (
tools/sandbox/run-uix.sh) — a second Dockerised HA rig
running a real UIX integration, set up headlessly through its actual config
flow. Verifies detection, both style keys,uix:-over-card_mod:
precedence, and the live editor's output key against the real integration.
tools/sandbox/harness/compat_check.mjscovers the reverse direction
(card-mod-only) against the existing card-mod sandbox.
Correctness details worth knowing
- Clearing a style clears it under both keys. If you clear all styling on
a card that has stale content under the other key (e.g. oldcard_mod:
from before you switched to UIX-only), that stale value is cleared too —
otherwise it would silently reactivate via whichever engine's fallback
precedence applies, so "clear" wouldn't actually mean no styling. - Editing card_mod: keeps a plain uix: value in sync (UIX prioritizes
uix:overcard_mod:, so without this a card_mod edit could silently
have no visible effect under UIX) but never touches a uix: block using
macros/billets — that's hand-authored content the studio can't safely
regenerate, so it's left untouched rather than silently overwritten. An
info banner explains when this applies. - Editing uix: directly does overwrite existing macro/billet content,
since (unlike the case above) there's no fallback key to preserve it in —
the panel warns about this before it happens rather than silently
proceeding or silently doing nothing. - Explicit-but-empty style values (
uix: {style: ''}or{style: {}}) are
treated as "not set," matching UIX's own effective behavior, so they can't
accidentally mask a realcard_mod:fallback.