How the vorssaint-utils Cleaner Scans for Application Leftovers and Caches

The Cleaner employs a two-phase oracle-based approach that first indexes all installed applications by bundle identifier, then cross-references Library folders and cache directories against this registry to identify orphaned files that remain after app removal.

The vorssaint-utils repository provides a macOS maintenance utility designed to reclaim storage by systematically scanning for stale application data. At its core, the JunkCleaner class implements a safety-first algorithm to detect application leftovers and caches without risking active program files. The scanning logic combines bundle identifier resolution with filesystem metadata analysis to distinguish between legitimate application support data and removable remnants.

The Two-Phase Scanning Architecture

The scan() method in Sources/Vorssaint/Services/Cleaner/JunkCleaner.swift orchestrates detection through a validated pipeline: first establishing a baseline of installed applications, then auditing known Library locations against that baseline.

Phase 1: Building the Installed Apps Oracle

Before examining any directories, the scanner constructs a comprehensive set of legitimate bundle identifiers via installedBundleIDs(). This method traverses three standard application directories—/Applications, /System/Applications, and ~/Applications—recursively up to three levels deep, while also inspecting currently running processes through NSWorkspace to capture transient or non-standard installations.

Phase 2: Scanning Library Locations for Leftovers

With the oracle established, scanLeftovers(installed:) iterates through predefined leftoverRoots including Application Support, Caches, Preferences, and other Library subdirectories. For each entry, the appendLeftovers(in:usesContainerMetadata:installed:fm:into:) method attempts to establish ownership by extracting candidate bundle identifiers.

Resolving Bundle Identifiers from Folder Metadata

The leftoverOwner(entry:url:usesContainerMetadata:) function employs dual identification strategies: parsing the folder name itself using CleanerSupport.bundleIDCandidate, or reading the internal .com.apple.containermanagerd.metadata.plist file that macOS maintains for sandboxed applications. Shared container wrappers are explicitly ignored to prevent cross-application data loss.

The Safety Verification Layer

Before flagging any item as removable, hasLivingOwner(_:installed:) performs three critical validations: it checks if the identifier exists in the installed set, verifies whether it shares a vendor namespace with an installed application, and confirms that NSWorkspace.shared.urlForApplication(withBundleIdentifier:) resolves to an active bundle on disk. If any condition matches, the entry is preserved and excluded from results.

Cache Directory Enumeration and Deduplication

After processing leftovers, scanCaches(excluding:) enumerates the user’s ~/Library/Caches directory while respecting exclusion policies defined in CleanerPolicy.isExcludedCacheEntry. The scanner maintains a claimed set throughout the process to ensure that any path already categorized as a leftover is excluded from cache results, preventing the same directory from appearing in multiple cleanup categories.

Implementing the Scanner Programmatically

Developers can invoke the scanning logic directly through the JunkCleaner singleton. The following Swift example demonstrates initiating a scan and retrieving categorized results:

let cleaner = JunkCleaner.shared
cleaner.reset()
cleaner.scan()

// Access results when phase completes
if cleaner.phase == .results {
    let leftovers = cleaner.items(in: .leftovers)
    leftovers.forEach { item in
        print("\(item.detail): \(item.url.path) (\(item.size) bytes)")
    }
    
    let caches = cleaner.items(in: .caches)
    print("Cache entries found: \(caches.count)")
}

For synchronous execution in testing environments or scripts, wrap the asynchronous scan in a dispatch group:

let group = DispatchGroup()
group.enter()
DispatchQueue.global(qos: .userInitiated).async {
    JunkCleaner.shared.scan()
    while JunkCleaner.shared.phase == .scanning { 
        usleep(100_000) 
    }
    group.leave()
}
group.wait()

Summary

  • The scanner builds a comprehensive bundle identifier oracle by examining /Applications, /System/Applications, ~/Applications, and currently running processes via installedBundleIDs().
  • Leftover detection targets predefined Library subdirectories including Application Support and Preferences, using both folder names and container metadata for owner identification in leftoverOwner().
  • Safety checks in hasLivingOwner() prevent accidental removal by verifying bundle identifiers against installed apps, vendor namespaces, and live NSWorkspace resolution.
  • Cache scanning enumerates ~/Library/Caches while utilizing a claimed set to deduplicate entries already flagged as leftovers in previous phases.
  • Core implementation resides in Sources/Vorssaint/Services/Cleaner/JunkCleaner.swift with supporting utilities in CleanerSupport.swift and exclusion policies in CleanerPolicy.swift.

Frequently Asked Questions

How does the Cleaner determine if a folder belongs to an uninstalled application?

The Cleaner extracts the bundle identifier from either the folder name via CleanerSupport.bundleIDCandidate or the .com.apple.containermanagerd.metadata.plist metadata file, then verifies against the installed apps oracle. If hasLivingOwner() cannot locate the identifier in installed applications, running processes, or shared vendor namespaces, the folder is classified as a leftover eligible for removal.

What prevents the scanner from deleting active application data?

Three safety mechanisms protect active data: the installedBundleIDs oracle checks for existing applications on disk, hasLivingOwner() validates against NSWorkspace for live bundles, and CleanerSupport.isProtectedBundleID filters out protected system identifiers. Additionally, the scanner ignores shared container wrappers to prevent collateral damage to other applications.

Can the scanning logic be used outside the vorssaint-utils GUI?

Yes, the JunkCleaner class exposes a public singleton interface suitable for programmatic access. Developers can invoke scan() for asynchronous operation or wrap it in a DispatchGroup for synchronous execution, then retrieve categorized Item arrays via items(in:) for integration with custom maintenance scripts or alternative user interfaces.

How does the scanner handle duplicate entries across leftovers and caches?

A claimed set tracks every path identified during the leftovers scan. When scanCaches() enumerates ~/Library/Caches, it skips any entry present in this set, ensuring that a directory found in both Application Support and Caches appears only once in the final results. This prevents user confusion and accidental double-counting of reclaimable space.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →