[codex] add FDA checks and actionable clean failures#9
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves macOS cleanup UX by detecting Full Disk Access (FDA) status, surfacing it pre-clean, and returning more actionable clean failure details (including TCC/FDA-related failures). It also tightens cache-clean reporting and fixes cleanup flow/state coordination, while bumping the app version to 0.4.1 and allowing the macOS System Settings deeplink via the shell plugin allowlist.
Changes:
- Add FDA status detection (Tauri command + UI hook/store) and display warnings/deeplinks on the welcome + done flows.
- Extend clean summaries with
method_labeland per-item failure details; merge cache clean outcomes into the final summary. - Update config/versioning (Tauri config + workspace version) and restrict
shell.openvia a regex allowlist.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/stores/ui-store.ts | Adds FDA status + dismissal persistence to UI state. |
| ui/src/stores/system-store.ts | Serializes detectSystem() calls to reduce races. |
| ui/src/lib/tauri.ts | Extends clean DTOs; changes cleanCache to return bytes freed; adds checkFdaStatus. |
| ui/src/hooks/useFdaCheck.ts | Implements periodic FDA checks (initial + on window focus). |
| ui/src/components/WelcomeView.tsx | Shows FDA warning banner and opens System Settings deeplink. |
| ui/src/components/ResultsView.tsx | Aggregates cache-clean results/failures and merges into final summary; adjusts cleaning flow. |
| ui/src/components/CelebrationView.tsx | Displays method label and actionable failure/TCC guidance (with deeplink). |
| ui/src/components/clean/CleanSummary.tsx | Displays method_label in the summary modal. |
| ui/src/App.tsx | Only mounts scan/FDA hooks after disclaimer acceptance. |
| tauri/tauri.conf.json | Bumps app version to 0.4.1; restricts shell.open via allowlist regex. |
| tauri/src/lib.rs | Registers the new check_fda_status command. |
| tauri/src/dto.rs | Adds CleanFailureDto, method_label, and failures to clean summary DTO; adds FdaStatusDto. |
| tauri/src/commands/system.rs | Implements FDA status detection (macOS-specific). |
| tauri/src/commands/clean.rs | Collects per-target clean failures and emits them in the clean summary. |
| tauri/src/commands/cache.rs | Returns bytes_freed from cache cleaning. |
| tauri/Cargo.toml | Adds dirs dependency (workspace). |
| Cargo.toml | Bumps workspace package version to 0.4.1. |
| Cargo.lock | Updates lockfile entries (but currently inconsistent with the 0.4.1 workspace bump). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| return () => { | ||
| cancelled = true; | ||
| void unlistenPromise.then((unlisten) => unlisten()); |
There was a problem hiding this comment.
Cleanup registers the focus-change unlistener via unlistenPromise.then(...) but does not handle promise rejection. If onFocusChanged fails (e.g., event registration error), this can surface as an unhandled promise rejection; add a .catch(...) (or wrap in try/await inside cleanup) to swallow/log safely.
| void unlistenPromise.then((unlisten) => unlisten()); | |
| void unlistenPromise | |
| .then((unlisten) => unlisten()) | |
| .catch((error) => { | |
| console.error('Failed to unregister focus change listener:', error); | |
| }); |
| {summary.used_trash && ( | ||
| <p className="text-xs text-[var(--color-text-muted)] text-center"> | ||
| Items were moved to Trash | ||
| Method: {summary.method_label} | ||
| </p> | ||
| )} | ||
| {!summary.used_trash && ( | ||
| <p className="text-xs text-[var(--color-text-muted)] text-center"> | ||
| Method: {summary.method_label} | ||
| </p> | ||
| )} |
There was a problem hiding this comment.
The used_trash and !used_trash branches render the exact same markup (Method: {summary.method_label}), so the conditional is redundant. Consider rendering this once unconditionally to reduce duplication and avoid future drift between the branches.
Summary
Why
macOS privacy protections were causing cleanup failures to look like silent generic failures. Users needed a direct warning before cleanup, clearer failure reasons after cleanup, and a working path into the relevant System Settings page.
Impact
The app now warns when Full Disk Access is missing, shows per-item cleanup failures, opens the Full Disk Access settings deeplink correctly, and produces a consistent summary for path-only, cache-only, and mixed cleanup runs.
Validation
Notes
A released update must be versioned above the current latest GitHub release (
v0.4.0) for the in-app updater to surface it, so this change bumps the app to0.4.1.