|
| 1 | +# CLAUDE.md — MacSweep Codebase Guide |
| 2 | + |
| 3 | +This file provides AI assistants with the context needed to understand, navigate, and contribute to MacSweep effectively. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Project Overview |
| 8 | + |
| 9 | +MacSweep is a free, open-source macOS system cleaner and security tool built entirely with SwiftUI and native Apple frameworks. It targets macOS 13 Ventura and later, has zero external dependencies, and ships as a signed DMG. The project was built using AI-assisted "vibe coding" with Claude, OpenAI Codex, and Google Gemini. |
| 10 | + |
| 11 | +- **Current version**: 3.3 (Build 33) |
| 12 | +- **Bundle ID**: `com.mehmed.MacSweep` |
| 13 | +- **Minimum macOS**: 13 Ventura |
| 14 | +- **Language**: Swift 5.9+ / SwiftUI |
| 15 | +- **License**: MIT |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +## Repository Layout |
| 20 | + |
| 21 | +``` |
| 22 | +MacSweep/ |
| 23 | +├── MacSweep/ # All Swift source files (35 files, ~29.5K lines) |
| 24 | +│ ├── MacSweepApp.swift # @main entry point, AppDelegate |
| 25 | +│ ├── Models.swift # All data models, design system, AppSettings |
| 26 | +│ ├── ScanEngine.swift # Disk/CPU/RAM/network metrics and junk scanning |
| 27 | +│ ├── CleanEngine.swift # File deletion logic |
| 28 | +│ ├── SecurityEngine.swift # Malware detection, ransomware guard, network monitor |
| 29 | +│ ├── NavigationManager.swift # Navigation history and state |
| 30 | +│ ├── AppUpdateEngine.swift # GitHub Releases version checking |
| 31 | +│ ├── AutoPolicyEngine.swift # Automated scan/clean scheduling |
| 32 | +│ ├── NotificationManager.swift |
| 33 | +│ ├── *View.swift # 20+ SwiftUI view files (one per section) |
| 34 | +│ ├── Assets.xcassets/ # App icons, images |
| 35 | +│ └── Info.plist # App config, entitlements declarations |
| 36 | +├── MacSweep.xcodeproj/ # Xcode project (auto-generated by generate_project.py) |
| 37 | +├── .github/workflows/build.yml # GitHub Actions CI (build verification only) |
| 38 | +├── homebrew/macsweep.rb # Homebrew cask formula |
| 39 | +├── build.sh # Full build → DMG pipeline |
| 40 | +├── build-dmg.sh # DMG creator with drag-to-Applications UI |
| 41 | +├── generate_project.py # Regenerates .xcodeproj from source files |
| 42 | +├── install.sh # One-line installer (removes quarantine) |
| 43 | +├── make_icns.py # Icon generator utility |
| 44 | +├── screenshots/ # App screenshots used in README |
| 45 | +├── README.md |
| 46 | +└── CONTRIBUTING.md |
| 47 | +``` |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## Architecture |
| 52 | + |
| 53 | +### Pattern: MVVM + Service Layer |
| 54 | + |
| 55 | +**Engines** (service/business logic layer): |
| 56 | +- Located in `*Engine.swift` files |
| 57 | +- Subclass `ObservableObject` and expose `@Published` properties |
| 58 | +- Decorated with `@MainActor` for async operations |
| 59 | +- Instantiated once in `MacSweepApp` and passed down as `@StateObject`/`@ObservedObject` |
| 60 | + |
| 61 | +**Views** (presentation layer): |
| 62 | +- Located in `*View.swift` files |
| 63 | +- Pure SwiftUI `struct`s — no UIKit |
| 64 | +- Receive engines as `@ObservedObject` constructor arguments |
| 65 | +- Use `@EnvironmentObject` for shared singletons: `NavigationManager`, `AppSettings` |
| 66 | + |
| 67 | +**Data flow**: |
| 68 | +``` |
| 69 | +MacSweepApp |
| 70 | + └─ creates: ScanEngine, CleanEngine, SecurityEngine, AppSettings, ... |
| 71 | + └─ passes to: ContentView → SidebarView + detail views |
| 72 | + └─ AppSettings persisted via UserDefaults (didSet handlers) |
| 73 | + └─ Navigation via NavigationManager (history stack) |
| 74 | +``` |
| 75 | + |
| 76 | +### Navigation |
| 77 | + |
| 78 | +`AppSection` enum in `Models.swift` is the **single source of truth** for navigation. It has 24 cases (one per app section/screen). Never hardcode section names; always use this enum. |
| 79 | + |
| 80 | +```swift |
| 81 | +enum AppSection { |
| 82 | + case dashboard, smartScan, systemJunk, largeFiles, appLeftovers, |
| 83 | + browserCleaner, devCleaner, spaceLens, privacy, memoryOptimizer, |
| 84 | + performanceManager, maintenance, applicationsManager, duplicateFinder, |
| 85 | + protectionManager, malwareScanner, realtimeProtection, adwareCleaner, |
| 86 | + ransomwareGuard, networkMonitor, quarantineManager, integrityMonitor, |
| 87 | + settings, legal |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +`NavigationManager` (shared via `@EnvironmentObject`) manages the active section and history. |
| 92 | + |
| 93 | +--- |
| 94 | + |
| 95 | +## Design System |
| 96 | + |
| 97 | +All UI styling is defined in `Models.swift` and must be used consistently. **Never hardcode colors, fonts, or spacing.** |
| 98 | + |
| 99 | +### Colors (`DS` struct) |
| 100 | +```swift |
| 101 | +DS.bg // #0A0A12 — window background |
| 102 | +DS.bgPanel // #12121E — panel/card background |
| 103 | +DS.bgElevated // #1A1A2A — elevated surfaces |
| 104 | +DS.brand // #169677 — primary green accent |
| 105 | +DS.brandLight // #19B08B — lighter green |
| 106 | +DS.success // green |
| 107 | +DS.warning // orange |
| 108 | +DS.danger // red |
| 109 | +DS.textPrimary // white |
| 110 | +DS.textSecondary // muted white |
| 111 | +``` |
| 112 | + |
| 113 | +### Typography (`MSFont`) |
| 114 | +```swift |
| 115 | +MSFont.heroTitle // Large display heading |
| 116 | +MSFont.title // Section title |
| 117 | +MSFont.title2 / .title3 |
| 118 | +MSFont.headline // Card/group header |
| 119 | +MSFont.bodyBold / .body |
| 120 | +MSFont.caption // Small labels |
| 121 | +MSFont.mono // Monospaced (paths, code) |
| 122 | +``` |
| 123 | + |
| 124 | +### Spacing (`MSSpacing`) |
| 125 | +```swift |
| 126 | +MSSpacing.xs // 6pt |
| 127 | +MSSpacing.sm // 12pt |
| 128 | +MSSpacing.md // 20pt |
| 129 | +MSSpacing.lg // 28pt |
| 130 | +MSSpacing.xl // 40pt |
| 131 | +``` |
| 132 | + |
| 133 | +### Section Themes |
| 134 | +Each of the 24 app sections has a gradient + glow color: |
| 135 | +```swift |
| 136 | +SectionTheme.theme(for: .malwareScanner) |
| 137 | +// Returns (gradient: [Color], glow: Color) |
| 138 | +``` |
| 139 | +Always use `SectionTheme.theme(for:)` for per-section visual identity. |
| 140 | + |
| 141 | +### Motion / Animation |
| 142 | +```swift |
| 143 | +Motion.fast // 0.15s ease |
| 144 | +Motion.std // 0.25s ease |
| 145 | +Motion.slow // 0.4s ease |
| 146 | +Motion.spring // spring physics |
| 147 | +Motion.breathe // repeating scale pulse |
| 148 | +Motion.spin // repeating rotation |
| 149 | +``` |
| 150 | +Use staggered index-based delays for list animations. |
| 151 | + |
| 152 | +--- |
| 153 | + |
| 154 | +## Key Files Reference |
| 155 | + |
| 156 | +| File | Responsibility | |
| 157 | +|------|----------------| |
| 158 | +| `Models.swift` | Data models, `DS` design system, `MSFont`, `MSSpacing`, `SectionTheme`, `Motion`, `AppSettings`, `AppSection`, `ScanCategory`, `ThreatSeverity` | |
| 159 | +| `MacSweepApp.swift` | `@main` entry, window config (1380×920), `AppDelegate`, dock icon toggling, single-instance enforcement | |
| 160 | +| `ScanEngine.swift` | Junk scanning, disk/CPU/RAM/network live metrics, Space Lens analysis | |
| 161 | +| `SecurityEngine.swift` | Malware heuristics, adware detection, ransomware file-rate monitoring, network TCP inspection, FSEvents real-time protection, system integrity checks | |
| 162 | +| `MenuBarView.swift` | Menu bar popover UI (3,116 lines) — live metrics label, quick-action grid, section launchers | |
| 163 | +| `SettingsView.swift` | Full settings UI (2,239 lines) — scan options, browser toggles, automation policies, notifications | |
| 164 | +| `DevCleanerView.swift` | Xcode/npm/pip/gem cache cleaner | |
| 165 | +| `DashboardView.swift` | Main dashboard with freed-space history chart | |
| 166 | +| `SpaceLensView.swift` | Interactive treemap disk visualization | |
| 167 | +| `ApplicationsManagerView.swift` | App list sorted by size/last-used | |
| 168 | + |
| 169 | +--- |
| 170 | + |
| 171 | +## Code Conventions |
| 172 | + |
| 173 | +### Naming |
| 174 | +- **Types** (classes, structs, enums, protocols): `PascalCase` |
| 175 | +- **Properties and functions**: `camelCase` |
| 176 | +- **View files**: `<Name>View.swift` |
| 177 | +- **Engine files**: `<Name>Engine.swift` |
| 178 | +- **Enum cases**: `camelCase` (Swift convention) |
| 179 | + |
| 180 | +### Swift Style |
| 181 | +- Swift 5.9+ features are fine (macros, `if`/`switch` expressions, etc.) |
| 182 | +- **No force unwraps** (`!`). Use `guard let`, `if let`, or `??`. |
| 183 | +- **No third-party dependencies**. Use only Apple frameworks. |
| 184 | +- **No UIKit**. This is a pure SwiftUI app. |
| 185 | +- Prefer `async/await` over completion handlers for new async code. |
| 186 | +- Mark async engine classes `@MainActor`. |
| 187 | +- Use `@Published` for all reactive state in engines. |
| 188 | + |
| 189 | +### UI Guidelines |
| 190 | +- All views must use the `DS` design system for colors, `MSFont` for typography, and `MSSpacing` for spacing. |
| 191 | +- All section-specific gradients/glow effects must use `SectionTheme.theme(for:)`. |
| 192 | +- The app is dark-theme only — do not add light mode support. |
| 193 | +- Use `Motion.*` constants for all animation durations. |
| 194 | +- Apply staggered list animations with index-based delays. |
| 195 | + |
| 196 | +### Separation of Concerns |
| 197 | +- Keep business logic in engine files, not in views. |
| 198 | +- Views should only observe engine state and call engine methods. |
| 199 | +- `AppSettings` is the only settings store; persist new settings as `@Published var` with a `UserDefaults` `didSet`. |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +## Build & Development |
| 204 | + |
| 205 | +### Prerequisites |
| 206 | +- macOS 13+ with Xcode 15+ |
| 207 | +- Swift 5.9+ |
| 208 | +- Command-line tools: `xcodebuild`, `xcpretty` (optional), Python 3 (for `generate_project.py`) |
| 209 | + |
| 210 | +### Regenerate the Xcode Project |
| 211 | +If you add or remove Swift source files, regenerate the `.xcodeproj`: |
| 212 | +```bash |
| 213 | +python3 generate_project.py |
| 214 | +``` |
| 215 | + |
| 216 | +### Build via Xcode |
| 217 | +Open `MacSweep.xcodeproj` in Xcode and press ⌘R. |
| 218 | + |
| 219 | +### Build from Terminal (full pipeline) |
| 220 | +```bash |
| 221 | +./build.sh # Generates project, compiles, creates DMG |
| 222 | +``` |
| 223 | +Architecture auto-detection: Apple Silicon → `arm64`, Intel → `x86_64`. |
| 224 | + |
| 225 | +### Create Installer DMG |
| 226 | +```bash |
| 227 | +./build-dmg.sh # Branded DMG with drag-to-Applications UI |
| 228 | +``` |
| 229 | + |
| 230 | +### Install Locally (skip Gatekeeper) |
| 231 | +```bash |
| 232 | +./install.sh # Removes quarantine, copies to /Applications |
| 233 | +``` |
| 234 | + |
| 235 | +### CI Build Command (no code signing) |
| 236 | +```bash |
| 237 | +xcodebuild \ |
| 238 | + -project MacSweep.xcodeproj \ |
| 239 | + -scheme MacSweep \ |
| 240 | + -destination "platform=macOS" \ |
| 241 | + -configuration Debug \ |
| 242 | + CODE_SIGNING_ALLOWED=NO \ |
| 243 | + build |
| 244 | +``` |
| 245 | + |
| 246 | +--- |
| 247 | + |
| 248 | +## CI/CD |
| 249 | + |
| 250 | +**GitHub Actions** (`.github/workflows/build.yml`): |
| 251 | +- Triggers on push and PRs to `main` |
| 252 | +- Runs on `macos-14` |
| 253 | +- Verifies the project compiles with `xcodebuild` (no code signing) |
| 254 | +- Does **not** run tests (no test suite exists) |
| 255 | +- Does **not** upload artifacts |
| 256 | + |
| 257 | +To verify your changes compile before pushing: |
| 258 | +```bash |
| 259 | +xcodebuild -project MacSweep.xcodeproj -scheme MacSweep \ |
| 260 | + -destination "platform=macOS" -configuration Debug \ |
| 261 | + CODE_SIGNING_ALLOWED=NO build 2>&1 | grep -E "error:|BUILD FAILED|BUILD SUCCEEDED" |
| 262 | +``` |
| 263 | + |
| 264 | +--- |
| 265 | + |
| 266 | +## App Entry Point & Lifecycle |
| 267 | + |
| 268 | +``` |
| 269 | +MacSweepApp (@main) |
| 270 | +├── OnboardingView ← shown on first launch |
| 271 | +└── ContentView ← main shell |
| 272 | + ├── SidebarView ← 200px left sidebar (section list) |
| 273 | + └── Detail view ← driven by NavigationManager.activeSection |
| 274 | +``` |
| 275 | + |
| 276 | +**Window**: 1380×920 preferred, 1240×820 minimum, hidden title bar, unified toolbar. |
| 277 | + |
| 278 | +**Single-instance enforcement**: `AppDelegate` detects an already-running instance via `NSRunningApplication` and brings it to front instead of launching a second copy. During development (debugger attached), multiple instances are allowed. |
| 279 | + |
| 280 | +**⌘Q behavior**: Hides the window (menu bar stays active) instead of quitting; the app only truly quits from the menu bar icon. |
| 281 | + |
| 282 | +**Dock icon**: Shown by default; can be toggled off in Settings (launches as menu-bar-only). |
| 283 | + |
| 284 | +**Menu bar label**: Displays live CPU%, RAM, disk free, network speed. Turns red when CPU > 80%. |
| 285 | + |
| 286 | +--- |
| 287 | + |
| 288 | +## Settings & Persistence |
| 289 | + |
| 290 | +All settings are stored in `AppSettings` (`ObservableObject`) in `Models.swift`: |
| 291 | +- Each setting is a `@Published var` with a `UserDefaults` `didSet` handler. |
| 292 | +- Read settings via `@EnvironmentObject var settings: AppSettings`. |
| 293 | +- Adding a new setting: add a `@Published var` with a `UserDefaults` read in `init()` and a `didSet` write. |
| 294 | + |
| 295 | +--- |
| 296 | + |
| 297 | +## Security Engines (overview) |
| 298 | + |
| 299 | +| Engine | Location | What it does | |
| 300 | +|--------|----------|--------------| |
| 301 | +| Malware Scanner | `SecurityEngine.swift` | Heuristic file scanning for suspicious patterns | |
| 302 | +| Adware Cleaner | `SecurityEngine.swift` | Audits browser extensions and login items | |
| 303 | +| Ransomware Guard | `SecurityEngine.swift` | Monitors file-change rate in watched folders | |
| 304 | +| Network Monitor | `SecurityEngine.swift` | Inspects active TCP connections for suspicious ports | |
| 305 | +| Real-Time Protection | `SecurityEngine.swift` | FSEvents watcher on Downloads/Desktop/Documents | |
| 306 | +| Integrity Monitor | `SecurityEngine.swift` | Scans launch agents, daemons, hosts file, SSH config, kernel extensions | |
| 307 | +| Quarantine Manager | `SecurityEngine.swift` | Isolates and restores flagged items | |
| 308 | + |
| 309 | +--- |
| 310 | + |
| 311 | +## Common Tasks |
| 312 | + |
| 313 | +### Add a new app section |
| 314 | +1. Add a case to `AppSection` in `Models.swift`. |
| 315 | +2. Add a `SectionTheme` entry for the new section. |
| 316 | +3. Create `<Name>View.swift` following existing view patterns. |
| 317 | +4. Add routing in the detail view switcher (usually in `ContentView` or `SidebarView`). |
| 318 | +5. Add a sidebar entry in `SidebarView`. |
| 319 | + |
| 320 | +### Add a new setting |
| 321 | +1. Add a `@Published var newSetting: Type = defaultValue` to `AppSettings` in `Models.swift`. |
| 322 | +2. In `AppSettings.init()`, read from UserDefaults. |
| 323 | +3. Add a `didSet { UserDefaults.standard.set(newSetting, forKey: "newSetting") }`. |
| 324 | +4. Expose the toggle/control in `SettingsView.swift`. |
| 325 | + |
| 326 | +### Add a new scan category |
| 327 | +1. Add a case to `ScanCategory` in `Models.swift`. |
| 328 | +2. Implement scanning logic in `ScanEngine`. |
| 329 | +3. Add display in `SystemJunkView` or the relevant view. |
| 330 | + |
| 331 | +--- |
| 332 | + |
| 333 | +## What to Avoid |
| 334 | + |
| 335 | +- **Force unwraps** (`!`) — always use safe unwrapping. |
| 336 | +- **Hardcoded colors/fonts/spacing** — always use `DS`, `MSFont`, `MSSpacing`. |
| 337 | +- **Third-party packages** — zero external dependencies is a hard requirement. |
| 338 | +- **UIKit** — SwiftUI only. |
| 339 | +- **Light mode code** — the app is dark-theme only. |
| 340 | +- **Multiple `NavigationManager` instances** — it's a singleton via `@EnvironmentObject`. |
| 341 | +- **Logic in views** — keep engine code in engine files. |
| 342 | +- **Modifying `.xcodeproj` by hand** — regenerate it with `python3 generate_project.py` after adding/removing files. |
0 commit comments