DEV Community

Cover image for SlothSort πŸ¦₯ β€” An Offline AI File Organizer That Rewards Laziness
D9292S
D9292S

Posted on AI-assisted

SlothSort πŸ¦₯ β€” An Offline AI File Organizer That Rewards Laziness

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission πŸ¦₯

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

Most developers have a Downloads folder that looks like a digital landfill: dozens of document(1).pdf, Screenshot 2026-10-21.png, and camera uploads like IMG_20241019_142356.jpg.

Organizing them manually is tedious, and simple extension-moving scripts fail because they can't understand what a file actually contains.

In honor of International Sloth Day and this week's theme β€” Slow and Steady: build something with open-source AI that rewards laziness β€” I built SlothSort.

SlothSort is a lightweight CLI that uses a local open-weight model (llama3.2) via Ollama to scan messy folders, understand file context, clean up names into readable kebab-case, and sort everything into category folders.

Core Features

  • 🧠 Contextual Sorting: Classifies files using both extensions and text header previews (peeking at the first few lines of text/CSV/code).
  • 🏷️ Clean Renaming: Standardizes messy timestamps and downloads (Screenshot 2026-10-21 000814.png β†’ screenshot-2026-10-21-000814.png).
  • πŸ¦₯ True Sloth Mode (--watch): Runs quietly in the background, tidying up new downloads automatically while you take a nap.
  • πŸ“‘ Deduplication (--dedupe): Uses fast SHA-256 matching to isolate duplicate downloads (invoice (1).pdf) into a Duplicates/ folder.
  • πŸ›‘οΈ Defensive by Default: Safe dry-run previews by default, collision protection (-1, -2), and instant 1-command rollback (slothsort undo).

Demo

Here is a live terminal session running against a messy directory:

$ slothsort ~/Downloads --dedupe

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ πŸ¦₯ slothsort v1.0.0 ────────────────┐
β”‚  πŸ“‚ /Users/deepa/Downloads                          β”‚
β”‚  βš™οΈ   DRY-RUN  Model: llama3.2 β€’ Offline Inference  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Taxonomy Breakdown                                                          
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Category           β”‚    Files β”‚       Size β”‚    Renamed β”‚      Inference β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ πŸ“¦ Archives        β”‚        3 β”‚    45.0 MB β”‚          1 β”‚      1/3 local β”‚
β”‚ 🎡 Audio           β”‚        2 β”‚    18.5 MB β”‚          2 β”‚          rules β”‚
β”‚ πŸ’» Code            β”‚        5 β”‚     0.2 MB β”‚          2 β”‚          rules β”‚
β”‚ πŸ“Š Data            β”‚        3 β”‚     1.1 MB β”‚          3 β”‚          rules β”‚
β”‚ 🎨 Design          β”‚        2 β”‚    24.0 MB β”‚          2 β”‚          rules β”‚
β”‚ πŸ“„ Documents       β”‚        7 β”‚     2.8 MB β”‚          6 β”‚      1/7 local β”‚
β”‚ πŸ“‘ Duplicates      β”‚        2 β”‚     1.4 MB β”‚          0 β”‚         dedupe β”‚
β”‚ πŸ–ΌοΈ  Images         β”‚        4 β”‚     6.9 MB β”‚          4 β”‚          rules β”‚
β”‚ βš™οΈ  Installers     β”‚        2 β”‚   157.9 MB β”‚          2 β”‚          rules β”‚
β”‚ 🎬 Videos          β”‚        1 β”‚   240.0 MB β”‚          1 β”‚      1/1 local β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Total              β”‚       31 β”‚   497.8 MB β”‚         23 β”‚              β€” β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€ Proposed Directory Hierarchy ──────────────────────────────────────────────┐
β”‚ πŸ“ Downloads/                                                               β”‚
β”‚ β”œβ”€β”€ πŸ“„ Documents/ (7 files)                                                 β”‚
β”‚ β”‚   β”œβ”€β”€ analytics_october_metrics.csv β†’ analytics-october-metrics.csv β€’     β”‚
β”‚ β”‚   β”‚   Financial data report                                               β”‚
β”‚ β”‚   β”œβ”€β”€ budget_forecast_q4.xlsx β†’ budget-forecast-q4.xlsx β€’ standardized    β”‚
β”‚ β”‚   β”‚   kebab-case                                                          β”‚
β”‚ β”‚   β”œβ”€β”€ final_report_FINAL_v3_USETHISONE.docx β†’                             β”‚
β”‚ β”‚   β”‚   final-report-final-v3-usethisone.docx β€’ standardized kebab-case     β”‚
β”‚ β”‚   └── meeting_notes_oct.txt β†’ meeting-notes-oct.txt β€’ standardized        β”‚
β”‚ β”‚       kebab-case                                                          β”‚
β”‚ β”œβ”€β”€ πŸ“‘ Duplicates/ (2 files)                                                β”‚
β”‚ β”‚   β”œβ”€β”€ document(2).pdf β†’ Duplicates/document(2).pdf β€’ duplicate of         β”‚
β”‚ β”‚   β”‚   document(1).pdf                                                     β”‚
β”‚ β”‚   └── IMG_20241020_083211.jpg β†’ Duplicates/IMG_20241020_083211.jpg β€’      β”‚
β”‚ β”‚       duplicate of IMG_20241019_142356.jpg                                β”‚
β”‚ β”œβ”€β”€ πŸ–ΌοΈ  Images/ (4 files)                                                   β”‚
β”‚ β”‚   β”œβ”€β”€ Screenshot 2026-10-21 000814.png β†’                                  β”‚
β”‚ β”‚   β”‚   screenshot-2026-10-21-000814.png β€’ standardized kebab-case          β”‚
β”‚ β”‚   └── wallpaper_4k_mountain.jpg β†’ wallpaper-4k-mountain.jpg β€’             β”‚
β”‚ β”‚       standardized kebab-case                                             β”‚
β”‚ └── βš™οΈ  Installers/ (2 files)                                               β”‚
β”‚     β”œβ”€β”€ ABDownloadManager_1.11.1_windows_x64.exe β†’                          β”‚
β”‚     β”‚   abdownloadmanager-1.11.1-windows-x64.exe β€’ standardized kebab-case  β”‚
β”‚     └── VSCodeUserSetup-x64-1.92.0.exe β†’ vscodeusersetup-x64-1.92.0.exe β€’   β”‚
β”‚         standardized kebab-case                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€ Next Step ─────────────────────────────────────────────────────────────────┐
β”‚  Dry-run preview complete. No files were modified on disk.                  β”‚
β”‚                                                                             β”‚
β”‚  To apply these changes, run:                                               β”‚
β”‚    slothsort "~/Downloads" --execute --dedupe                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

