]> ###2026.06.11.09 - Release: Promote the full `2026.05.27.01` through `2026.06.11.08` development cycle to the stable `main` channel while keeping the manifest, CA feed, package archive, and plugin install link pointed at `main` - UX: Rework the cleanup dashboard around clearer `Ready`, `Needs review`, `Blocked`, and `Ignored` outcomes, merge search/sort/filter controls, remove the scanned appdata paths block, simplify row badges/actions, and keep the Controls panel focused on Rescan, Cleanup Options, and Help - UX: Add a detailed Help reference, richer row Details diagnostics, inline explanations for review/blocked rows, clearer result/status messaging, and Cleanup Options affected-row counts so users can understand why an item is safe, review-gated, or blocked - UX: Move review unlock controls closer to selection workflows, autosave Cleanup Options switches, rename Advanced safety to Cleanup Options, restore the full non-tabbed Help layout, and tighten dashboard spacing across the top controls and results status areas - Safety: Preserve hard locks for unsafe paths, Docker inventory uncertainty, ZFS dataset delete requirements, permanent-delete requirements, outside-share review gates, and saved-template cleanup gates while allowing per-scan unlocks for review rows - Delete flow: Add a live permanent-delete progress window with counters, a progress bar, recently deleted paths, and a View results step before the final completion screen - Fix: Improve Unraid theme handling, row Details modal rendering/content, light-theme palette detection, and cleanup review workflow regressions from the development cycle - Test: Extend behavior smoke coverage for scan-scoped unlocks, settings persistence, delete/progress behavior, details data, row actionability, and safety bypass boundaries ###2026.06.11.08 - UX: Restore the Help window to the original full reference layout without tabs ###2026.06.11.07 - UX: Merge search and sort into one results controls panel, remove the scanned appdata paths block, simplify row badges and locked-row actions, and make Help tabbed ###2026.06.11.06 - UX: Combine notices and results filter status into one responsive row with equal-width modules on desktop ###2026.06.11.05 - UX: Move visible/detected and active filter status out of the Sort card into a dedicated results status row with a Clear filter button ###2026.06.11.04 - UX: Tighten the Controls panel layout so Rescan, Cleanup Options, and Help fit the top row without making the dashboard cards uneven ###2026.06.11.03 - UX: Add a Controls Help button with a detailed in-app reference covering scan sources, result states, row reasons, actions, Cleanup Options, quarantine, ZFS, safety rules, troubleshooting, and recommended workflow ###2026.06.11.02 - UX: Add Cleanup Options affected-row counts, split safety-blocked rows from option-blocked rows, restructure Details around verdict/source/action-gate explanations, and clarify cleanup result and empty-state messages ###2026.06.11.01 - UX: Add explicit Why and How to resolve explanations to Needs review and Protected rows, with fuller Details diagnostics for policy locks, safety locks, templates, paths, and ZFS state ###2026.06.10.10 - UX: Add a live permanent-delete progress window with counters, a progress bar, recent deleted paths, and a View results step before the final completion screen ###2026.06.10.09 - UX: Rename Advanced safety to Cleanup Options and move it into the Controls panel with a short controls description ###2026.06.10.08 - UX: Move the bulk Unlock selected control from the top action bar to the bottom selection bar beside Select ready ###2026.06.10.07 - UX: Remove the Advanced safety save button and automatically persist each safety checkbox when it changes ###2026.05.27.01 - UX: Simplify the dashboard around `Ready to clean`, `Needs review`, `Protected`, and `Ignored` sections so users see cleanup outcomes instead of internal source categories - UX: Move persistent risky switches into an `Advanced safety` modal and keep the main controls focused on rescan, selection, quarantine, and review workflows - UX: Add per-row `Unlock for this scan` and `Relock` actions for review items so saved-template and outside-appdata decisions can stay temporary by default - Safety: Keep protected paths, Docker inventory locks, ZFS delete requirements, and permanent-delete requirements non-bypassable from the normal workflow - Copy: Reword saved-template warnings, row details, notices, counters, and selection hints around user-facing outcomes rather than policy-lock terminology - Test: Cover scan-scoped saved-template unlocks while preserving the persistent advanced saved-template bypass behavior ###2026.05.20.04 - Release: Promote the full `2026.05.05.01` through `2026.05.20.03` development cycle to the stable `main` channel while keeping the manifest, CA feed, package archive, and plugin install link pointed at `main` - Support: Keep diagnostics available during failed or stuck operations, add a redacted `Copy diagnostics text` fallback, and include clearer runtime-lock state, scan timing details, safety toggles, source roots, quarantine totals, and export failure context for troubleshooting - Fix: Return the underlying filesystem move error when quarantine fails instead of hiding it behind a generic failure message - Fix: Stop quarantine manager and dashboard summary loads from running scheduled purge side effects, so expired or protected quarantine entries no longer keep the backend busy while users are trying to review quarantine - Fix: Allow quarantine purge to remove symlink entries inside already-quarantined folders without following them, while continuing to block mount points, top-level symlinks, and special filesystem entries - Fix: Pause failed scheduled purge timers and retain the failure reason so protected quarantine entries are not retried on every page refresh - Safety: Lock saved-template appdata candidates by default, keep template-referenced rows under configured appdata roots out of outside-share review counts, and show a `Template reference` badge for that policy lock - Safety: Disable cleanup actions when Docker appears to be running but installed containers cannot be verified while saved templates are present - Safety: Add an `Allow saved-template cleanup` checkbox that bypasses only the saved-template policy lock while preserving outside-share, ZFS dataset delete, permanent-delete, hard-lock, ignored-row, and Docker inventory safeguards - Test: Extend behavior smoke coverage for diagnostics fallback, quarantine load/purge behavior, failed purge suppression, saved-template locks and bypass, template row labeling, and unverified Docker inventory locks ###2026.05.20.03 - Safety: Add an `Allow saved-template cleanup` checkbox that bypasses only the saved-template policy lock for template-referenced rows - Safety: Keep outside-share, ZFS dataset delete, permanent-delete, hard-lock, and Docker inventory locks enforced when saved-template cleanup is enabled - Test: Cover saved-template cleanup persistence, dashboard actionability, action-time validation, and outside-share lock preservation ###2026.05.20.02 - Fix: Keep saved-template rows inside configured appdata sources from being mislabeled as outside-share review rows while preserving the template-reference safety lock - UI: Show a `Template reference` lock badge for saved-template rows instead of the outside-share badge when the path is already under a configured appdata source - Test: Cover template-backed rows under configured appdata sources so they stay locked without inflating outside-share review counts ###2026.05.20.01 - Fix: Stop quarantine manager and dashboard summary loads from running scheduled purge side effects, so expired or failing purge entries no longer keep the backend busy while users are trying to review quarantine - Fix: Allow quarantine purge to remove symlink entries inside already-quarantined folders without following them, while continuing to block mount points, top-level symlinks, and special filesystem entries - Fix: Pause failed scheduled purge timers and preserve the failure reason so the same protected quarantine entry is not retried on every page refresh - Safety: Lock saved-template appdata candidates by default and require the saved Docker template to be removed or updated before quarantine or delete actions are allowed - Safety: Disable cleanup actions for a scan when Docker appears to be running but no installed containers can be verified while saved templates are present - Test: Cover read-only quarantine loads, symlink-containing quarantine purge, failed purge retry suppression, template-backed action locks, and unverified Docker inventory scan locks ###2026.05.05.03 - Support: Clarify copied diagnostics text by reporting runtime lock metadata separately from active held locks - Support: Mark each copied runtime lock row as active or inactive and include active lock counts - Support: Include boolean scan phase details such as Docker runtime state and snapshot write success in copied diagnostics text ###2026.05.05.02 - Support: Add `Copy diagnostics text` in Tools so users can copy a redacted plain-text diagnostics summary for forum posts - Support: Include scan summary, safety toggles, source roots, quarantine totals, scan timing phases, runtime-lock state, server runtime context, support log counts, visible/selected row counts, and diagnostics export errors in the copied text - Fix: If JSON diagnostics export fails, the text diagnostics copy still falls back to local browser state and includes the export failure message ###2026.05.05.01 - Support: Allow diagnostics export to run even when a scan, hydration, quarantine, or cleanup operation is holding the expensive-operation lock, so users can still capture troubleshooting data after a failed or stuck operation - Fix: Return the underlying filesystem `rename()` error when quarantine moves fail, while preserving the source folder in place ###2026.05.04.07 - Release: Promote the full `2026.05.04.01` through `2026.05.04.06` development cycle to the stable `main` channel while keeping the manifest, CA feed, package archive, and plugin install link pointed at `main` - Fix: Prevent Appdata Cleanup Plus from exhausting Unraid PHP-FPM workers by allowing only one filesystem-heavy scan, hydration, quarantine, diagnostics, or cleanup request to run at a time and returning a fast retry response for overlapping requests - Fix: Include safety-setting saves in the expensive-operation guard so quarantine rebuilds and settings writes cannot overlap with scan or hydration requests - Fix: Recover old unheld runtime lock metadata safely before acquiring a new operation lock, while leaving active `flock`-held operations untouched - Fix: Backfill exported `scan.metrics` from persisted server diagnostics when browser scan state has an empty metrics object - Support: Add backend-generated diagnostics exports with redacted plugin state files, safety settings, quarantine registry, ignore list, audit history, snapshot summaries, stats-cache counts, runtime context, runtime-lock state, latest scan metrics, and bounded support log excerpts - Support: Add per-phase scan timing metrics for settings load, template glob, Docker state/query, template scan, filesystem discovery, candidate filtering, row build, and snapshot write - Support: Persist latest backend scan timing metrics server-side so diagnostics exports can include phase timings even when browser page state misses them - Support: Add runtime-lock diagnostics to the Tools export so active lock name, action, age, PID state, held state, and stale status are visible during troubleshooting - Privacy: Redact filesystem paths, share/app-specific path segments, syslog hostnames, IP addresses, emails, query tokens, UUIDs, MAC addresses, long hex tokens, nested audit row payloads, restored app names, and audit result paths before diagnostics are downloaded - Support: Tighten diagnostics log matching so unrelated `emhttpd`, flash-backup, startup, and pool noise is excluded while plugin, PHP-FPM, nginx, timeout, and error context stays included - UX: Pause background row-stat hydration before user-triggered operations, retry plugin-busy responses, and show a distinct `Backend busy` scan state for HTTP 429 instead of presenting guarded requests as generic scan failures - UX: Update Tools diagnostics copy to clarify that exported diagnostics include redacted server-side log context and should still be reviewed before sharing - Performance: Read audit history from the tail of the audit log with a bounded default instead of loading the full audit file on long-lived installs - Performance: Replace parent-candidate O(n²) pruning with a path-prefix index while preserving parent, child, and sibling behavior - Safety: Add a filesystem discovery size guard with bounded partial results and a warning when direct appdata candidate discovery reaches the safety limit - Test: Extend behavior smoke coverage for runtime locks, duplicate lock rejection, stale-lock recovery, parent-candidate pruning, diagnostics redaction, diagnostics log filtering, scan timing metrics, persisted scan metrics, and filesystem discovery truncation ###2026.05.04.06 - Support: Persist the latest backend scan timing metrics server-side so diagnostics exports can include phase timings even when browser page state misses them - Fix: Backfill exported `scan.metrics` from server diagnostics when the frontend scan state has an empty metrics object - Test: Extend behavior smoke coverage to verify scan metrics are persisted for diagnostics fallback ###2026.05.04.05 - Support: Add runtime-lock diagnostics to the Tools export so active lock name, action, age, PID state, held state, and stale status are visible during troubleshooting - Fix: Recover old unheld runtime lock metadata safely before acquiring a new operation lock, while leaving active `flock`-held operations untouched - Support: Add per-phase scan timing metrics for settings load, Docker state/query, template scan, filesystem discovery, filtering, row build, and snapshot write - Support: Tighten diagnostics log matching so unrelated `emhttpd` startup/pool noise is excluded while plugin, PHP-FPM, nginx, timeout, and error context stays included - UX: Show a distinct `Backend busy` scan state when a guarded request returns HTTP 429 instead of presenting it as a generic scan failure - Safety: Add a filesystem discovery size guard with bounded partial results and a warning when direct appdata candidate discovery reaches the safety limit - Test: Cover stale-lock recovery, scan timing metrics, diagnostics log filtering, and filesystem discovery truncation in the behavior smoke suite ###2026.05.04.04 - Privacy: Tighten server diagnostics audit export so nested action row payloads are omitted and restored app names inside audit results are redacted - Support: Reduce diagnostics log noise by matching `emhttpd` process lines instead of every unrelated log line that only references an `emhttp` filesystem path - Test: Extend diagnostics smoke coverage to block unrelated flash-backup log noise and nested audit app-name leakage ###2026.05.04.03 - Support: Add a backend-generated diagnostics bundle so Tools exports include redacted plugin state files, audit history, snapshot summaries, runtime context, and bounded support log excerpts - Privacy: Redact filesystem paths, share/app-specific path segments, syslog hostnames, IP addresses, emails, query tokens, UUIDs, MAC addresses, and long hex tokens before diagnostics are downloaded - UX: Update the Tools diagnostics copy to clarify that exported diagnostics include redacted server-side log context and should still be reviewed before sharing - Test: Cover diagnostics log inclusion and redaction with a synthetic syslog containing sensitive host, path, email, IP, and token data ###2026.05.04.02 - Fix: Include safety-setting saves in the expensive-operation guard so quarantine rebuilds and settings writes cannot overlap with scan or hydration requests - UX: Pause background row-stat hydration before user-triggered operations and retry plugin-busy responses so healthy guarded requests do not show as false failures - Performance: Read audit history from the tail of the audit log with a bounded default instead of loading the full audit file on long-lived installs - Performance: Replace the parent-candidate O(n²) pruning pass with a path-prefix index while preserving parent, child, and sibling behavior - Test: Cover parent-candidate pruning behavior in the smoke suite ###2026.05.04.01 - Fix: Prevent Appdata Cleanup Plus from exhausting Unraid PHP-FPM workers by allowing only one filesystem-heavy scan, hydration, quarantine, or cleanup request to run at a time and returning a fast retry response for overlapping requests - UX: Retry deferred row-stat hydration and quarantine-summary refreshes after plugin-busy responses so the dashboard can finish background updates without stacking PHP workers - Test: Cover runtime lock acquire, duplicate-acquire rejection, release, and reacquire behavior in the behavior smoke suite ###2026.04.23.02 - Release: Promote the full `2026.04.13.04` through `2026.04.23.01` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Support: Add a `Tools` workflow with redacted diagnostics export plus `Copy support summary` so current version, scan counts, safety toggles, scan roots, ZFS state, notices, and quarantine totals can be shared quickly in issue reports and forum posts - UX: Add a dedicated `Scan summary` panel, richer empty-state guidance, per-row `Details` dialogs, saved view presets, and bulk selection presets for ready rows, discovery-only rows, ZFS-backed rows, and rows older than 90 days - UI: Refine the dashboard controls by removing the extra search preset row, flattening and polishing the bottom-bar preset control, and surfacing clearer inline blocker badges for ZFS delete disabled, permanent delete mode disabled, mapped-but-nonexact ZFS paths, and generic policy locks - ZFS: Expand row-level ZFS guidance with matched share-root and dataset-root context, checked dataset-side paths, and on-demand destroy previews that surface recursive impact, child datasets, and snapshots directly in row details - Fix: Reduce large-scan WebUI hangs and gateway timeouts by keeping the initial scan request focused on orphan discovery, deferring audit-history and quarantine-summary loading until after the scan renders, and indexing nested reference checks so filesystem discovery no longer walks every template and live mount for every candidate folder ###2026.04.23.01 - Release: Promote the full `2026.04.13.04` through `2026.04.23.01` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Support: Add a `Tools` workflow with redacted diagnostics export plus `Copy support summary` so current version, scan counts, safety toggles, scan roots, ZFS state, notices, and quarantine totals can be shared quickly in issue reports and forum posts - UX: Add a dedicated `Scan summary` panel, richer empty-state guidance, per-row `Details` dialogs, saved view presets, and bulk selection presets for ready rows, discovery-only rows, ZFS-backed rows, and rows older than 90 days - UI: Refine the dashboard controls by removing the extra search preset row, flattening and polishing the bottom-bar preset control, and surfacing clearer inline blocker badges for ZFS delete disabled, permanent delete mode disabled, mapped-but-nonexact ZFS paths, and generic policy locks - ZFS: Expand row-level ZFS guidance with matched share-root and dataset-root context, checked dataset-side paths, and on-demand destroy previews that surface recursive impact, child datasets, and snapshots directly in row details - Fix: Reduce large-scan WebUI hangs and gateway timeouts by keeping the initial scan request focused on orphan discovery, deferring audit-history and quarantine-summary loading until after the scan renders, and indexing nested reference checks so filesystem discovery no longer walks every template and live mount for every candidate folder ###2026.04.13.11 - Support: Add `Copy support summary` under `Tools` so the current version, scan counts, safety toggles, scan roots, ZFS state, notices, and quarantine totals can be copied into forum posts quickly - UX: Surface more row-level blocker context inline by adding badges for ZFS delete disabled, permanent delete mode disabled, generic policy locks, and mapped-but-nonexact ZFS paths ###2026.04.13.10 - Support: Add `Copy support summary` under `Tools` so the current version, scan counts, safety toggles, scan roots, ZFS state, notices, and quarantine totals can be copied into forum posts quickly - UX: Surface more row-level blocker context inline by adding badges for ZFS delete disabled, permanent delete mode disabled, generic policy locks, and mapped-but-nonexact ZFS paths ###2026.04.13.09 - UX: Polish row details with clearer outcome and next-step explanations for locked, review, ignored, ZFS-backed, and manually unlocked rows - ZFS: Add row-level resolution context for mapped-but-nonexact paths, including the matched share root, matched dataset root, and checked dataset-side paths - ZFS: Load the current ZFS destroy preview into row details on demand so recursive destroy mode, impact summaries, child datasets, and snapshots are visible without running a delete preview first - ZFS: Suggest likely ZFS path mappings in the mappings modal by inferring dataset roots from detected ZFS mountpoints under the effective scan roots and keep the root labels explicit as `Unraid share root` and `ZFS dataset mount root` ###2026.04.13.07 - UI: Remove the extra search-panel preset row so the bottom action bar remains the only preset control in the dashboard ###2026.04.13.06 - UI: Align the bottom-bar selection preset control with the adjacent action buttons by flattening the field treatment in that bar - UX: Remove the inert `Preset` placeholder from the selection preset menu and default the control to `Ready rows` ###2026.04.13.05 - Usability: Add bulk selection presets in the bottom action bar for ready rows, discovery-only rows, ZFS-backed rows, and rows older than 90 days - Usability: Add saved view presets in the filter panel so the current search term, risk filter, ignored visibility, badge filter, and sort order can be reused later from the same browser - UX: Strengthen the empty-state guidance so zero-result scans explain which appdata roots were checked, whether Docker templates were part of the scan, and what to verify next ###2026.04.13.04 - Support: Add a `Tools` action with one-click diagnostics export so users can download the current scan state, safety settings, source roots, notices, quarantine summary, audit history, and row metadata for troubleshooting - UX: Add a dedicated `Scan summary` panel that surfaces current scan-root coverage plus template, discovery, review, locked, ZFS-backed, mapped-share, and ignored row counts without needing to infer them from the grouped results - UX: Add per-row `Details` dialogs so each orphaned path can explain its current path, canonical path, source evidence, safety state, storage metadata, and key stats before the user decides what to do - Privacy: Redact diagnostics by default so exported app names, template filenames, and filesystem paths are replaced with stable aliases while preserving enough structure for support review - Privacy: Extend diagnostics redaction to cover exported target paths and audit-summary text that only references app names or paths from audit entries - Fix: Populate the diagnostics plugin version from the installed plugin manifest instead of leaving the exported `pluginVersion` field blank ###2026.04.13.02 - Release: Promote the full `2026.04.09.02` through `2026.04.13.01` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Feature: Add ZFS-backed appdata cleanup with exact dataset mountpoint resolution, case-sensitive dataset handling, dataset-aware permanent delete using `zfs destroy`, and recursive destroy support only when required - UI: Add a dedicated `ZFS mappings` workflow, hide it until ZFS dataset delete is enabled, clarify the share-root versus dataset-root setup, and prevent incomplete or unsaved mapping drafts from being mistaken as saved configuration - UX: Improve ZFS delete wording and confirmation flows so dataset-backed rows describe destroy behavior clearly, surface recursive impact summaries, and show child datasets and snapshots directly in the delete preview and results modals - Safety: Keep ZFS-backed rows behind both the ZFS dataset delete toggle and permanent delete mode while continuing to block quarantine for dataset-backed paths - Fix: Harden the quarantine action response path by releasing the PHP session lock before long-running actions and avoiding expensive uncached quarantine size scans in lightweight post-action summary responses - Docs and test: Refresh the README for ZFS-backed appdata support and extend the behavior smoke coverage for ZFS dataset resolution, recursive destroy metadata, quarantine response-path hardening, and the refined ZFS workflow ###2026.04.13.01 - Maintenance: Refresh package metadata and build artifacts ###2026.04.10.03 - Maintenance: Refresh package metadata and build artifacts ###2026.04.10.02 - Maintenance: Refresh package metadata and build artifacts ###2026.04.10.01 - Maintenance: Refresh package metadata and build artifacts ###2026.04.09.03 - Maintenance: Refresh package metadata and build artifacts ###2026.04.09.02 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.10 - Release: Promote the `2026.04.07.09` development build to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Discovery: Surface empty direct-child parent folders left behind after nested appdata mount paths are removed, instead of hiding them forever behind stale nested template or live-path references - Safety: Keep direct-child parents hidden when a real nested appdata descendant still exists, and keep non-empty stale parents hidden in this first safe pass - Test: Extend the behavior smoke coverage for active nested mounts, empty stale parents, and non-empty stale parent remnants ###2026.04.07.09 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.08 - Release: Promote the full `2026.04.07.01` through `2026.04.07.07` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Feature: Add an `Appdata sources` action-bar workflow for non-standard Docker appdata roots so extra mount locations can be saved and scanned beside the auto-detected Docker appdata path - Scan and match: Treat configured manual appdata roots as first-class discovery sources and normalize share-like aliases such as `/mnt/user/...` versus pool or disk-backed paths to suppress false orphan results from alternate mounts - Safety: Add scan-scoped unlock and relock controls for outside-share review rows while keeping hard locks non-bypassable and server-side action validation intact - UI: Replace manual source text entry with a browseable folder picker that supports current-path navigation, parent-directory stepping, and a tighter Unraid-style list layout for selecting appdata roots ###2026.04.07.07 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.06 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.05 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.04 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.03 - Maintenance: Refresh package metadata and build artifacts ###2026.04.07.02 - Feature: Add an action-bar lock override control for outside-share review rows using scan-scoped unlock and relock state - Safety: Keep hard locks non-bypassable while allowing manually unlocked review rows to stay actionable for the active scan only ###2026.04.07.01 - Feature: Add an `Appdata sources` action-bar button with a modal for saving manual appdata source roots used by non-standard Docker mounts - Scan: Treat configured manual appdata roots as first-class discovery sources so direct-child orphan scans can run outside the single auto-detected Docker appdata share - Match: Normalize share-like mount aliases such as `/mnt/user/...` and pool or disk-backed paths when comparing template, discovery, and live-container host paths to suppress false orphan rows - Safety: Treat paths inside configured manual appdata sources as normal inside-source candidates for hydration, quarantine, and action validation instead of forcing them into outside-share review mode - Test: Extend the behavior smoke regression for manual source persistence, manual-root discovery, and alias-mount live-container matching ###2026.04.01.24 - Release: Promote the `2026.04.01.23` development build to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Quarantine: Recover tracked quarantine entries from folders already on disk when `quarantine-records.json` is missing after reinstalling the plugin or switching between `dev` and `main` - Quarantine: Rebuild the registry from known quarantine roots before the manager payload is loaded so recovered entries can be viewed, restored, purged, and counted again - Quarantine: Write an on-disk entry marker inside newly quarantined folders so recovery preserves the exact original source path and metadata even if plugin state is lost later - Quarantine: Fall back to conservative layout-based recovery for older quarantine folders that predate the new on-disk marker file - Restore: Remove the on-disk recovery marker after restore so it does not leak back into the restored appdata folder - Test: Cover marker-backed recovery, legacy layout recovery, deduped repeated manager loads, and restore/purge behavior on recovered entries ###2026.04.01.23 - Quarantine: Recover tracked quarantine entries from folders already on disk when `quarantine-records.json` is missing after reinstalling the plugin or switching between `dev` and `main` - Quarantine: Rebuild the registry from known quarantine roots before the manager payload is loaded so recovered entries can be viewed, restored, purged, and included in the summary count again - Quarantine: Write an on-disk entry marker inside newly quarantined folders so future recovery preserves the exact original source path and metadata even if plugin state is lost - Quarantine: Fall back to conservative layout-based recovery for older quarantine folders that predate the new marker file - Restore: Remove the on-disk recovery marker after a quarantined folder is restored so it does not leak back into the restored appdata folder - Test: Cover exact marker-backed recovery after deleting the registry/settings files, legacy path-based recovery for older quarantine folders, deduped repeated manager loads, and restore/purge behavior on recovered entries ###2026.04.01.22 - Release: Promote the full `2026.04.01.10` through `2026.04.01.21` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Quarantine UI: Render the exact scheduled purge timestamp as its own colored, outlined badge beside the relative purge timer badge so pending permanent deletion is more obvious at a glance - Quarantine: Persist a configurable `Default purge in days` setting, automatically apply that timer to newly quarantined folders, and let selected tracked entries be overridden with an exact `Set purge at` date/time - Quarantine: When the default purge timer changes, immediately reschedule existing default-managed entries and refresh the open quarantine manager so badges and scheduled purge timestamps update without a manual reload - Quarantine safety: Recalculate default-managed purge timers from each entry's original quarantine timestamp instead of restarting them from the moment the default changes, while preserving manual per-entry exact-time overrides and legacy schedules that do not match the previous default - Fix: Correct the quarantine purge-schedule API field mismatch that caused `Set purge` to fail, while keeping the temporary legacy request key compatible internally - UI: Regroup the quarantine manager toolbar so purge scheduling controls stay on the left, bulk actions stay on the right, and the action buttons align cleanly with the purge input fields - UI: Remove the unused bottom action-bar `Done` button and fix the stale action-bar reference that could leave the dashboard stuck on the initial scan screen after the button was removed - UI: Make the audit history popup use the same wide modal sizing as the quarantine manager so both review windows share the same footprint - UI: Unify dashboard and quarantine-manager button styling, keep the orange-accent text on modal secondary actions, and add a clearly visible thin black outline that remains visible at rest instead of only reading as outlined once hover changes the fill ###2026.04.01.21 - UI: Strengthen the shared button stroke so dashboard and quarantine-manager buttons show a clearly visible thin black outline at rest instead of only reading as outlined once hover changes the fill ###2026.04.01.20 - UI: Remove the modal-only `.acp-button` styling override so quarantine-manager action buttons inherit the exact same button styling path as the dashboard buttons, while SweetAlert confirm/cancel buttons keep their dedicated modal styling ###2026.04.01.19 - UI: Keep the orange-accent text on secondary action buttons inside the plugin modals while preserving the new thin black outline styling ###2026.04.01.18 - UI: Apply the thin black button outline and forced button chrome to inline action buttons inside the SweetAlert-based plugin modals so quarantine-manager controls render with the same outlined button style ###2026.04.01.17 - UI: Fix the thin black button outline so it actually renders on normal plugin buttons by overriding the earlier box-shadow reset, and strengthen the outline slightly for clearer contrast ###2026.04.01.16 - UI: Add a thin black outer outline to the plugin button style so normal actions and modal confirm/cancel buttons read more clearly against the panel backgrounds ###2026.04.01.15 - Quarantine: Recalculate default purge schedules from each entry's original quarantine timestamp instead of restarting every existing entry from the moment the global default changes - Quarantine: Preserve manual per-entry `Set purge at` overrides when the global default purge timer changes, and keep legacy scheduled entries that do not match the previous default from being overwritten - Cleanup: Remove the no-op `purgeAfterDays: 0` post from the exact-time scheduling UI path and drop the redundant early quarantine-selection disabled assignment in the modal renderer ###2026.04.01.14 - UI: Nudge the quarantine toolbar action buttons down slightly on desktop so they sit centered against the purge input boxes without affecting the stacked mobile layout ###2026.04.01.13 - Quarantine: Changing `Default purge in days` now reschedules existing tracked quarantine entries immediately instead of only affecting newly quarantined folders - Quarantine UI: Keep the modal state in sync after default purge changes so badges and scheduled purge timestamps refresh without a manual reload - UI: Regroup the quarantine toolbar into left-side schedule controls and right-side bulk action buttons, and bottom-align the action buttons with the schedule inputs for cleaner alignment ###2026.04.01.12 - Quarantine: Persist a configurable `Default purge in days` safety setting and automatically apply that timer when new folders are moved into quarantine - Quarantine UI: Split the old day-based toolbar control into a saved default purge-days input plus a separate `Set purge at` date/time override for selected quarantined items - Restore/Quarantine UX: Leave the exact-time purge override blank when no default timer is configured, instead of pre-filling an unsafe immediate purge time - API: Accept exact purge timestamps for selected-entry scheduling while keeping the older day-based scheduling path compatible internally - Test: Cover safety-setting persistence for default purge days, exact-time purge scheduling, and default-timer inheritance on new quarantine records ###2026.04.01.11 - UI: Add colored outlines to modal status badges so the scheduled purge timestamp badge reads as a clearer pill beside the relative purge timer badge ###2026.04.01.10 - Quarantine UI: Move the exact scheduled purge timestamp out of the plain meta line and render it as its own colored badge beside the relative purge timer badge for better visual visibility ###2026.04.01.09 - Release: Promote the full `2026.04.01.03` through `2026.04.01.08` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Restore: Let quarantine restore conflicts use per-folder edited restore names instead of only generated suffix paths, validate edited names server-side, and report edited restore destinations back in the restore results summary - UX: Show the fixed restore parent path, editable restore name, and a live edited restore-path preview in the quarantine restore-conflict dialog before restore runs - Scan: Read the configured Docker image storage path from `docker.cfg` and exclude Docker-managed storage roots from orphan detection and action execution, and exclude `lost+found` alongside `.Recycle.Bin` from direct-child appdata discovery - Quarantine: Add per-entry scheduled purge timers so selected quarantine entries can be set to purge after a chosen number of days - Quarantine: Sweep expired scheduled purge timers automatically when quarantine state is loaded, using the normal purge path and recording scheduled purges in audit history - Quarantine UI: Add bulk `Purge in days`, `Set purge`, and `Clear purge timer` controls to the quarantine manager toolbar, plus visible scheduled-purge badges and exact scheduled purge timestamps on quarantined entries - Fix: Send the scheduled-purge action with the correct API field name and accept both the temporary `mode` key and the final `purgeScheduleMode` key for compatibility - UI: Remove the unused bottom action-bar `Done` button and the now-unused close-page wiring from the dashboard script - Fix: Remove the last stale `els.$doneBottom` action-bar reference so the dashboard no longer crashes during initial scan load after the bottom `Done` button removal - UI: Make the audit history popup use the same wide modal sizing as the quarantine manager so both review windows have matching width and height - Test: Extend the behavior smoke coverage for edited restore names, invalid edited names, Docker-managed path exclusion, `lost+found` exclusion, scheduled purge set/clear/expire flows, and the audit label path for scheduled purge actions ###2026.04.01.08 - UI: Make the audit history popup use the same wide modal sizing as the quarantine manager so both review windows have matching width and height ###2026.04.01.07 - Fix: Remove the last stale `els.$doneBottom` reference from the dashboard action-bar refresh logic so the page no longer crashes during initial scan load after the bottom `Done` button removal ###2026.04.01.06 - UI: Remove the unused `Done` button from the bottom action bar so only meaningful selection and cleanup actions remain - Cleanup: Drop the now-unused close-page button wiring from the dashboard script ###2026.04.01.05 - Fix: Send the scheduled-purge action using the correct API field name so `Set purge` no longer fails immediately in the quarantine manager - Compatibility: Let the backend accept both the old temporary `mode` key and the final `purgeScheduleMode` key for quarantine purge schedule updates ###2026.04.01.04 - Quarantine: Add per-entry scheduled purge timers so selected quarantine records can be marked for purge in a chosen number of days - Quarantine: Sweep due scheduled purges automatically when quarantine state is loaded, using the normal purge path and recording scheduled purges in audit history - Quarantine UI: Add bulk `Purge in days`, `Set purge`, and `Clear purge timer` controls to the quarantine manager toolbar - Quarantine UI: Show scheduled purge badges and exact scheduled purge timestamps on quarantined entries so pending permanent deletion is visible at a glance - Audit: Label scheduled auto-purge history entries as `Scheduled purge` instead of showing the raw internal operation key - Test: Cover setting, clearing, and expiring quarantine purge schedules in the behavior smoke suite ###2026.04.01.03 - Restore: Let the quarantine restore-conflict dialog accept per-folder edited restore names instead of only offering a generated suffix - Safety: Validate edited restore names server-side, reject invalid names cleanly, and report edited restore destinations back in the restore results summary - UX: Show the fixed parent path, editable restore name, and live edited restore-path preview in the quarantine conflict dialog before restore runs - Scan: Read the configured Docker image storage path from `docker.cfg` and exclude Docker-managed storage roots from orphan detection and action execution - Scan: Exclude `lost+found` alongside `.Recycle.Bin` from direct-child appdata discovery so obvious system metadata folders do not surface as orphaned appdata candidates - Test: Cover edited restore-name restores, invalid edited names, Docker-managed path exclusion, and `lost+found` exclusion in the behavior smoke regression ###2026.04.01.02 - Release: Promote the `2026.04.01.01` development build to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Fix: Allow inside-share appdata rows to remain actionable when the configured appdata root itself is intentionally symlinked - Safety: Keep direct folder symlinks and deeper nested symlink segments locked, so the symlink exemption only applies to the configured appdata share root - Scan: Exclude `.Recycle.Bin` from direct-child appdata share discovery so recycle metadata does not surface as an orphaned appdata folder - Docs: Refresh the README with current install, update, safety, quarantine, development, and support guidance, plus repo badges and issue-form support flow - Maintainer: Carry the GitHub issue forms and the explicit branch-ref release verification improvements into the stable branch metadata ###2026.04.01.01 - Fix: Treat the configured appdata share root symlink as an allowed path segment so inside-share rows do not get hard-locked when the appdata root itself is intentionally symlinked - Safety: Keep direct folder symlinks and deeper nested symlink segments locked, so only the configured appdata root symlink exemption is allowed - Scan: Exclude `.Recycle.Bin` from direct-child appdata share discovery so recycle metadata does not surface as an orphaned appdata folder - Test: Cover symlinked appdata share roots and `.Recycle.Bin` discovery exclusion in the behavior smoke regression ###2026.03.31.18 - Release: Promote the full `2026.03.31.12` through `2026.03.31.17` development cycle to the stable `main` channel while keeping the manifest, CA feed, and package metadata pointed at `main` - Feature: Add quarantine restore collision handling with `Skip conflicts`, `Restore with suffix`, and `Review conflict`, plus explicit conflict and skipped restore results - Scan: Render orphan rows first with lightweight metadata, then hydrate size data progressively in background batches so larger appdata scans become interactive faster - UX: Rework result badges into ordered actionability, state, source, and reason pills with filtering, then restore the previous filled-pill look while tuning `Locked` and `Discovery` colors for clearer visual meaning - Safety: Read VM Manager storage paths from `domain.cfg`, automatically exclude configured vdisk, ISO, and libvirt locations from orphan detection, and block cleanup actions that target VM-managed paths - Maintainer: Strengthen the release flow with raw manifest/XML verification, exact cache-busting install output, and a fixed `main` to `dev` back-merge so future stable releases keep the required branch ancestry intact ###2026.03.31.17 - Fix: Read VM Manager default storage paths from `domain.cfg` and automatically exclude configured vdisk, ISO, and libvirt locations from orphan detection - Safety: Block cleanup actions for VM-managed paths even if a stale snapshot or unusual candidate path reaches the execution layer - Test: Cover VM domains, VM ISOs, libvirt-under-appdata parents, and template-backed paths inside VM storage in the behavior smoke regression ###2026.03.31.16 - Tweak: Give `Locked` badges a stronger stop color and `Discovery` badges a distinct blue source color while keeping `Template` neutral ###2026.03.31.15 - Fix: Render clickable badges as badge-styled spans instead of host-styled buttons so the row badges keep the previous filled-pill look while remaining filterable - Accessibility: Allow badge filters to activate from keyboard with `Enter` or `Space` ###2026.03.31.14 - Fix: Restore the older filled-pill badge look for scan rows and section summaries so the new badge system no longer renders like outlined action buttons - Tweak: Keep badge filtering active states subtle while preserving the new `Ready`, `Locked`, source, and reason badges ###2026.03.31.13 - UX: Rework result badges into ordered actionability, state, source, and reason badges so rows read clearly at a glance without mixing status and safety - UX: Add clickable badge filters, active badge-filter feedback, section header count badges, and tooltips so badges are functional instead of decorative - Tweak: Rename `Safe` row states to `Ready` and `Blocked` row states to `Locked` across the scan UI and result summaries for clearer wording ###2026.03.31.12 - Feature: Add restore collision handling in the quarantine manager so existing original paths trigger a conflict flow instead of a dead-end restore failure - UX: Show a restore conflict dialog with `Skip conflicts`, `Restore with suffix`, and `Review conflict` options, plus explicit conflict and skipped result states in restore results and audit history - Scan: Load orphan rows first with lightweight stats, then hydrate size metadata progressively from the secure scan snapshot in background batches so large appdata scans feel faster - Maintainer: Add `bash scripts/release_main.sh` on `dev` to merge `dev` into `main`, build the release, tag it, publish GitHub release notes, verify the live raw manifest and CA XML, sync `dev`, and print the exact cache-busting install command ###2026.03.31.11 - Feature: Add a `Select all` button to the main bottom action bar for selecting every deletable scan result - Feature: Add a `Select all` button to the quarantine manager toolbar for bulk restore and purge workflows ###2026.03.31.10 - Fix: Restore true centered positioning for SweetAlert confirmation and utility dialogs after the wider modal overrides - Fix: Reset modal `margin-top` and use full `translate(-50%, -50%)` centering so tall confirm dialogs do not open cut off near the bottom of the screen ###2026.03.31.09 - Fix: Replace fragile `min(...)` modal sizing with explicit width/max-width overrides so the quarantine manager can actually expand horizontally - Fix: Force SweetAlert modal centering with explicit left/right/margin handling when wider widths are applied ###2026.03.31.08 - Fix: Stop reopening the quarantine manager after a successful restore or purge result dialog is dismissed ###2026.03.31.07 - Tweak: Expand the quarantine manager horizontally to use more of the available viewport width - Tweak: Trim modal and panel side padding so quarantined path cards get more usable horizontal space ###2026.03.31.06 - Tweak: Reduce the quarantine manager width from the oversized layout while keeping the taller review area - Fix: Vertically align quarantine entry names with their checkboxes and action row ###2026.03.31.05 - Fix: Restore page scrolling correctly after quarantine restore and purge modal flows close - Improvement: Expand the quarantine manager width and internal list height so more quarantined path details stay visible without cramped wrapping - Fix: Clear modal-specific SweetAlert classes cleanly when switching between quarantine, audit, and other modal views ###2026.03.31.04 - Fix: Reopen the quarantine manager reliably after restore and purge actions instead of getting stuck until a full page refresh - Feature: Add quarantine entry checkboxes with bulk restore and bulk purge actions - Fix: Allow permanent-delete and outside-share safety toggles to save even when the current scan is empty ###2026.03.31.03 - Fix: Canonicalize host paths before matching saved template references against live container mounts so trailing slashes cannot create false orphan rows - Test: Cover saved-template trailing slash mismatches against live Docker mount paths in the behavior smoke regression ###2026.03.31.02 - UX: Split one scan into grouped result sections for saved template references, appdata share discovery, and ignored paths - UX: Keep filtering, sorting, and selection global while sorting rows within each visible result section ###2026.03.31.01 - UX: Explain locked symlink candidates with the exact offending path segment instead of a generic safety warning - Scan: Detect direct child orphan folders in the configured appdata share even when no saved Docker template still references them ###2026.03.30.34 - UX: Pin the stacked Controls buttons to the top-right of the panel instead of letting the action column float - UX: Render the desktop Controls buttons as a tight grid stack so no vertical spacing is introduced by flex layout ###2026.03.30.33 - UX: Shorten the Search panel another step on desktop so the Controls panel gets more breathing room - UX: Remove the gap between the stacked Controls buttons so the action column reads as one tight group ###2026.03.30.32 - UX: Shorten the Search panel width and widen the Controls panel so the safety labels fit cleanly on desktop - UX: Give the stacked action buttons a fixed right-side column so the Controls panel reads cleanly instead of collapsing ###2026.03.30.31 - UX: Move the visible and detected results count into the Sort panel and keep the Controls panel focused on actions and safety toggles - UX: Narrow the Controls panel and stack Rescan, Select visible, and Clear vertically on the right side of the panel ###2026.03.30.30 - UX: Split the former combined sort/control block into a dedicated Sort panel plus a separate Controls panel to its right - UX: Keep the sort panel compact while moving the action buttons, safety toggles, and results meta into their own panel ###2026.03.30.29 - UX: Stop stretching the summary cards and top toolbar panels to the tallest neighbor so the top row returns to its compact height - UX: Keep the search and sort panels sized to their own content instead of inheriting extra height from the adjacent panel ###2026.03.30.28 - UX: Restore the previous compact top-row height by removing the stretched sort-panel row behavior - UX: Align the Rescan, Select visible, and Clear buttons to the sort select control instead of the full labeled field ###2026.03.30.27 - UX: Push the safety toggles lower in the sort panel so they sit bottom-left with clear separation from the order control - UX: Vertically center the Rescan, Select visible, and Clear buttons against the sort dropdown and center that button row on desktop ###2026.03.30.26 - UX: Stack the safety toggles so Enable permanent delete sits directly under Allow outside-share cleanup - UX: Keep the sort order control and toolbar action buttons on one desktop row, with stacked fallback on narrow layouts ###2026.03.30.25 - Maintenance: Remove dead latest-audit payload/state and the unused server-side notices payload after the notice bar refactor - Maintenance: Remove empty audit/quarantine panel plumbing, stale strings, and the leftover empty quarantine panel container from the page shell ###2026.03.30.24 - UX: Restore actions now add the candidate back into the detected list live instead of waiting for a manual rescan - UX: Restore actions now return an updated secure snapshot token so restored rows stay actionable without reloading the plugin ###2026.03.30.23 - UX: Keep quarantine and delete actions live in the current results list instead of forcing a full scan refresh after success - UX: Update the action bar quarantine summary from persisted size data so tracked quarantine storage no longer sticks at 0 B ###2026.03.30.22 - UX: Remove the inline Last cleanup notice now that audit history is available from the action bar - UX: Keep ignore and restore actions live in the current results set instead of forcing a full rescan after each row change ###2026.03.30.21 - Maintenance: Refresh package metadata and build artifacts ###2026.03.30.20 - UX: Limit the summary-tile glow effect to nonzero values so empty stats stay visually quiet while active stats still pick up their tone color - UX: Center the detected-row copy block vertically inside each orphan card so the title, metadata, and reason sit more evenly beside the checkbox and actions - Fix: Hide SweetAlert's built-in info icon chrome for the quarantine and audit popups so the custom modal content stops artifacting behind the manager surface ###2026.03.30.19 - UX: Add a color-matched glow to the summary-card values so each number picks up the same tone family as its status dot - UX: Rename the top utility launcher to Action bar, move Show history into it beside Show quarantine, and remove the old inline audit-history card - UX: Open audit history in the same popup style as the quarantine manager, with a wider scrollable modal for longer history lists ###2026.03.30.17 - Fix: Hide SweetAlert's base body text whenever the quarantine manager injects custom modal content so stale text no longer bleeds through during refresh - UX: Remove the duplicate in-body quarantine manager title so refreshing the manager updates a single clean modal surface instead of echoing the title inside the content host ###2026.03.30.16 - UX: Flatten panel backgrounds across every host theme so dashboard cards use plain solid surfaces instead of gradient fades - UX: Remove the extra accent fade overlays from the hero banner, quarantine manager launcher card, and sticky action bar so they match the rest of the panel chrome ###2026.03.30.15 - Fix: Restore detected-folder size measurement on uncached scans and write measured bytes back into the stats cache so rows stop showing Unknown by default - UX: Keep ORPHANED and SAFE badges to the left of the path chip in one non-wrapping desktop row instead of collapsing the badges into a vertical stack ###2026.03.30.14 - UX: Move detected-card descriptions directly under the metadata line so the right-side action stack no longer creates a blank vertical gap - UX: Keep the detected-card path chip and ORPHANED or SAFE badges in one shared header row on desktop, with responsive wrapping only on narrower layouts ###2026.03.30.12 - UX: Tighten the top mode and audit cards again with shorter chrome, smaller action buttons, and less internal padding - UX: Compress result-row spacing so orphan cards read denser with less vertical padding between title, metadata, notes, and action chips ###2026.03.30.11 - Maintenance: Refresh package metadata and build artifacts ###2026.03.30.10 - Fix: Rename the helper INI parser shims to plugin-scoped function names so scan requests stop fatally colliding with other globally declared `my_parse_ini_*` helpers in the Unraid PHP runtime ###2026.03.30.09 - Fix: Replace the quarantine manager modal host paragraph with a block container so refreshes stop stacking duplicate content into the SweetAlert body - Fix: Stop live recursive folder-size walks during scan so orphan discovery no longer risks timing out or fatally dying on large appdata trees - Debug: Return JSON from fatal backend shutdowns so future scan failures expose the actual PHP fatal message instead of a blank HTTP 500 ###2026.03.30.08 - Fix: Keep the quarantine manager inside a single SweetAlert instance so refresh updates the current modal instead of reopening and duplicating the content block - Fix: Return dashboard results in read-only mode when snapshot persistence fails so scan output can still render instead of aborting the whole request - UX: Surface plain-text backend response details when exec returns non-JSON output so future scan failures are diagnosable from the page ###2026.03.30.07 - Fix: Keep exec responses valid JSON by buffering and discarding stray backend output, and suppress Docker manager warnings so scan requests stop failing on noisy DockerClient calls - Fix: Normalize installed-container volume data before orphan filtering so scan requests survive object-shaped Docker metadata - UX: Rework the SweetAlert modal host injection so refreshing the quarantine manager rewrites the active modal instead of duplicating its contents ###2026.03.30.06 - Fix: Stop loading Unraid's Docker client at file import time so a Docker manager include failure cannot abort scan or quarantine requests before the API responds - Test: Add a behavior smoke regression that forces the Docker client include to fail and verifies the dashboard still builds ###2026.03.30.05 - Fix: Harden scan responses against missing Docker config text, invalid UTF-8 path data, malformed template entries, and per-candidate scan exceptions so one bad input no longer aborts the whole scan - UX: Move the quarantine manager out of the page body and into a dedicated popup window launched from the split mode bar ###2026.03.30.04 - Fix: Accept proxied forwarded hosts and catch Docker client failures so scan requests stop failing on reverse-proxied or transient Docker states - UX: Collapse the quarantine manager until it is opened and tighten the new utility card spacing so the dashboard stays close to the previous compact height ###2026.03.30.03 - UX: Split the mode banner into safe/delete status and a quarantine manager launcher, add a full audit history panel, and surface tracked quarantine entries with restore or purge actions - Safety: Scope action snapshots to the active session, track quarantine records explicitly, and keep cached path stats so large appdata trees re-scan faster without trusting stale ids - Maintenance: Split the exec backend and dashboard frontend into smaller modules, add local behavior smoke tests, and make plugin state storage overrideable for automated testing ###2026.03.30.02 - Security: Remove the unused XML helper, stop depending on Community Applications helper code, tighten internal directory creation to `0755`, and reject non-POST or cross-host exec requests - Safety: Require typed confirmation for every permanent delete action, not just outside-share deletes - Compatibility: Parse Docker template XML locally so scans no longer depend on CA runtime helpers ###2026.03.30.01 - Security: Remove the unused XML helper, drop the Community Applications helper dependency, tighten internal directory permissions, and require same-host POST requests for exec actions - Safety: Require typed confirmation for every permanent delete instead of only outside-share delete paths - UX: Add explicit installed-plugin titles for the main and dev README descriptions shown in Unraid ###2026.03.27.24 - Fix: Replace the incorrect Community Applications conflict abort with a real CA helper dependency check so fresh installs can place the plugin in Unraid Settings again - Fix: Mark the settings page as `Type="xmenu"` so the Settings menu entry follows the same explicit page mode used by other modern plugins ###2026.03.27.23 - Release: First Appdata Cleanup Plus release for Unraid 7.0.0+ with a modern, theme-aware dashboard for reviewing orphaned Docker appdata folders - UX: Add compact search, sorting, risk filtering, summary stats, size and last-updated metadata, detailed flag reasons, and ignore or restore controls for surfaced paths - Safety: Default real actions to quarantine, add dry run support, gate outside-share cleanup and permanent delete behind explicit toggles, and use clearer warning and confirmation dialogs - Security: Execute actions from server-side scan snapshots with candidate ids, require CSRF validation, enforce canonical path and target checks, and block unsafe roots, symlinks, and mount points - Platform: Ship custom plugin branding, branch-aware main and dev feeds, Unraid-friendly versioning, cleanup audit logging, and theme support for Black, Azure, Gray, and White ###2026.03.27.22 - Maintenance: Refresh package metadata and build artifacts ###2026.03.27.21 - Maintenance: Refresh package metadata and build artifacts ###2026.03.27.20 - Maintenance: Refresh package metadata and build artifacts ###2026.03.27.19 - Maintenance: Refresh package metadata and build artifacts ###2026.03.27.18 - UX: Add folder size, last-updated metadata, richer template-to-target flag reasons, and compact ignore or restore actions directly in the cleanup list - UX: Add a Show ignored toggle plus clearer result and empty-state messaging when candidates are hidden by the ignore list - Safety: Persist ignored paths and write a cleanup audit trail under the plugin config directory, then surface the latest cleanup summary back in the dashboard ###2026.03.27.17 - Fix: Copy the active ACP theme tokens onto SweetAlert at runtime so the delete and results popups render a real themed background instead of falling through to the page - UX: Harden the popup shell chrome with explicit card sizing, borders, icon styling, and button styling so the delete dialog reads like a proper modal ###2026.03.27.16 - UX: Rebuild the delete confirmation popup with a real warning badge, clearer irreversible-action copy, summary chips, and a boxed folder review list - UX: Unify the normal delete and typed-confirm review flows so higher-risk deletes use the same warning layout with a stronger review-required callout ###2026.03.27.15 - Maintenance: Remove legacy source comments from the packaged helper files and old manifest comment blocks while keeping the release changelog structure intact - UX: Make the orphan-list checkboxes smaller and centered in the left column for faster scanning and cleaner alignment ###2026.03.27.14 - Compatibility: Raise the supported Unraid minimum version to 7.0.0+ in both the plugin manifest and CA metadata ###2026.03.27.13 - Fix: Export the active Unraid host theme from the PHP page shell and stamp explicit host-theme attributes like FolderView Plus so White mode no longer falls back to dark tokens - UX: Keep summary values centered in the stat tiles while theme classification now uses host-theme attributes first and luminance fallback second ###2026.03.27.12 - UX: Center the stat values within each summary tile while keeping the labels anchored at the top - UX: Detect the active Unraid theme at runtime and apply the matching White, Azure, Gray, or Black token palette reliably ###2026.03.27.11 - UX: Lock the top stat tile values to a shared baseline so wrapped labels no longer shift the numbers - UX: Rebuild the sort panel layout so the order dropdown, actions, and result count align cleanly at the same card height as search ###2026.03.27.10 - UX: Shrink the top stat tiles into a compact left-aligned cluster instead of full-width cards - UX: Split the old combined toolbar into separate Search and Sort panels positioned beside the stat tiles - UX: Replace the header risk buttons with a dropdown so the top control area stays compact ###2026.03.27.09 - UX: Add a theme token system with explicit Black, Azure, Gray, and White Dynamix theme palettes - UX: Keep the compact dashboard layout while adapting contrast, panels, buttons, badges, and path chips to the active Unraid theme ###2026.03.27.08 - UX: Remove the top-right Done button and compress the dashboard spacing across the header, stats, toolbar, and sticky action bar - UX: Replace tall orphan cards with a compact row list so folders can be scanned and selected much faster - UX: Hard-reset button and filter styling to stop hover artifacts from inherited Unraid button effects ###2026.03.27.07 - UX: Tighten the dashboard spacing so cards, controls, and orphan rows take less vertical space - UX: Remove button hover motion and switch to a stable highlight so hover outlines do not jitter ###2026.03.27.06 - UX: Replace the legacy settings page with a modern cleanup dashboard, summary cards, filters, and a sticky action bar - Safety: Move scan/delete responses to JSON, keep dangerous root-level paths locked, and require typed confirmation for outside-share deletes - Maintenance: Split the frontend into dedicated JS/CSS assets and remove leftover debug behavior from the helper layer ###2026.03.27.05 - UX: Remove the top warning banner from the settings page - UX: Remove the Credits link, support footer, and plugin version footer from the settings page ###2026.03.27.04 - UX: Shorten the installed plugin description so it states exactly what the plugin does - UX: Show a clear testing-channel note on dev builds while keeping main descriptions clean ###2026.03.27.03 - Maintenance: Refresh package metadata and build artifacts ###2026.03.27.02 - Docs: Add install, update, and release basics to the repository and bundled plugin README files - Maintenance: Add branch-aware CA metadata plus Unraid-friendly YYYY.MM.DD.UU package versioning for main and dev channels ###2026.03.27 - Renamed the plugin to Appdata Cleanup Plus - Moved package metadata and update feeds to alexphillips-dev/Appdata-Cleanup-Plus on the dev branch ###2024.11.28 - Fixed: Compatibility with Unraid 6.12.14+ ###2022.10.21 - Support translations by request ###2021.12.08 - Ignore error if corrupted XML files ###2021.11.27 - Unraid 6.10 compatibility ###2021.03.10 - Permission Fix ###2020.10.21 - Compatibility Fixes ###2019.09.15 - Fixed: Weirdness if using an appdata folder containing special characters ###2019.08.18 - Add another CYA banner warning ###2019.08.03 - Add large warning that if you screwed up, it's your problem ###2019.06.01 - Fix typo, credits fix, change update notification to CA style ###2019.05.14 - Suppress errors if xml file is corrupted ###2019.01.13 - Update Icon ###2018.12.31 - Add in some checks for when user had a severely misconfigured application previously installed ###2018.10.19 - Fix Broken Pipe ###2018.03.15 - Ignore metadata files created by OSX ###2017.11.23 - Reorganization as part of updates to CA proper - Relocate Icon to Settings / User Utilities ###2017.01.28 - Fixed: Errors when no templates have any possibilities for cleanup ###2016.11.11 - Initial Release ]]> rm -f $(ls /boot/config/plugins/&name;/&name;*.txz 2>/dev/null | grep -v '&version;') https://raw.githubusercontent.com/&github;/main/archive/&name;-&version;-x86_64-1.txz &md5; rm -rf /usr/local/emhttp/plugins/ca.cleanup.appdata/CA.page rm -rf /usr/local/emhttp/plugins/ca.cleanup.appdata/caHelp.page rm -rf /usr/local/emhttp/plugins/ca.cleanup.appdata echo "" echo "----------------------------------------------------" echo " &name; has been installed." echo " Maintainer: &author;" echo " Repo: &github;" echo " Version: &version;" echo "----------------------------------------------------" echo "" removepkg &name;-&version;-x86_64-1 rm -rf &plugdir; rm -rf /boot/config/plugins/&name;