A small, practical Rust CLI for everyday performance and productivity utilities.
The binary is named tiny. The project is intentionally minimal so it stays
easy to read while it grows.
- Keep dependencies tight (
clap,anyhow,serde,sysinfo). - Separate CLI parsing (
src/cli.rs) from command execution (src/commands/). - Provide useful, real-world commands that are safe by default.
cargo build
cargo run -- --helpcargo run -- sysReports OS, host, uptime, CPU count and model, memory usage, and per-disk usage.
cargo run -- scan
cargo run -- scan --min-size-mb 100 --older-than-days 30Scans ~/Downloads, ~/Desktop, and ~/Documents. Reports the largest files
and the oldest files that exceed the thresholds. scan is strictly
read-only — it never deletes anything. For cleanup, see clean below.
Options:
--min-size-mb(default100): report files at or above this size.--older-than-days(default90): report files older than this many days.
tiny clean # picker → plan → action menu
tiny clean --dry-run # show plan and exit, no prompt
tiny clean --include-review # also list review-risk caches
tiny clean --include-destructive # also list Trash + tmutil snapshots
tiny clean --review-paths # drill-down picker per path before action
tiny clean --idle-days 60 # raise idle threshold for project caches
tiny clean --category node-modules # interactive, scoped to one category
tiny clean --category trash --hard # the only sanctioned way to empty Trash
TINY_CONFIRM_HARD=1 tiny clean --category cargo --hard -y # non-interactive permanent deleteCategories are grouped into three families in the picker (31 total):
Dev caches (17) — cargo, npm, pnpm, yarn, node-modules,
python-caches, rust-targets, gradle-maven, jetbrains, vscode,
ios-simulators, android-sdk, go-cache, docker, xcode-derived,
xcode-archives, xcode-devicesupport.
User storage (6) — downloads-old, screenshots-old,
mail-attachments, streaming-caches, chat-caches, browser-caches.
System leftovers (8) — user-logs, user-caches, trash,
quarantine, crash-reports, app-orphans, time-machine-local,
font-quicklook-caches.
The default picker shows only safe categories. Add --include-review
for developer caches and other items that may want manual review. Add
--include-destructive to surface trash and time-machine-local
(snapshots are not recoverable). Use --category <id> to target a single
category — repeating the flag is fine (--category user-logs --category xcode-derived).
Flags that affect discovery:
--idle-days N(default30): only flag project caches whose project manifest hasn't been touched in the lastNdays. Applies tonode-modules,python-caches,rust-targets,android-sdk,downloads-old,screenshots-old.Nmust be> 0.--review-paths: after the family picker, opens a per-path drill-down so you can deselect individual paths before the action runs. Also available mid-flow as the Review paths entry in the action menu.
Safety model:
- Default action is Move to Trash (recoverable).
--hardis permanent; without-yit requires a Y/n confirmation, with-yit requiresTINY_CONFIRM_HARD=1in the environment.--yesrequires--categoryso the scope is always explicit.- The Trash provider is wired so only
Hard deletereaches it (mapped to Finder's empty-trash);Move to Trashfor the trash category is rejected. - Discovery skips a category whose owning app is currently running
(e.g.
xcode-derivedwhen Xcode is open). - All filesystem walks are symlink-safe — symlinked directories are never followed, so we cannot delete data outside the listed paths.
Note: even Move to Trash is destructive if macOS "Empty Trash automatically" (System Settings → General → Storage) is on. Use
--dry-runfirst or disable that setting.
scan vs clean at a glance: scan is read-only and surfaces personal
files in ~/Downloads / ~/Desktop / ~/Documents so you can review and
decide. clean is interactive deletion of developer caches and recoverable
data. They are intentionally separate — personal files never appear in
clean.
cargo run -- focus --minutes 25
cargo run -- focus --minutes 50 --label "deep work"Runs a synchronous timer with a simple progress bar. When the session ends,
the entry is appended to ~/.tiny-cli/focus-sessions.json so you have a
record of completed sessions.
tiny uninstall # picker → report → action menu
tiny uninstall AltTab # report → action menu
tiny uninstall AltTab --dry-run # report only, no prompt
tiny uninstall AltTab -y # skip menu, move to Trash immediately
tiny uninstall AltTab --hard -y # skip menu, rm -rf (advanced)
tiny uninstall AltTab --shallow # only /Applications/<Name>.app
tiny uninstall AltTab --leftovers-only # only ~/Library cleanupAfter the report, an action menu lets you choose:
- Move to Trash (recoverable) — default, safe
- Dry-run (no changes)
- Hard delete (NOT recoverable) — extra confirm prompt before touching anything
- Cancel
Safety:
- Default action highlights "Move to Trash" — you must press Enter, nothing auto-runs.
- Trash is recoverable; hard delete requires a separate
[y/N]confirmation. - Refuses system apps (
com.apple.*) and Homebrew casks (usebrew uninstall --cask; pass--forceto override).
Picker sorts: --sort=last-used (default), size, name.
files— richer filesystem analytics (duplicates, by-extension breakdowns).doctor— check common dev environment issues (PATH, dotfiles, tools).today— daily summary combining focus log and calendar-style notes.