---
name: mole-cli
description: "Drive the Mole CLI (`mo`) safely from an agent: which command answers which question, the machine-readable surfaces (analyze --json, status --json, history --json, the dry-run path list), and the rules that keep an automated run from deleting something the user wanted. Read before running any `mo` command on a user's Mac."
homepage: https://mole.fit
repository: https://github.com/tw93/Mole
license: GPL-3.0
platform: macOS 14+
---

# Using Mole from an agent

Mole (`mo`) cleans, uninstalls, analyzes, optimizes, and monitors a Mac. Install
it with `brew install mole`; it is free and open source under GPL-3.0. The paid
Mac app at https://mole.fit is a separate native implementation with similar
cleanup categories and a narrower deletion scope. It is not agent-drivable, so
an agent works through the CLI.

Mole is a real deletion tool operating on someone's live machine, so the way an
agent uses it differs from the way a human does: never guess, never let a TUI
decide, and never let a destructive command run without the user having seen the
list.

## The rules

1. **Preview before you delete. Always.** Every destructive command takes
   `--dry-run`. Run it, read the result, show the user what would go, and only
   then offer the real run. An agent that runs `mo clean` before `mo clean
   --dry-run` has skipped the only step the user can veto.
2. **The user runs the destructive command, not you**, unless they explicitly
   asked you to do it in the current turn. "Clean my Mac" is such an ask;
   "why is my disk full" is not.
3. **Never parse a TUI frame.** Interactive `mo analyze` and terminal-attached
   `mo status` are full-screen programs whose output is drawn, not printed.
   Use `mo analyze --json`, `mo status --json`, or `mo status --watch` instead.
4. **Never invent flags.** The command surface is small and listed here; if
   something is not on this page, run `mo <command> --help` and read it, do not
   assume a `--yes` or `--force` exists.
5. **Protection is a whitelist, not an argument.** If the user wants a cache
   kept, the answer is `mo clean --whitelist`, not a hand-rolled `find`. Never
   work around Mole's safety layer with raw `rm`.

## What answers which question

| The user asks | Command |
|---|---|
| "What is eating my disk?" | `mo analyze --json` (whole disk) or `mo analyze <path> --json` |
| "Free up space" | `mo clean --dry-run`, review, then `mo clean` |
| "Remove this app completely" | `mo uninstall --dry-run` then `mo uninstall` |
| "My Mac feels slow" / caches look broken | `mo optimize --dry-run` then `mo optimize` |
| "Clean up my old projects" | `mo purge --dry-run` then `mo purge` |
| "Get rid of downloaded installers" | `mo installer --dry-run` then `mo installer` |
| "What did Mole delete?" | `mo history --json --limit 20` |
| One CPU / memory / disk / network snapshot | `mo status --json` |
| A short time series for diagnosis | `mo status --watch --interval 1s` (NDJSON; stop after enough samples) |

## Machine-readable surfaces

These four surfaces are the agent-facing API. Everything else is for humans.

**Disk usage.** `mo analyze --json` prints one JSON object: `path`, `overview`,
and `entries[]` of `{name, path, size, is_dir, insight}`. `size` is bytes.
`insight: true` marks an entry Mole considers noteworthy (a large iOS backup, a
runaway cache). Pass a path to scope it: `mo analyze ~/Library --json`.

**Cleanup history.** `mo history --json [--limit N]` (N is 1-200) prints
`logs` (paths of the operations and deletions logs) plus `sessions[]` with
`command`, `started_at`, `items`, `size`, and an `actions` breakdown of
removed / trashed / skipped / failed. This is how you answer "did Mole delete
my file" without guessing: the deletions log has the paths.

**The dry-run path list.** `mo clean --dry-run` prints a summary to the
terminal and writes every candidate path to `~/.config/mole/clean-list.txt`.
Read that file, not the terminal output, when you need to reason about or show
the user exactly what a real run would remove. This list is clean-only: `mo
purge --dry-run` and `mo installer --dry-run` print their candidates to the
terminal and write no file.

**System status.** `mo status --json` prints one metrics snapshot. It also
switches to JSON automatically when stdout is not a TTY, but pass `--json`
explicitly in scripts so intent stays obvious. `mo status --watch --interval
1s` emits one complete JSON object per line from a warm collector. Bound the
watch duration or sample count and terminate it after collecting the evidence
the user asked for; do not leave an unbounded monitor running in the background.

## Command notes worth knowing

- `mo clean` also sweeps leftovers from apps the user already deleted. It does
  not touch installed apps; that is `mo uninstall`.
- `mo clean --external <path>` cleans macOS metadata off an external volume.
- `mo purge` scans rebuildable project artifacts (`target/`, `build/`,
  `dist/`, `.next/`) and downloaded dependency directories (`node_modules/`,
  `Pods/`, `venv/`). Because dependency restoration needs a network and may not
  reproduce the same resolved state, always show the dry-run list and treat
  recent projects conservatively. `mo purge --paths` configures which
  directories are scanned; `--include-empty` shows zero-size candidates.
- `mo optimize` refreshes caches and system services. It is the one destructive
  command whose effects are not "files disappear", so say what it will do
  before running it.
- `mo update` self-updates; `mo update --nightly` installs unreleased `main`.
  Do not run either on a user's behalf without being asked.
- `--debug` on any command prints the detailed operation log. Reach for it when
  a command silently did nothing; do not leave it on in normal use.

## When something goes wrong

**`mo clean` deletions are permanent by default.** Cache cleanup removes files
rather than moving them to the Trash, so there is usually nothing to restore.
That is exactly why rule 1 exists: the dry-run is the undo. `mo uninstall` is
the exception: it routes the app and its leftovers through the Trash, so an
uninstalled app is recoverable until the Trash is emptied.

What you do have is a record. `mo history --json` names the deletions log, and
every deletion is one tab-separated line in it: timestamp, mode, size, status,
path. So when a user asks "did Mole take my file", read the log and answer with
the actual line instead of guessing. Then add the path to the whitelist (`mo
clean --whitelist`) so the next run leaves it alone.
