feat(homepage): Audiobookshelf's own mark, and the voice endpoint in the model block
Audiobookshelf carried the improvised "AB" hex monogram — the fallback for apps with no icon. Simple Icons carries its brand mark, so the card now uses /img/apps/audiobookshelf.svg the way Plex and Jellyfin use theirs; the monogram went to .AGENTTRASH. frank-tts (Qwen3-TTS 1.7 B base talker on the gfx1151 iGPU) was an admin-only status tile, so the household read about five cloned voices in /docs and saw no sign of the door that speaks them. It is now a Model Information card on the user page beside the three chat models, carrying the ask-Frank permission note and a privacy note about cloned voices. miCard grew the shape that requires: art falls back to the card's own `art` when a card has no StarCraft `unit`, the accent falls back to `.mi-tool`, and a `tagline` with no `sfx` renders as text instead of a play button that plays nothing. No audio asset ships with the card on purpose: every pack on that endpoint is a replica of a real person's voice, so a sample clip would put a synthetic person's voice in the repo and on the page. Seams: the model-card contract splits unit cards (equivalence, supervision, playable voice line) from tool cards (permission note), and the voice stack's homepage seam now pins category=user with the reason.
This commit is contained in:
1 parent
e6a85176c4
commit
53e4a777b4
8 files changed
+60
-25
No files matched your search
@@ -981,9 +981,12 @@ DRV
|
||||
# there is no address the checker could dial, and a card that can never be
|
||||
# green is worse than no card. The façade carries the pair's signal — and
|
||||
# since the 2026-10-18 deploy that signal is a real probe (`wip: false`), not
|
||||
# a placeholder. It stays `showLink: false` and admin-only: an HTTP API has no
|
||||
# page to open, and the checker counts ANY HTTP response as up, so the card is
|
||||
# honest without a link and without a `/health` path in the probe.
|
||||
# a placeholder. It stays `showLink: false`: an HTTP API has no page to open,
|
||||
# and the checker counts ANY HTTP response as up, so the card is honest
|
||||
# without a link and without a `/health` path in the probe.
|
||||
# 2026-11-04: the card moved from admin to the user page's Model Information
|
||||
# block — the household guide already documents the voices (/docs#models), so
|
||||
# the family reading about them should also see whether the door is up.
|
||||
python3 - "$REPO_ROOT" <<'PY'
|
||||
import json, os, sys
|
||||
root = sys.argv[1]
|
||||
@@ -996,8 +999,10 @@ assert fts["wip"] is False, \
|
||||
"the endpoint is deployed; a wip card would hide its real state: " + repr(fts.get("wip"))
|
||||
assert fts["showLink"] is False and fts["url"] == "", \
|
||||
"an API endpoint has no UI to link to — it is a status card, not a tile"
|
||||
assert fts["category"] == "admin", \
|
||||
"consumers dial this; it is not an app the user homepage should advertise"
|
||||
assert fts["category"] == "user" and fts["section"] == "AI", \
|
||||
"the voice endpoint belongs to the user page's Model Information block: " + repr(fts["category"])
|
||||
assert isinstance(fts.get("model"), dict) and fts["model"].get("role"), \
|
||||
"the card renders as a Model Information card, which needs a model object"
|
||||
assert os.path.exists(f"{root}/shared/homepage{fts['art']}"), f"missing art {fts['art']}"
|
||||
PY
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user