Safe Uninstall
Safely identify, investigate, and remove macOS programs through a structured workflow: target identification, comprehensive investigation, removal approach selection, risk-assessed execution, and verification.
Dependency
This skill delegates execution of irreversible operations (file deletion, service
removal) to Prosoche (/attend). The epistemic-protocols plugin must be
installed for safe execution gating.
Workflow Overview
Target Identification → Investigation → Report → Approach Selection → /attend Execution → Verification
Phase 1: Target Identification
Support two entry points depending on user context.
A. Resource Scan
When the user reports high resource usage, unknown processes, or Activity Monitor concerns, start with a resource scan to identify the target:
- Scan top processes by memory and CPU:
ps aux --sort=-%mem | head -20 ps aux --sort=-%cpu | head -20 - Present non-system processes consuming significant resources (filter out kernel_task, WindowServer, and other known macOS system processes)
- For unknown processes, gather identification signals:
codesign -dv --verbose=2 <binary_path> 2>&1 # vendor identity - User selects target process for investigation
B. Direct Specification
When the user names a specific process or program, confirm the target and derive
search patterns (see references/investigation-paths.md for pattern derivation).
Phase 2: Comprehensive Investigation
Delegate investigation to a subagent for efficient parallel execution.
Derive multiple search patterns from the target: binary path components, process name, vendor name, product name. Use case-insensitive grep across ALL locations.
Investigation Checklist
Every investigation must cover all of these (no shortcuts):
| Category | Command Pattern |
|---|---|
| Running processes | ps aux | grep -i -E "<patterns>" |
| LaunchDaemons | ls /Library/LaunchDaemons/ | grep -i -E "<patterns>" |
| LaunchAgents (system) | ls /Library/LaunchAgents/ | grep -i -E "<patterns>" |
| LaunchAgents (user) | ls ~/Library/LaunchAgents/ | grep -i -E "<patterns>" |
| Application Support | ls "/Library/Application Support/" | grep -i -E "<patterns>" |
| Applications | ls /Applications/ | grep -i -E "<patterns>" |
| Kernel Extensions | ls /Library/Extensions/ | grep -i -E "<patterns>" |
| System Extensions | ls /Library/SystemExtensions/ | grep -i -E "<patterns>" |
| Privileged Helpers | ls /Library/PrivilegedHelperTools/ | grep -i -E "<patterns>" |
| Browser Plugins | ls "/Library/Internet Plug-Ins/" | grep -i -E "<patterns>" |
| Login Items | osascript -e 'tell application "System Events" to get the name of every login item' |
| Package Receipts | pkgutil --pkgs | grep -i -E "<patterns>" |
| Uninstaller search | find /Applications -iname "*uninstall*" | grep -i -E "<patterns>" |
For each LaunchDaemon/Agent plist found, read it to extract KeepAlive, RunAtLoad, and Program properties — these determine the removal strategy.
Also check for companion frameworks in sibling Application Support directories
(see references/investigation-paths.md for known companion patterns).
Phase 3: Report
Present findings as a structured report so the user can make an informed decision.
Template:
## [Program Name] — Investigation Report
**Running Processes:**
| PID | User | %MEM | %CPU | Binary Path |
|-----|------|------|------|-------------|
**LaunchDaemons/Agents (KeepAlive services respawn after kill):**
| plist Path | KeepAlive | RunAtLoad |
|------------|-----------|-----------|
**Installed Files:**
| Category | Path | Notes |
|----------|------|-------|
**Uninstaller:** [path or "Not found"]
**Package Receipts:** [list or "None"]
**Companion Frameworks:** [list or "None"]
Phase 4: Removal Approach Selection
Present options based on findings:
- Official Uninstaller (when found) — Run first, then verify and clean up leftovers. The vendor understands their own installation layout best.
- Manual Removal — Direct removal of all identified components. Appropriate when no uninstaller exists.
Phase 5: Execution via Prosoche
Invoke /attend with the removal task list. Prosoche will classify each task
for risk and gate irreversible operations through user judgment.
Typical task ordering (KeepAlive-aware):
- Unload services —
launchctl bootout/unloadfor KeepAlive plist (before kill) - Run uninstaller —
open /path/to/Uninstaller.app(if selected) - Verify post-uninstaller — check what remains
- Kill remaining processes —
kill <PID> - Remove remaining service registrations —
launchctl remove <label> - Delete files —
sudo rm -rffor remaining directories - Remove browser plugins —
sudo rmsymlinks and plugin bundles - Forget package receipts —
sudo pkgutil --forget <id>
Handling sudo Failures
Non-interactive terminal sessions cannot accept sudo passwords. When sudo operations fail:
- Complete all non-sudo operations (kill, launchctl remove)
- Collect failed sudo commands into a single executable block
- Present to user as a copy-paste command with
!prefix for Claude Code prompt - After user executes, proceed to verification
Phase 6: Verification
Run a comprehensive post-removal check against all previously identified items:
- Processes:
ps aux | grep -i -E "<patterns>" | grep -v grep - Services:
launchctl list 2>/dev/null | grep -i -E "<patterns>" - Files: Check each previously found path exists
- Package receipts:
pkgutil --pkgs | grep -i -E "<patterns>"
Present final status:
## Removal Verification
| Item | Status |
|------|--------|
| [item description] | [Removed] / [Remaining] |
**Result:** [N] items removed, [M] remaining
Edge Cases
- Process not running: Search by name in file system (
mdfind -name "<name>") to find installed-but-inactive programs - Companion frameworks: Detect related vendor directories in Application Support and include in removal scope (present to user for confirmation)
- KeepAlive services: Always unload via launchctl before killing — otherwise launchd immediately respawns the process
- Modern macOS kext restrictions: Kernel extensions may be present on disk but not loaded (blocked by SIP). Note in report; still remove files
- Broken symlinks: Partial uninstalls may leave dangling symlinks (especially
browser plugins). Detect via
ls -laand include in cleanup - Multiple user contexts: Some programs install both root-level (LaunchDaemon) and user-level (LaunchAgent) services. Ensure both are addressed