When you pass --execute, the moves happen atomically. If you ever change your mind:

$ slothsort undo ~/Downloads

β”Œβ”€ Rollback Complete ─────────────────────────────────────────────────────────┐
β”‚  βœ“ Successfully restored 31 file(s) to original locations.                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Code

The complete codebase, documentation, and automated test suite are open-sourced on GitHub:

πŸ‘‰ GitHub Repository: D9292S/slothsort

slothsort/
β”œβ”€β”€ pyproject.toml              # Modern Hatchling package configuration
β”œβ”€β”€ README.md                   # Full documentation and command reference
β”œβ”€β”€ LICENSE                     # MIT License
β”œβ”€β”€ .slothsort.toml.example     # Configuration template for user overrides
β”œβ”€β”€ slothsort/
β”‚   β”œβ”€β”€ __init__.py             # Version metadata
β”‚   β”œβ”€β”€ config.py               # Taxonomy mapping, model configurations, defaults
β”‚   β”œβ”€β”€ scanner.py              # Filtering, snippet extraction, SHA-256 duplicate hashing
β”‚   β”œβ”€β”€ categorizer.py          # Ollama JSON inference + Algorithmic Hallucination Guard
β”‚   β”œβ”€β”€ organizer.py            # Collision resolution (-1, -2), moves, atomic undo manifest
β”‚   └── cli.py                  # Rich terminal UI, diff tree, watch mode, commands
β”œβ”€β”€ demo/
β”‚   └── simulate_mess.py        # Demo script to generate 31 realistic messy files
└── tests/
    β”œβ”€β”€ test_scanner.py         # Filtering, snippets, duplicate detection tests
    β”œβ”€β”€ test_safety.py          # Hallucination guard & name preservation tests
    β”œβ”€β”€ test_parser.py          # Resilient JSON parsing tests (lists, dicts, markdown)
    └── test_organizer.py       # Collision resolution & end-to-end rollback tests
Enter fullscreen mode Exit fullscreen mode

How I Built It

SlothSort is built with Python 3.10+, Ollama, Meta Llama 3.2 (3B), Click, Rich, and Pydantic.

Technical Highlights

  1. Local Inference: Files are batched and sent to Ollama with strict JSON schemas enforced by Pydantic.
  2. Content Sniffing: For ambiguous text/code/data files under 2 MB, the scanner peeks at the first 300 characters to provide the model with grounding context.
  3. The Hallucination Guard (is_safe_rename): During testing, I caught a 3B model edge case: when given a batch containing multiple installers, Llama 3.2 occasionally cross-pollinated names (trying to rename ABDownloadManager.exe to bitdefender.exe). I wrote an algorithmic safety guard that verifies suggested names never borrow tokens from other files in the batch, falling back to safe formatting if cross-contamination is detected.
  4. Safety & Testing: Includes an atomic rollback log (.slothsort-undo.json) and 12 unit tests in pytest verifying parsing, collision handling, and hallucination rejection.

Why Does Open Innovation Matter?

For personal file management, local open-source AI is fundamentally superior to closed cloud APIs:

  • πŸ”’ Absolute Privacy: Your Downloads folder contains tax drafts, bank statements, and personal records. With local models, zero bytes leave your machine.
  • πŸ’Έ Zero Recurring Cost: Organizing thousands of files costs \$0.00 in API tokens.
  • ✈️ 100% Offline: Operates in airplane mode, on trains, or without internet.
  • πŸŽ›οΈ Model Portability: Swap models freely based on your hardware (--model llama3.2, --model phi3, or --model mistral).
  • πŸ›‘οΈ Resilient Fallback: If Ollama is offline or files exceed 500 MB, SlothSort gracefully falls back to deterministic rules. It never crashes.

My Agent Session

I built SlothSort through an iterative agent pair-programming session with an AI coding assistant. The agent helped scaffold the initial Click/Rich CLI architecture, iterate on small-model prompt engineering with Ollama, and write the 12-test pytest suite that verified the algorithmic hallucination guard.

The Lazy Payoff

Manually sorting an 800-file Downloads folder usually takes 45 minutes of tedious drag-and-drop.

With SlothSort, it takes 5 seconds with one command β€” or zero effort if you leave --watch running in the background.

Top comments (0)