A terminal UI (TUI) for exploring, auditing, and cleaning developer cache directories on macOS and Linux. Scan cached packages for known CVEs, find outdated dependencies, and reclaim disk space — all from one tool.
Developer machines accumulate tens of gigabytes of invisible cache data — ML models, package archives, build artifacts, downloaded bottles. ccmd makes it all visible, scannable for vulnerabilities, and safely deletable.
- ML models (HuggingFace, PyTorch, Whisper) — tens of GB you forgot about
- Package caches (pip, uv, npm, Cargo, Homebrew) — old versions with known CVEs
- npm supply chain risk — transitive deps with install scripts hiding in npx cache
- Build artifacts (pre-commit hooks, Prisma engines) — stale and re-downloadable
ccmd gives you a single view across all of them with security scanning built in.
brew tap juliensimon/tap
brew install ccmdcargo install ccmdcargo binstall ccmdgit clone https://github.com/juliensimon/cache-commander
cd cache-commander
cargo build --release
./target/release/ccmdDownload from GitHub Releases — available for macOS (x86_64, Apple Silicon) and Linux (x86_64, aarch64).
ccmd # browse all default cache locations
ccmd --vulncheck # scan for CVEs on startup
ccmd --versioncheck # check for outdated packages on startup
ccmd --root ~/.cache/huggingface # scan a specific directory- Two-pane TUI — navigable tree on the left, details on the right
- 12 cache providers — semantic names instead of hash directories
- Safety levels — green (safe to delete), yellow (may cause rebuilds), red (contains state)
- Sort by size, name, or last modified
- Search with
/— case-insensitive filter across the tree
- Vulnerability scanning — queries OSV.dev for known CVEs in cached packages
- Version checking — compares cached versions against PyPI, crates.io, and npm registries
- Fix versions — shows which version resolves each CVE, with upgrade commands
- npm supply chain — scans transitive deps in npx cache, flags packages with install scripts
- Filter by status — dim non-vulnerable items to focus on what matters
- Copy upgrade command — press
cto copypip install pkg>=versionto clipboard
- Mark and delete — Space to mark,
dto delete with confirmation - Bulk mark —
mmarks all visible (non-dimmed) items after filtering - Workflow: scan (
V) → filter (f) → mark all (m) → delete (d)
| Provider | Location | Semantic names |
|---|---|---|
| HuggingFace | ~/.cache/huggingface |
Model/dataset names, revisions |
| pip | ~/.cache/pip |
Wheel packages |
| uv | ~/.cache/uv |
Package names via dist-info |
| npm | ~/.npm |
npx packages + transitive node_modules deps |
| Homebrew | ~/Library/Caches/Homebrew |
Bottles, casks |
| Cargo | ~/.cargo/registry |
Crate names and versions |
| pre-commit | ~/.cache/pre-commit |
Hook repo names |
| Whisper | ~/.cache/whisper |
Model names (Large v3, Tiny, etc.) |
| GitHub CLI | ~/.cache/gh |
Workflow run logs |
| PyTorch | ~/.cache/torch |
Model checkpoints |
| Chroma | ~/.cache/chroma |
Embedding models |
| Prisma | ~/.cache/prisma |
Engine versions |
| Key | Action |
|---|---|
↑/k ↓/j |
Move up / down |
→/l ←/h |
Expand / Collapse (or go to parent) |
Enter |
Toggle expand |
g / G |
Jump to top / bottom |
/ |
Search — type to filter, Enter to keep, Esc to clear |
| Key | Action |
|---|---|
v / V |
Scan selected / all for CVEs |
o / O |
Check selected / all for outdated versions |
f |
Cycle status filter: none → vuln → outdated → both |
c |
Copy upgrade command to clipboard |
| Key | Action |
|---|---|
Space |
Mark / unmark item |
m |
Mark all visible items (with confirmation) |
u |
Unmark all |
d / D |
Delete marked items |
| Key | Action |
|---|---|
s |
Cycle sort (size → name → modified) |
r / R |
Refresh selected / all |
? |
Help overlay |
q / Ctrl+C |
Quit |
Create ~/.config/ccmd/config.toml:
roots = ["~/.cache", "~/Library/Caches", "~/.npm", "~/.cargo/registry"]
sort_by = "size" # size | name | modified
sort_desc = true
confirm_delete = true
[vulncheck]
enabled = false # set true to scan on startup
[versioncheck]
enabled = false # set true to check on startupCLI flags override config file values.
ccmd walks your cache directories and identifies providers by directory name and structure. Each provider has custom logic to decode semantic names — for example, HuggingFace stores models in directories like models--meta-llama--Llama-3.1-8B, which ccmd displays as [model] meta-llama/Llama-3.1-8B.
When you press V (or pass --vulncheck):
ccmdwalks the cache tree to discover packages with identifiable name + version- Sends a batch query to the OSV.dev API (chunked to 100 packages per request)
- For each vulnerability found, fetches the detailed advisory to extract fix versions
- Filters out vulnerabilities already fixed by the installed version
- Displays results in the detail panel with fix version, upgrade command, and advisory link
The npx cache (~/.npm/_npx/) contains full node_modules trees. ccmd scans every transitive dependency for:
- Known CVEs via OSV.dev
- Install scripts (
preinstall,install,postinstall) — the primary vector for supply chain attacks - Dependency depth — whether a package is a direct dependency or deep transitive
The intended workflow for cleaning vulnerable packages:
- Scan: Press
Vto scan all packages for CVEs - Filter: Press
fto show only vulnerable items (non-matching items are dimmed) - Review: Navigate to see fix versions and upgrade commands
- Mark: Press
mto mark all vulnerable items for deletion - Delete: Press
dto delete — frees space and forces fresh downloads
src/
├── main.rs # CLI bootstrap, terminal setup
├── config.rs # TOML config + CLI flag merging
├── app.rs # Event loop, key handling, rendering
├── tree/
│ ├── node.rs # TreeNode, CacheKind enum
│ └── state.rs # TreeState, FilterMode, visibility, marking
├── scanner/
│ ├── mod.rs # Background scan orchestrator, package discovery
│ └── walker.rs # Directory traversal, size calculation
├── providers/
│ ├── mod.rs # Provider dispatch, safety levels, upgrade commands
│ ├── huggingface.rs # HuggingFace Hub semantic decoding
│ ├── pip.rs, uv.rs # Python package providers
│ ├── npm.rs # npm + npx + node_modules scanning
│ ├── cargo.rs # Rust crate provider
│ └── ... # 7 more providers
├── security/
│ ├── mod.rs # Scan orchestration, vulnerability filtering
│ ├── osv.rs # OSV.dev API, version comparison, fix extraction
│ └── registry.rs # PyPI, crates.io, npm registry lookups
└── ui/
├── tree_panel.rs # Left pane — tree with status icons
├── detail_panel.rs # Right pane — metadata, vulns, guidance
├── dialogs.rs # Delete confirmation, help overlay
└── theme.rs # Color and style constants
- No async runtime — pure
std::thread+mpsc::channel - Flat arena tree — avoids recursive structs and borrow checker issues
- Background scanning — UI stays responsive during API calls and directory walks
Contributions and feedback are welcome!
- Bug reports & feature requests — open an issue
- Pull requests — fork the repo, create a branch, and submit a PR. Please run
cargo fmtandcargo clippybefore submitting. - New cache providers — adding support for a new tool? See
src/providers/for examples. Each provider is a single file with a detection function and a name decoder. - Questions & ideas — feel free to start a discussion or reach out directly.
Julien Simon — julien@julien.org — github.com/juliensimon
MIT — see LICENSE for details.
