Golden runs, benchmarks and documentation captures each called
assertFreshDemoBundle; the smoke launcher never did, so all ~128 smokes could
silently test a stale demo/srv/assets bundle. On #234 that cost a round of
analysis: three assertions went red and a fourth went green, because the old
code was wrong in two places that agreed with each other, and a mixed result
reads as a logic defect rather than a stale artefact.
launch() now runs the check once for every smoke, against the repository root
rather than the serving root — demo/srv has no src/** to fingerprint.
HP_ALLOW_STALE_BUNDLE=1 skips it for debugging and warns out loud, because a
guard that says nothing when it steps aside is the silent success this project
keeps removing. A mutation entry proves the call cannot quietly disappear.
Issue: #236
User-Visible: no
A fully fictional house (plans, devices, states) used for README screenshots,
the demo GIF and headless smoke tests — so no real home data ever appears in
public materials.
srv/demo.html — self-contained host page: <ha-icon>/<ha-card> stubs and a
fake hass (registries, states, callWS, callService, floors).
srv/assets/ — generated plan SVGs and icons.js (node demo/gen_icons.mjs,
needs the repo's devDependencies). The card bundle is copied from dist/:
cp dist/houseplan-card.js demo/srv/assets/.
serve.mjs — playwright launcher (route interception, no web server).
smoke_*.mjs — feature smoke tests; run with a Chromium installed via
PLAYWRIGHT_BROWSERS_PATH=<dir> npx playwright install chromium-headless-shell.
Note for sandboxed sessions: /tmp does not survive; this directory is the
persistent home of the harness (docs/DEVELOPMENT.md has the LD_LIBRARY_PATH recipe).