11 Commits

Author SHA1 Message Date
librelad
7709b0d97b fix(backup): dispose document listeners on unmount (sidebar stacking bug)
The original report: clicking a backup sidebar tab loaded content on top of
the old content. Root cause (flagged in the unmount comment as deferred):
BackupPage.bindEvents() attaches document-level click/input/change listeners
guarded only by the instance-level this.eventBound, and unmount() nulled
window.backupPage WITHOUT removing them. Each revisit added another full set of
listeners bound to a stale BackupPage, all firing on every click and mutating
the live DOM (double tab-switches, double modal opens, stale-instance renders).

Fix (mirrors the kernel's MountContext pattern): give BackupPage an
AbortController, bind the three document listeners to its signal, add dispose()
that aborts them (+ drops the task-refresh reg + clears the timer), and call it
from the feature module's unmount(). Revisits now start clean — one live
instance, one set of listeners.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 14:48:54 +01:00
librelad
30612a0d87 docs: organize docs/ into purpose folders with consistent naming
Sort docs/ into guide/ contributing/ architecture/ roadmap/ and rename
to consistent kebab-case (USER->guide/install-and-use, FOOTPRINT->
architecture/system-footprint, frontend-modularization->architecture/
webui-architecture, etc.). Add a docs/README.md index and a docs/
CONTRIBUTING.md pointer so the forge still surfaces the contributing
guide. Fix every reference (README, init.sh comments, frontend code
comments, and the USER<->DEVELOPMENT cross-links). History preserved
via git mv. Root stays README.md + CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 00:48:38 +01:00
librelad
164606dc7c docs(webui): refresh stale features/ path comments after the components/ rename
Comment-only tidy from the feng-shui audit — no code behavior changes. The
features/ directory was renamed to components/ during modularization, but
several header banners and inline comments still named the old path:

- 6 component module headers (admin/tasks/backup/dashboard/updater/index.js +
  updater/js/updater-page.js) now name their real components/<id>/… path
- core/kernel/js/spa.js + core/tasks/js/task-router.js comments
- backend/routes/features.js doc-banner (drop a components/<id>/ folder …)
- core/update-notifier/css/update-notifier.css header (js/update-notifier.js)

Guarded the rewrite so the LIVE /api/features/list endpoint name (feature-
registry.js sources + backend route) is untouched — only stale 'features/<path>'
directory references were updated.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 00:41:16 +01:00
librelad
fe5cc18827 refactor(webui): give every core/ subsystem the js/css/html convention
Brings core/ in line with components/ — each subsystem now sorts its files into
js/ css/ html/ subfolders (and the nested auth/ + controls/ groups keep theirs):

  core/topbar/{js/{topbar,mobile-menu}.js, css/{topbar,sidebar}.css, html/topbar.html}
  core/theme/{js/theme-registry.js, css/{tokens,themes,base,aurora-background}.css}
  core/forms/{css/{forms,config}.css, controls/js/{custom-number,custom-select}.js}
  core/boot/{js/{system-loader,system-orchestrator}.js, auth/{js/auth-manager.js,css/login.css}}
  core/{config,tasks,kernel}/js/…  core/overlays/{js,css}/…  core/setup/{js,css}/…
  core/{app-meta,backup-card,data-loader,dom,live,notifications,ui-mode,ui-state}/js/…
  core/{loading,update-notifier}/{js,css}/…

50 files relocated (pure git mv). All path literals rewritten from a generated
old→new map across index.html, system-loader.js bundles, topbar.js's internal
fetch (/core/topbar/html/topbar.html), and the three backup-app-card loaders. No
OLD path contained a js/css/html segment, so no double-prefixing was possible.
core/icons/ left as-is (shared asset tree). All 50 /core asset refs verified to
resolve; full node --check sweep clean.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 00:00:52 +01:00
librelad
5351da5b4c refactor(webui): regroup core/ui + core/boot into named subsystems
Final structural phase — the catch-all core/ui/ is gone and core/boot/ keeps
only the genuine bootstrap pipeline:

  core/ui/eo-modal.js, confirmation-dialog.js   -> core/overlays/
  core/ui/notifications.js                       -> core/notifications/
  core/ui/topbar.{js,html}, mobile-menu.js       -> core/topbar/
  core/ui/update-notifier.js                     -> core/update-notifier/
  core/ui/backup-app-card.js                     -> core/backup-card/  (shared widget)
  core/boot/controls/                            -> core/forms/controls/
  core/boot/setup/                               -> core/setup/
  core/boot/loading-ui.js                        -> core/loading/
  core/boot/auth-manager.js                      -> core/boot/auth/

Each subsystem now owns its JS + CSS together (topbar.js beside topbar.css,
auth-manager beside login.css, etc.). Path-only moves; rewrote literals in
index.html, system-loader.js (confirmation/notifications/topbar/mobile-menu/
update-notifier/apps bundles), topbar.js's internal fetch('/core/topbar/
topbar.html'), and all THREE backup-app-card loaders (system-loader, backup/
index.js, spa.js). core/boot now = system-loader, system-orchestrator, auth/.
All 24 referenced paths resolve; full node --check sweep clean.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 21:34:18 +01:00
librelad
aa563f1fed refactor(webui): separate core/lib + core/boot into sub-system folders
core/lib held 18 loose .js; core/boot held 10. Grouped by responsibility,
mirroring the components/* sub-system layout:

  core/lib/task/    task kernel (8): event-bus, commands, actions, router,
                    global-functions, manager, refresh-coordinator,
                    parameter-preserve
  core/lib/config/  config helpers (2): config-shared, config-options
  core/lib/util/    generic utils (7): data-loader, dom-helpers, ui-helpers,
                    lp-ui, router, system-live, dismissible
  core/boot/setup/  first-run wizard (3): setup-detector, setup-wizard,
                    setup-completion-watcher
  core/boot/controls/ form widgets (2): custom-number, custom-select

core/lib is now purely subfolders. backup-app-card.js was misfiled in lib (it's
a UI card) — moved to core/ui/. core/boot keeps the genuine bootstrap singletons
at root (system-loader, system-orchestrator, auth-manager, loading-ui,
theme-registry).

Path-only moves (git mv); all 35 referenced core paths verified to resolve,
full node --check sweep of 100 frontend .js files clean.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 19:32:09 +01:00
librelad
939f0223fb refactor(webui): separate backup component into sub-system folders
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>
2026-05-30 19:18:43 +01:00
librelad
82989069e2 refactor(backup): decompose backup-page god-file into 13 responsibility files
Faithful prototype-augment split of backup-page.js (2353->753 line base) into
fetch-client, dashboard, snapshots, locations, location-fields, ssh-key,
retention-presets, configuration, engine-details, location-modal,
snapshot-actions, migrate (+ the earlier cron-schedule). Methods relocated
verbatim (mechanical sed/awk extraction, no logic change); all augment
BackupPage.prototype and load after the base via the ordered kernel loader.
Verified: all 99 original methods present exactly once across base+clusters,
no duplicates, all 14 files node --check clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 14:02:45 +01:00
librelad
3ad44a62f2 refactor(backup): extract cron-schedule cluster from backup-page god-file
First god-file decomposition slice: lift the standalone cron-next utility
(nextCronFireTime/_cronFieldSet/formatRelativeFuture/formatScheduleClock) out
of backup-page.js into backup-cron-schedule.js, augmenting BackupPage.prototype.
Extracted verbatim via sed (no logic change); loaded after backup-page.js in
the feature's ordered scripts array. backup-page.js 2470 -> ~2353 lines.
Proves the faithful prototype-split pattern on the verify-confirmed-safe loader.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 13:02:13 +01:00
librelad
2ef4cc00e1 refactor(webui): granular sub-system folders per component
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>
2026-05-30 12:42:35 +01:00
librelad
d39852aa3d refactor(webui): reorganize into components/ + core/ taxonomy
Final modularization layout (user-chosen): every page is a self-contained
folder under components/<id>/ (controllers + CSS + its html fragment), and all
shared/framework code folds into core/:
  core/kernel  (feature-registry, lifecycle, services, spa)
  core/boot    (auth, system-loader/orchestrator, setup, loaders)
  core/lib     (data-loader, router, helpers, the task kernel, shared modules)
  core/ui      (topbar, modal, notifications, … + topbar.html)
  core/css     (all shared stylesheets)
  core/icons
Top level is now just: components/, core/, themes/, index.html (+ runtime data/).

Every path reference rewritten (index.html, scripts arrays, fetch()/
loadFragment()/loadScript() literals, system-loader + config-manager controller
paths, kernel manifest URL, feature.json, backend FEATURES_DIR). The
/api/features/list endpoint NAME is unchanged (it now scans components/).
Deleted 3 dead files (app-content.html, apps-content.html, html-cache.js).
Verified: 0 stale prefixes, 0 double-rewrites, all JS/JSON valid.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-30 07:13:52 +01:00