New self-contained feature in features/updater/ (mirrors the backup feature):
- index.js + feature.json (auto-discovered; routes /updater + sub-tabs).
- updater-page.js: 5 tabs — Overview (update/CVE/recovery counts), Updates
(per-app current->available + Update/Update-all), Security (CVEs by severity,
links to NVD), Recovery (per-app rollback points; snapshot-before-update),
History. Reads /data/updater/generated/{updates,cves,history}.json; falls
back to the installed-apps list so it's useful before the first scan. All
actions route through services.tasks (updater_check/apply/apply_all/rollback)
— no new mutating API.
- updater.css (self-contained, teal --page-updater hue) + updater-content.html.
- New topbar 'Updates' nav button (nav-updater) + active-highlighting in
topbar.js + spa.js. Kernel: setupRoutesFromManifest now allows module-only
features (no legacy handler) — this is the first such feature.
Backend generator + 'libreportal updater' task land next.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
The kernel now loads each feature's self-registering index.js from the
manifest (new 'module' field) before building routes, so index.html no
longer hardcodes a per-feature <script> list — one of the four registries
the modularization targets is now gone. Adding a page = drop a
features/<id>/ folder + a manifest entry; no index.html edit.
loadScript is idempotent and non-fatal: a module that 404s or fails to
register leaves its route on the legacy handler. Manifest-load failure
still falls back to the built-in route table.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Adds the foundation of the feature-module architecture
(docs/frontend-modularization.md) as inert, additive code:
- kernel/feature-registry.js: window.LP.features — runtime register(),
manifest loader, route-table + nav builders.
- features/manifest.dev.json: hand-committed manifest mirroring spa.js
setupRoutes() exactly (route -> handler + navId).
- index.html loads the kernel before spa.js.
Zero behaviour change: nothing consults the registry yet. Phase 0b flips
routing to be registry-driven with the spa.js Map as fallback.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>