Plugin settings UI:
- Settings → Plugins now shows a clean list (status dot, name, enabled badge)
with a Settings button per plugin linking to its own detail page
- Per-plugin detail page at /settings/plugins/<name>/ shows enable toggle,
all config fields, load status, and failure notice if the plugin errored
- Config saving now scoped per-plugin via POST /settings/plugins/<name>/;
removes the monolithic save-all-plugins form
Plugin repositories:
- Replace single Plugin Index URL field with a managed list of repositories
(HTMX add/edit/remove per entry, same pattern as Ansible sources)
- plugin_index.py: fetch_catalog() now accepts a list of URLs, caches per-URL,
and merges results deduplicating by plugin name (first repo wins)
- Legacy plugins.index_url is auto-migrated to the new list format on first
access so existing installs don't lose their configured URL
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Plugin failures:
- Track load-time failures in _FAILED_PLUGINS dict with human-readable reasons
- Inject plugin_failures into all templates via context processor
- Show admin-only warning banner in base.html when any plugin fails to load
- Show inline failure notice per plugin card in Settings → Plugins
NUT managed mode:
- entrypoint.sh: make nut_setup.py failure non-fatal so the container starts
even if nut_ups_host isn't set yet (allows fixing config via UI)
- save_plugins: when nut_managed is enabled, auto-set nut_host=localhost so
the plugin connects to the managed NUT instance without extra manual config
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add managed NUT mode: configure NUT daemon from Settings → Plugins
(UPS plugin), writes /data/nut_managed.json read by entrypoint on
restart — no env vars or USB passthrough required
- entrypoint.sh: start NUT from /data/nut_managed.json or NUT_MANAGED=1
env var; drop to app user via gosu after NUT daemons start
- nut_setup.py: support --from-file <json> in addition to env vars
- Dockerfile: add nut, nut-client, gosu packages and entrypoint
- docker-compose.yml: document optional NUT_MANAGED env var block
- Fix plugin hot-reload migration failure: pass all plugin migration
dirs to Alembic so previously-stamped revisions from other plugins
remain resolvable (fixes UPS and any plugin with depends_on)
- Fix plugin list-type config (e.g. SNMP devices) rendering as broken
text input — now shows a read-only note to edit plugin.yaml instead
- Fix _sync_nut_managed_config: only write JSON when nut_ups_host is
non-empty, preventing NUT startup loop on container restart
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>