core/css held 13 flat stylesheets. Grouped by role, matching the JS sub-system
split:
core/css/base/ foundation (3): tokens, style, themes
core/css/components/ chrome + widgets (7): topbar, sidebar, modal, forms,
config, update-notifier, aurora-background
core/css/screens/ full-page screens (3): login, loading-screen,
setup-wizard
Path-only move (git mv) + href rewrite in index.html. No @import anywhere and
the <link> line order is unchanged, so the cascade is preserved; all 13 paths
verified to resolve.
Signed-off-by: librelad <librelad@digitalangels.vip>
backup/ held 15 loose .js plus css/html at the component root. Split into
per-tab sub-systems mirroring the admin/apps layout:
backup/core/{js,css,html}/ schema, base BackupPage, fetch-client,
cron-schedule, backup.css, backup-content.html
backup/dashboard/js/ backup-dashboard
backup/snapshots/js/ backup-snapshots, backup-snapshot-actions
backup/locations/js/ backup-locations, backup-location-fields,
backup-location-modal, backup-ssh-key
backup/migrate/js/ backup-migrate
backup/configuration/js/ backup-configuration, backup-retention-presets,
backup-engine-details
Updated the scripts[] array + loadFragment in index.js, the backup.css href in
index.html, and the handleBackup() fallback paths in spa.js. No behaviour
change — files moved verbatim (prototype-augment clusters), all 17 referenced
paths verified to resolve, node --check clean.
Signed-off-by: librelad <librelad@digitalangels.vip>
config-redirect/, peers/, ssh/ were redirect-only shim components (just a
feature.json each) whose handlers re-entered navigate() and were silently
no-op'd by the isLoading guard — i.e. the legacy /config /peers /ssh URLs were
broken, and nothing in the UI links to them. Replace all three with a single
_legacyRedirect() at the top of navigate() (before the guard, so it actually
works) that rewrites them to the canonical /admin/* path. Removed the 3
folders, their manifest entries, the 3 dead spa.js handlers, and their
setupRoutes() lines. components/ is now exactly the 6 real pages; the real
SSH/Peers pages live (as before) under admin/ssh and admin/peers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Brace-aware split of apps-manager.js (4154->2015 base) into apps-grid,
config-form, port-manager-integration, gluetun-vpn, config-dirty-guard,
install-console, service-buttons-sidebar — augmenting AppsManager.prototype.
Removed the dead duplicate initializeSimpleTabs (kept the live later def).
Used a self-checking extractor (node --check per cluster, auto-revert on
failure): install-dispatch contains a regex literal (/^\d{16}$/) that trips
brace-bounding, so its methods were safely LEFT in the base rather than risk a
bad split. ServiceButtons class + expandServiceLinks + bootstrap also remain
inline. Verified: all 117 methods preserved (none lost), all files
node --check clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
Faithful brace-aware split of tasks-manager.js (2664->491 line base) into
list-render, data-load, log-stream, row-expand, actions, modals, logs-modal,
format — augmenting TasksManager.prototype. First removed 4 provably-dead
duplicate defs (the earlier init/setupAutoRefresh/startLogStreaming/loadTaskLogs
that the later defs already overrode — behavior-preserving). Methods relocated
verbatim via a brace-aware Node extractor (handles strings/templates/comments/
regex, fixing the line-heuristic over-capture). Verified: all 60 (deduped)
methods present exactly once, no dups, all 9 files node --check clean. Wired
after the base in the task-system loader (async=false-ordered).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
De-clutter each component into sub-system folders (apps: core/ port-manager/
services/ tools/ routing/; admin: config/ overview/ system/ ssh/ peers/) with
the standard js/ css/ html/ icons/ layout inside; single-page components
(backup/dashboard/tasks/updater) get js/ css/ html/. Single-feature icon sets
moved into their sub-system (vpn -> apps/core/icons, config/cpu/os ->
admin/{config,system}/icons); shared app + category icons stay in core/icons.
feature.json + index.js stay at each component root (the scanned descriptor +
entry). Every controller/CSS/fragment/icon path reference rewritten; verified
no stale refs, all JS valid.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
system-loader's loadScript appended scripts without async=false, so a
component's scripts[] executed in download-finish order, not array order.
That's a latent nondeterminism today (duplicate-method 'last wins' depended
on it) and a hard blocker for splitting a class across files (a base file
must run before prototype-augment files). Forcing async=false makes the
boot loader honour array order, matching the kernel's ctx.loadScripts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>