Summary
Add a standalone App Uninstaller plugin that removes a selected application and helps the user review files associated with it.
The defining product principle is evidence and confidence, not aggressive deletion.
Every associated item should explain:
- What it is
- Why MacTools believes it belongs to the selected application
- Whether it may be shared with another application
- Whether it contains user-created data
- Whether it is selected by default
- Whether it can be safely moved to Trash
- Whether a vendor-provided uninstaller or package manager should be used instead
Illustrative confidence groups:
Verified application bundle
Verified application container
Verified application cache
Verified preference
Verified helper or launch item
Shared vendor data
Possible associated data
Ambiguous user-created data
Protected
The user must review the exact application and associated files before removal.
This plugin should be built after the Storage Explorer scanner and shared file-safety primitives are sufficiently proven, but the product boundary can be agreed in advance.
Motivation
Dragging an application to Trash often leaves behind:
- Caches
- Preferences
- Saved application state
- Application Support data
- Containers
- Login items
- Launch agents
- Helper tools
- Logs
- Web data
- Extensions
- Vendor-specific support directories
However, filename similarity alone is not enough to prove ownership.
Aggressive uninstaller tools risk removing:
- Data shared by several applications from the same vendor
- Group containers
- Plug-ins used by another application
- User documents
- Presets
- Templates
- Downloaded models
- Licensed content
- Browser profiles
- Project files
- Shared helpers
MacTools should provide a conservative uninstall workflow that makes association evidence visible and keeps the user in control.
Product boundary
App Uninstaller owns:
- Selecting or dropping an application
- Application identity
- Associated-file discovery
- Association evidence
- Confidence classification
- Application-specific review
- Quit and removal planning
- Trash-first execution
- Uninstall history
It does not own:
- Generic cleanup of leftovers from unknown applications
- Whole-volume analysis
- Duplicate detection
- Application updates
- Malware removal
- Package management
- Enterprise device management
- Automatic bulk uninstall
- Removal of system applications
- Generic cache cleanup unrelated to the selected application
Relationship to other plugins:
| Plugin |
Responsibility |
| Disk Cleanup |
Known cleanup rules independent of an uninstall operation |
| Storage Explorer |
Neutral disk-usage analysis |
| App Uninstaller |
Evidence that files belong to one selected application |
| Homebrew |
Formula and cask management |
| Launch Items |
General launch-agent browsing and control |
| Empty Trash |
Explicit permanent Trash emptying |
Goals
- Let users select or drag an application into a dedicated workspace.
- Identify the app’s bundle ID, team/vendor identity, version, path, and installation source.
- Discover associated files from fixed, reviewed locations.
- Attach structured evidence to every associated file.
- Classify confidence and data sensitivity.
- Select only high-confidence disposable or application-owned data by default.
- Keep shared, ambiguous, and user-created data unselected.
- Protect system applications and critical roots.
- Detect running processes and offer a safe quit flow.
- Detect package-manager or vendor-uninstaller cases.
- Build an immutable removal plan.
- Revalidate identity and ownership before execution.
- Move the app and selected files to Trash by default.
- Record structured results and history.
- Expose only safe foreground actions through Command Palette and other action surfaces.
- Keep all analysis local.
- Use an independent implementation.
Non-goals
- One-click aggressive removal without review
- Automatic leftover cleanup for every missing bundle ID
- Bulk unattended uninstall
- Removing system applications
- Removing macOS components
- Removing applications managed by an organization
- Removing kernel extensions, system extensions, privileged helpers, or drivers without a dedicated supported flow
- Silently running vendor uninstall scripts
- Deleting user documents
- Deleting shared vendor data by default
- Deleting group containers by default
- Guessing ownership from a broad vendor folder alone
- Emptying Trash
- Malware scanning
- License deactivation
- Subscription cancellation
- App update management
- Replacing Homebrew cask uninstall
- Copying third-party uninstaller code, path lists, or heuristics
- Requiring a new host-wide operational window
Dependency and sequencing
This proposal should be tracked separately but implemented after:
- Storage Explorer or equivalent file-tree scanning primitives have proven file identity, path safety, bounded traversal, and Trash execution.
- Disk Cleanup’s explainability and provenance work has established a consistent evidence vocabulary.
- The project has a clear approach to shared narrow storage primitives.
App Uninstaller must not be implemented merely by copying a list of common ~/Library folders and matching names.
Primary user flow
Open App Uninstaller
→ Drop or choose an application
→ Identify app and installation source
→ Scan reviewed association roots
→ Group results by confidence and type
→ Explain every association
→ User selects or deselects individual items
→ Review exact removal plan
→ Quit application if needed
→ Move app and selected files to Trash
→ Show structured result and history
Application selection
Support:
- Drag an
.app bundle into the workspace
- Choose Application…
- Select from an installed-application browser
- Open App Uninstaller from Command Palette
- A future Finder integration or live Command Palette result
Validate:
- The path is an application bundle.
- The bundle has a readable identity.
- The application is not a protected system app.
- The application is not MacTools itself.
- The application is not inside a read-only or system-managed location.
- The application has not changed since it was selected.
Show:
- Icon
- Name
- Bundle identifier
- Version and build
- Developer/team identifier where available
- Installation path
- Installation source
- Running state
- Estimated bundle size
- Code-signing status where useful
Do not require code-signing identity for every app, but use it as evidence where available.
Installation-source detection
Potential sources:
Mac App Store
Homebrew cask
Standalone application
Vendor suite
Managed application
System application
Unknown
Homebrew
If the selected app is managed by a Homebrew cask:
- Explain that Homebrew is the authoritative manager.
- Offer to open the Homebrew plugin or execute an eligible confirmed cask-uninstall action.
- Do not independently remove files that Homebrew tracks unless the user explicitly chooses a follow-up associated-data review.
- Keep package-manager execution and associated-data cleanup as separate steps.
Vendor uninstaller
If an application contains or installs a known vendor uninstaller:
- Show it prominently.
- Explain why vendor removal may be required for privileged helpers, drivers, extensions, or licensing components.
- Do not execute it silently.
- Allow the user to launch it.
- Optionally offer associated-file review after it completes.
Managed or system application
- Block removal.
- Explain the reason.
- Do not provide an override.
Association evidence
Define structured evidence rather than a Boolean “belongs to app.”
Illustrative model:
enum AppAssociationEvidence: Hashable, Sendable {
case exactBundleIdentifier
case containerMetadata(bundleIdentifier: String)
case savedApplicationState(bundleIdentifier: String)
case preferenceDomain(bundleIdentifier: String)
case executableInsideApplicationBundle
case helperDesignatedRequirement
case launchItemExecutablePath
case loginItemEmbeddedInApplication
case applicationGroupIdentifier(String)
case teamIdentifier(String)
case packageReceipt(String)
case exactKnownVendorMetadata
case vendorNamespace(String)
case filenameSimilarity
case userSelected
}
Each candidate may carry several pieces of evidence.
Evidence strength must be explicit and testable.
Confidence model
Illustrative classification:
enum AppAssociationConfidence: Comparable, Sendable {
case verified
case strong
case shared
case possible
case ambiguous
case protected
}
Verified
Examples:
- The application bundle selected by the user
- Container metadata names the exact bundle ID
- Saved Application State uses the exact bundle ID
- Preference domain exactly matches the bundle ID
- Embedded login item or helper resides inside the app bundle
- Launch item executable path resolves inside the app bundle
Default:
- App bundle selected
- Verified disposable associated data may be selected
- User-created data still requires separate classification
Strong
Examples:
- Exact bundle ID in a reviewed standard support root
- Helper code signature or designated requirement maps to the app’s team and identifier
- Package receipt directly identifies the selected app
Default:
- Disposable caches/logs may be selected
- Application Support remains dependent on data sensitivity
Shared
Examples:
- App Group or Group Container
- Vendor suite support data
- Shared helper used by another installed app
- Team-identifier directory
Default:
- Unselected
- Explain which other installed applications may use it
Possible
Examples:
- Vendor namespace match
- Exact product-name folder without stronger metadata
- Helper label resembles the bundle ID
Default:
Ambiguous
Examples:
- Generic folder name
- Filename similarity only
- User Documents
- Project or media content
Default:
- Unselected
- Strong warning
- Never categorized as disposable automatically
Protected
Examples:
- System root
- Shared system component
- Another installed app’s data
- MacTools data
- Read-only system app
- Uncertain privileged component
Default:
Data sensitivity
Confidence that a file belongs to an app is separate from whether it is safe to remove.
Illustrative model:
enum AppAssociatedDataClass: Sendable {
case applicationBundle
case cache
case log
case preference
case savedState
case container
case applicationSupport
case loginItem
case launchAgent
case helper
case extensionComponent
case userDocument
case presetOrTemplate
case downloadedContent
case sharedVendorData
case unknown
}
Suggested default-selection policy:
| Data class |
Verified/strong |
Shared/possible |
Ambiguous |
| Application bundle |
Selected |
N/A |
N/A |
| Cache |
Selected |
Unselected |
Unselected |
| Log |
Selected |
Unselected |
Unselected |
| Preference |
Selected |
Unselected |
Unselected |
| Saved state |
Selected |
Unselected |
Unselected |
| Container |
Review policy |
Unselected |
Unselected |
| Application Support |
Unselected unless known disposable |
Unselected |
Unselected |
| Login item |
Selected only with exact executable evidence |
Unselected |
Unselected |
| Helper |
Review |
Unselected |
Unselected |
| Extension component |
Manual/vendor flow |
Unselected |
Unselected |
| User document |
Unselected |
Unselected |
Unselected |
| Preset/template |
Unselected |
Unselected |
Unselected |
| Downloaded content |
Unselected |
Unselected |
Unselected |
| Shared vendor data |
Unselected |
Unselected |
Unselected |
The exact matrix should be finalized after research and tests.
Reviewed association roots
Scan only fixed, reviewed roots.
Potential user-domain roots to research:
~/Library/Application Support
~/Library/Caches
~/Library/Preferences
~/Library/Preferences/ByHost
~/Library/Saved Application State
~/Library/HTTPStorages
~/Library/WebKit
~/Library/Logs
~/Library/Containers
~/Library/Cookies
~/Library/LaunchAgents
~/Library/Application Scripts
Potential local-domain roots:
/Library/Application Support
/Library/Caches
/Library/Preferences
/Library/LaunchAgents
/Library/LaunchDaemons
/Library/PrivilegedHelperTools
Inclusion here is not approval to delete all matches.
For every root, the implementation must define:
- Discovery evidence
- Confidence ceiling
- Data sensitivity
- Permission behavior
- Whether the root is user-domain or shared
- Whether another installed app can own the same item
- Whether Trash is supported
- Whether administrator approval is required
Do not recursively scan arbitrary filesystem roots.
Other installed applications as an ownership oracle
Before presenting an associated item:
- Inventory installed applications from reviewed application roots.
- Include running applications.
- Include embedded login items and helpers where discoverable.
- Use bundle IDs, team IDs, app groups, package receipts, and executable paths.
- Reject or downgrade candidates claimed by another installed application.
- Treat shared vendor namespaces conservatively.
- Do not assume an unregistered app is uninstalled merely because LaunchServices lookup fails.
The oracle must be testable with fixtures.
Running application behavior
If the selected application is running:
- Show the running state.
- Disable final removal until it quits.
- Offer Quit Application.
- Wait for termination with a bounded timeout.
- If ordinary quit fails, offer Force Quit only as a separate explicit action.
- Re-run association checks that depend on process state.
- Do not terminate unrelated helpers automatically.
If a related helper remains running:
- Explain which component is active.
- Skip it or require the vendor flow.
- Do not silently kill system or privileged processes.
Privileged helpers and system extensions
The MVP should be conservative.
Detect and display:
- Privileged helper tools
- Launch daemons
- System extensions
- Driver extensions
- Network extensions
- Audio components
- Finder extensions
- Browser extensions
Possible outcomes:
Can move to Trash after administrator approval
Vendor uninstaller recommended
Manual removal required
Protected and unsupported
Do not claim successful uninstall while active privileged components remain.
A full supported-removal flow for system extensions or drivers requires separate research and may remain out of scope.
Workspace UX
Suggested sections:
Application
Verified Data
Shared or Possible Data
User-Created or Ambiguous Data
Protected or Manual Components
Removal Plan
History
Candidate row
Show:
- Selection
- Name
- Full path
- Size
- Data class
- Confidence
- Evidence summary
- Other applications that may share it
- Safety status
Expanded details:
- Every evidence item
- Bundle/team/app-group identity
- Why selected or unselected
- What may be lost
- Last modified
- Reveal in Finder
- Quick Look where safe
- Copy path
Language
Prefer:
Verified cache
Exact preference domain
Shared vendor data
Possible associated folder
Contains user-created content
Vendor removal required
Avoid:
Junk
Safe leftover
Useless file
Guaranteed removable
unless the evidence supports the exact statement.
Removal plan
Build an immutable plan from:
- Selected application identity
- Scan artifact
- User-selected candidate IDs
- Current installed-app oracle
- Current process state
The plan should:
- Remove parent/child duplicates.
- Refuse paths outside reviewed roots.
- Refuse protected roots.
- Refuse candidates whose identity changed.
- Re-evaluate claims by other installed apps.
- Re-evaluate shared app groups.
- Separate package-manager and vendor steps.
- Record expected administrator requirements.
- Show exact item count and estimated size.
The UI must present the plan before execution.
Trash-first execution
Default behavior:
- Move the application bundle to Trash.
- Move selected eligible associated files to Trash.
- Do not empty Trash.
- Do not fall back silently to permanent deletion.
- Record each result.
- Support cancellation between items.
- Preserve original path and resulting Trash/staged name where available.
Administrator-required items:
- Use a standard, explicit macOS authorization path.
- Batch requests where safe.
- Never accept arbitrary privileged shell input from a profile or deep link.
- Fail closed when authorization is denied.
If a selected item cannot be moved safely:
- Skip it.
- Explain why.
- Do not report the uninstall as complete without qualification.
Structured result
Show:
Application moved to Trash
12 associated items moved
3 shared items left in place
1 helper requires vendor removal
2 items changed since review
0 permanent deletions
Outcome categories:
- Trashed
- Skipped by user
- Shared and retained
- Protected
- Changed since scan
- Still in use
- Authorization denied
- Vendor action required
- Failed
- Already absent
Do not collapse partial success into a generic success state.
History
Keep a bounded, local uninstall history.
Record:
- Application name and bundle ID
- Version
- Timestamp
- Installation source
- Selected item count
- Estimated and actual result size where available
- Per-item outcome
- Original path
- Trash/staged name
- Manual steps remaining
Do not store file contents, license data, or unrelated directory listings.
History should support:
- Expand details
- Reveal retained item
- Copy redacted diagnostics
- Clear history
- Highlight incomplete uninstalls
Canonical actions and Command Palette
Potential actions:
- Open App Uninstaller
- Choose Application to Review
- Review Installed Application…
- Open Latest Uninstall Review
- Cancel Active Association Scan
Possible future live Command Palette behavior:
Select an application result
→ Command-K actions
→ Review in App Uninstaller
Requirements:
- Review actions are foreground-interactive.
- No canonical action directly uninstalls without review.
- No uninstall action is eligible for automatic workflows.
- No uninstall action is exposed through Run Links.
- Command Palette is the primary global launcher.
- The same scanner and plan are used regardless of entry point.
Relationship to Storage Explorer
Storage Explorer may provide reusable primitives:
File identity
Physical path resolution
Bounded directory traversal
Allocated-size calculation
Mount-boundary detection
Trash plan execution
Progress
History envelope
App Uninstaller owns:
Application identity
Installed-app oracle
Association evidence
Confidence
Data sensitivity
Default selection
Vendor/package-manager routing
Uninstall UX
Do not make Storage Explorer classify application ownership.
Relationship to Disk Cleanup
Disk Cleanup may identify generic known caches and leftovers through its own rules.
App Uninstaller should not blindly import those results.
A future integration may show:
Also covered by Disk Cleanup rule: Chrome cache
only when:
- The exact physical path matches.
- The Disk Cleanup rule is installed and available.
- The association does not broaden App Uninstaller authority.
- The user still reviews the item.
Independent implementation and provenance
- Implement all association logic from first principles.
- Use bundle metadata, container metadata, code signatures, package receipts, launchd configuration, and reproducible tests.
- Do not copy third-party source.
- Do not copy curated association path lists or distinctive heuristics without a compatible dependency and license review.
- Record external research that materially informs a rule.
- Treat every new association source as safety-sensitive.
- Keep third-party notices complete.
Proposed implementation phases
Phase 0 — Association research
Phase 1 — Read-only review MVP
Phase 2 — Removal plan and user-domain Trash
Phase 3 — Package managers and privileged components
Phase 4 — Advanced integrations
Testing
Application identity
- Standard app
- App Store app
- Homebrew cask app
- Unsigned app
- Nested app
- Running app
- System app
- Managed app
- MacTools itself
- App replaced after selection
Evidence
- Exact bundle ID
- Container metadata
- Preference domain
- Saved state
- Embedded login item
- Launch item executable
- Team ID
- App group
- Shared vendor directory
- Filename similarity
- Multiple evidence sources
- Conflicting evidence
- Another installed app claims the item
Selection policy
- Verified cache selected
- Verified preference selected
- Shared data unselected
- Application Support conservative
- User documents unselected
- App Group unselected
- Protected item cannot be selected
- Unknown metadata never upgrades confidence
Execution
- Ordinary quit
- Quit timeout
- Force Quit separate confirmation
- Trash app
- Trash associated file
- Authorization denied
- Candidate changed
- Candidate missing
- Symlink escape
- Mount boundary
- Shared ownership appears after scan
- Partial failure
- Cancellation
- Vendor flow required
- Homebrew handoff
History and privacy
- Run summary
- Incomplete uninstall attention
- Path redaction
- Bounded retention
- Clear history
- No file content
- No license data
- No network activity
UX and accessibility
- Drag and drop
- Choose Application
- Installed app browser
- Confidence grouping
- Expand evidence
- Keyboard selection
- VoiceOver
- Long localization
- Light and Dark appearance
- Narrow workspace
Acceptance criteria
Open questions
- Which confidence levels and names are clearest to nontechnical users?
- Which verified associated-data classes should start selected?
- Should exact Application Support matches remain unselected by default?
- How should App Groups and Group Containers be explained?
- Which installed-app roots should the ownership oracle scan?
- How reliable is team-identifier evidence across vendor suites?
- Should Homebrew removal be executed from this plugin or handed to the Homebrew plugin?
- How should App Store receipt evidence affect removal?
- Which privileged-helper cases can MacTools safely support?
- Should the MVP be read-only before adding Trash execution?
- Which narrow storage primitives should be shared with Storage Explorer?
- Should post-uninstall orphan review be part of this plugin or remain a separate future flow?
Summary
Add a standalone App Uninstaller plugin that removes a selected application and helps the user review files associated with it.
The defining product principle is evidence and confidence, not aggressive deletion.
Every associated item should explain:
Illustrative confidence groups:
The user must review the exact application and associated files before removal.
This plugin should be built after the Storage Explorer scanner and shared file-safety primitives are sufficiently proven, but the product boundary can be agreed in advance.
Motivation
Dragging an application to Trash often leaves behind:
However, filename similarity alone is not enough to prove ownership.
Aggressive uninstaller tools risk removing:
MacTools should provide a conservative uninstall workflow that makes association evidence visible and keeps the user in control.
Product boundary
App Uninstaller owns:
It does not own:
Relationship to other plugins:
Goals
Non-goals
Dependency and sequencing
This proposal should be tracked separately but implemented after:
App Uninstaller must not be implemented merely by copying a list of common
~/Libraryfolders and matching names.Primary user flow
Application selection
Support:
.appbundle into the workspaceValidate:
Show:
Do not require code-signing identity for every app, but use it as evidence where available.
Installation-source detection
Potential sources:
Homebrew
If the selected app is managed by a Homebrew cask:
Vendor uninstaller
If an application contains or installs a known vendor uninstaller:
Managed or system application
Association evidence
Define structured evidence rather than a Boolean “belongs to app.”
Illustrative model:
Each candidate may carry several pieces of evidence.
Evidence strength must be explicit and testable.
Confidence model
Illustrative classification:
Verified
Examples:
Default:
Strong
Examples:
Default:
Shared
Examples:
Default:
Possible
Examples:
Default:
Ambiguous
Examples:
Default:
Protected
Examples:
Default:
Data sensitivity
Confidence that a file belongs to an app is separate from whether it is safe to remove.
Illustrative model:
Suggested default-selection policy:
The exact matrix should be finalized after research and tests.
Reviewed association roots
Scan only fixed, reviewed roots.
Potential user-domain roots to research:
Potential local-domain roots:
Inclusion here is not approval to delete all matches.
For every root, the implementation must define:
Do not recursively scan arbitrary filesystem roots.
Other installed applications as an ownership oracle
Before presenting an associated item:
The oracle must be testable with fixtures.
Running application behavior
If the selected application is running:
If a related helper remains running:
Privileged helpers and system extensions
The MVP should be conservative.
Detect and display:
Possible outcomes:
Do not claim successful uninstall while active privileged components remain.
A full supported-removal flow for system extensions or drivers requires separate research and may remain out of scope.
Workspace UX
Suggested sections:
Candidate row
Show:
Expanded details:
Language
Prefer:
Avoid:
unless the evidence supports the exact statement.
Removal plan
Build an immutable plan from:
The plan should:
The UI must present the plan before execution.
Trash-first execution
Default behavior:
Administrator-required items:
If a selected item cannot be moved safely:
Structured result
Show:
Outcome categories:
Do not collapse partial success into a generic success state.
History
Keep a bounded, local uninstall history.
Record:
Do not store file contents, license data, or unrelated directory listings.
History should support:
Canonical actions and Command Palette
Potential actions:
Possible future live Command Palette behavior:
Requirements:
Relationship to Storage Explorer
Storage Explorer may provide reusable primitives:
App Uninstaller owns:
Do not make Storage Explorer classify application ownership.
Relationship to Disk Cleanup
Disk Cleanup may identify generic known caches and leftovers through its own rules.
App Uninstaller should not blindly import those results.
A future integration may show:
only when:
Independent implementation and provenance
Proposed implementation phases
Phase 0 — Association research
Phase 1 — Read-only review MVP
Phase 2 — Removal plan and user-domain Trash
Phase 3 — Package managers and privileged components
Phase 4 — Advanced integrations
Testing
Application identity
Evidence
Selection policy
Execution
History and privacy
UX and accessibility
Acceptance criteria
Open questions