@@ -78,7 +78,8 @@ MyMacCleaner/
7878 │ │ ├── HomebrewService.swift
7979 │ │ └── LocalizationManager.swift
8080 │ ├── Models/
81- │ │ └── ScanResult.swift
81+ │ │ ├── ScanResult.swift
82+ │ │ └── PermissionCategory.swift
8283 │ └── Extensions/
8384 ├── Features/
8485 │ ├── Home/
@@ -98,7 +99,14 @@ MyMacCleaner/
9899 │ ├── Performance/
99100 │ ├── Applications/
100101 │ ├── PortManagement/
101- │ └── SystemHealth/
102+ │ ├── SystemHealth/
103+ │ ├── StartupItems/
104+ │ └── Permissions/
105+ │ ├── PermissionsView.swift
106+ │ ├── PermissionsViewModel.swift
107+ │ └── Components/
108+ │ ├── PermissionCategoryCard.swift
109+ │ └── PermissionFolderRow.swift
102110 ├── Resources/
103111 │ └── Assets.xcassets/
104112 └── MyMacCleaner.entitlements
@@ -831,6 +839,90 @@ MyMacCleaner/
831839
832840---
833841
842+ ### 2026-01-05 - Permissions Management Page & Warning Fixes
843+
844+ ** Session Goal** : Add new Permissions page for reviewing and managing folder access permissions, fix all compiler warnings
845+
846+ ** Completed** :
847+
848+ ** Permissions Management Page:**
849+ - Created PermissionCategory.swift data models:
850+ - PermissionCategoryType enum (fullDiskAccess, userFolders, systemFolders, applicationData, startupPaths)
851+ - FolderAccessInfo struct (path, displayName, status, requiresFDA, canTriggerTCCDialog)
852+ - FolderAccessStatus enum (accessible, denied, notExists, checking)
853+ - PermissionCategoryState struct for UI state
854+ - Created PermissionsViewModel.swift:
855+ - buildCategories() creates all 5 category states with folder paths
856+ - checkAllPermissions() tests actual read access to each folder
857+ - requestFolderAccess() triggers TCC dialog for user folders
858+ - revokeFolderAccess() opens appropriate System Settings pane
859+ - Auto-refresh on app activation
860+ - Created PermissionFolderRow.swift component:
861+ - Status icon (green checkmark / red X / orange ?)
862+ - Folder displayName and path
863+ - "Grant" button (green for TCC, blue gear for FDA)
864+ - "Revoke" button (red, opens System Settings)
865+ - Created PermissionCategoryCard.swift:
866+ - Expandable glassCard with header showing category status
867+ - Lists all folders with PermissionFolderRow
868+ - Created PermissionsView.swift:
869+ - Header with title, subtitle, and refresh button
870+ - Summary card showing X/Y folders accessible
871+ - Expandable category cards
872+ - Auto-refresh on NSApplication.didBecomeActiveNotification
873+ - Updated ContentView.swift:
874+ - Added NavigationSection.permissions case
875+ - Icon: "lock.shield.fill", Color: Theme.Colors.permissions (indigo)
876+ - Updated AppState.swift:
877+ - Added permissionsViewModel property
878+ - Updated Theme.swift:
879+ - Added permissions color (indigo)
880+ - Updated Localizable.xcstrings:
881+ - Added 25+ translation keys (EN/IT/ES) for permissions UI
882+
883+ ** Warning Fixes:**
884+ - Fixed AuthorizationService.swift:73,91 - "capture of 'self' with non-Sendable type"
885+ - Moved escapeForAppleScript() call before async block to capture escaped string instead of self
886+ - Fixed SpaceLensViewModel.swift:178 - "makeIterator unavailable from async"
887+ - Changed ` for case let fileURL as URL in enumerator ` to ` while let fileURL = enumerator.nextObject() as? URL `
888+ - Fixed PortManagementViewModel.swift:148 - "call to actor-isolated method"
889+ - Made parseLsofOutput() and parseAddressPort() nonisolated functions
890+ - Fixed FileScanner.swift:211,298 - "makeIterator unavailable from async"
891+ - Changed both for-in loops to while-let pattern
892+ - Fixed AppUpdateChecker.swift:95 - "reference to captured var"
893+ - Used collected.count instead of mutable captured variable
894+ - Fixed StartupItemsService.swift:180,520 - "call to actor-isolated method"
895+ - Reordered modifiers to ` private static nonisolated func ` for parseBTMOutput and getCodeSigningTeam
896+
897+ ** Files Created** :
898+ - ` MyMacCleaner/Core/Models/PermissionCategory.swift `
899+ - ` MyMacCleaner/Features/Permissions/PermissionsView.swift `
900+ - ` MyMacCleaner/Features/Permissions/PermissionsViewModel.swift `
901+ - ` MyMacCleaner/Features/Permissions/Components/PermissionCategoryCard.swift `
902+ - ` MyMacCleaner/Features/Permissions/Components/PermissionFolderRow.swift `
903+
904+ ** Files Modified** :
905+ - ` MyMacCleaner/App/ContentView.swift ` (added permissions navigation)
906+ - ` MyMacCleaner/App/AppState.swift ` (added permissionsViewModel)
907+ - ` MyMacCleaner/Core/Design/Theme.swift ` (added permissions color)
908+ - ` MyMacCleaner/Core/Services/AuthorizationService.swift ` (fixed self capture warning)
909+ - ` MyMacCleaner/Core/Services/FileScanner.swift ` (fixed makeIterator warning)
910+ - ` MyMacCleaner/Core/Services/AppUpdateChecker.swift ` (fixed captured var warning)
911+ - ` MyMacCleaner/Core/Services/StartupItemsService.swift ` (fixed actor-isolated warnings)
912+ - ` MyMacCleaner/Features/SpaceLens/SpaceLensViewModel.swift ` (fixed makeIterator warning)
913+ - ` MyMacCleaner/Features/PortManagement/PortManagementViewModel.swift ` (fixed actor-isolated warning)
914+ - ` MyMacCleaner/Resources/Localizable.xcstrings ` (added permissions translations)
915+
916+ ** Key Technical Decisions** :
917+ - TCC folders (Downloads, Documents, Desktop) trigger system permission dialog via FileManager.contentsOfDirectory()
918+ - FDA folders cannot trigger dialog programmatically - show "Open Settings" button
919+ - Permission revocation not possible programmatically on macOS - opens appropriate System Settings pane
920+ - Auto-refresh permissions when app becomes active (user returns from System Settings)
921+
922+ ** Build Status** : SUCCESS (0 warnings)
923+
924+ ---
925+
834926## Constraints & Guidelines
835927
836928### Code Quality
0 commit comments