Skip to content
Back to skills

File Organizer

ASecurity

Use when the user wants to organize, tidy, or restructure a messy directory (Downloads, Desktop, documents folder). LLM-powered file organizer that scans content, proposes a structure, and executes moves in chunks with a mandatory user confirmation gate.

  • 89 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 19, 2026
ai-agentspythongobashrailsgitapi

Works with

  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add moonlight-lupin/agent-skills --skill file-organizer --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of File Organizer?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for File Organizer
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/moonlight-lupin-file-organizer/badge)](https://www.skillsdirectory.com/skills/moonlight-lupin-file-organizer)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: file-organizer
description: "Use when the user wants to organize, tidy, or restructure a messy directory (Downloads, Desktop, documents folder). LLM-powered file organizer that scans content, proposes a structure, and executes moves in chunks with a mandatory user confirmation gate."
license: MIT
metadata:
  version: 1.0.0
  author: moonlight-lupin
  platforms: [linux, macos, windows]
  hermes:
    tags: [file-management, organization, cleanup, productivity]
---

# File Organizer

An LLM-powered file organizer that reads file contents, proposes a sensible folder
structure with renamed files, and executes moves in chunks — with a mandatory user
confirmation gate before any filesystem changes.

## Overview

Inspired by [LlamaFS](https://github.com/iyaja/llama-fs) but designed for Hermes:
the script handles filesystem I/O (scan, read snippets, execute moves). The agent's
own LLM does the reasoning by default. An optional `propose` subcommand can call a
cheaper external LLM (deepseek, openrouter, ollama) for cost-conscious runs on large
directories. Uses stdlib-only HTTP (urllib) — no requests/openai SDK needed.

## When to Use

- User says "organize my Downloads" / "tidy my Desktop" / "clean up this folder"
- User has a messy directory and wants files sorted into categories
- User wants files renamed based on their content (not just moved)
- User wants to organize files on a local disk, network mount, or remote filesystem

**Don't use for:**
- Bulk file deletion (this skill only moves and renames, never deletes)
- Deduplication (use a dedicated dedup tool)
- File content search (use `search_files` instead)

## Workflow

### Step 1 — Scan

Run the scan script to get file metadata + content snippets:

```bash
python3 scripts/organize.py scan --path <directory> [--depth N] [--max-snippet-chars 500]
```

Output is a JSON array. Each file entry contains:
- `path`: full file path
- `relative_path`: path relative to scanned directory
- `name`: current filename
- `size`: bytes
- `mtime`: ISO timestamp
- `type`: text, image, audio, pdf, office, archive, other
- `mime`: detected MIME type
- `snippet`: first N chars of content (text/pdf) or metadata (image/audio)

Flags: `--depth N` (max directory depth), `--max-snippet-chars N` (per-file snippet limit, default 500), `--include-hidden` (include dotfiles, skipped by default).

### Step 2 — Propose Organization (Agent LLM — Default)

Using the scan output, reason about:
- Natural categories based on file content and types
- A clean folder hierarchy (not too deep — 2-3 levels max)
- Descriptive filenames that reflect content (not `IMG_3847.jpg` → `Hawaii-Beach-Sunset.jpg`)
- Time-based grouping when appropriate (e.g., `2024-Taxes/`, `2023-Receipts/`)

Build a plan JSON:
```json
{
  "source_dir": "<scanned dir>",
  "moves": [
    {"source": "<full path>", "destination": "<full path>"}
  ],
  "folders_to_create": ["<full path>", ...]
}
```

**Cost-saving offer:** When presenting the plan (Step 3), mention to the user:
> "This used the agent's own model. For larger directories, I can run the reasoning
> through a cheaper LLM to save costs. Available options:"
>
> | Provider | Model | Cost | Notes |
> |----------|-------|------|-------|
> | deepseek | deepseek-chat | ~$0.14/M in, $0.28/M out | Cheapest cloud |
> | openrouter | deepseek/deepseek-chat | pay-as-you-go | Multi-model routing |
> | ollama | llama3.2:3b | Free (local CPU) | Slow but zero cost |
>
> Just say "use deepseek" or "use ollama" and I'll re-run via the cheaper model.

Only offer this if the scan had 20+ files (not worth it for tiny directories).

**Using a cheaper model (opt-in):** If the user requests a cheaper model, or if the
directory is very large (100+ files), use the `propose` subcommand instead:

```bash
python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir <dir> \
  --provider deepseek [--model <model-id>]
```

Provider priority: `--provider` flag > `DEEPSEEK_API_KEY` env > `OPENAI_API_KEY` env
> `OPENROUTER_API_KEY` env > `OLLAMA_HOST` env > error

If `propose` fails (network, auth, parse), fall back to agent reasoning manually.

### Step 3 — Present Plan to User (MANDATORY GATE)

**This step is non-negotiable.** Present the plan as a formatted table:

| # | Current Name | → | New Location | Type | Snippet Preview |
|---|---|---|---|---|---|

Ask the user to:
- Confirm the plan as-is
- Adjust specific moves (rename, re-categorize, skip)
- Cancel entirely

**Never proceed to execution without explicit user confirmation.**

### Step 4 — Execute in Chunks

After user confirms, write the plan to a temp file and execute:

```bash
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 10
```

The script:
- Creates destination folders first
- Moves files in chunks of 10 (configurable)
- Prints progress after each chunk: `[chunk 2/5] moved 10, failed 0`
- Skips conflicts (destination exists) — never overwrites
- Logs per-file errors without aborting the batch

### Step 5 — Report Results

Present the final summary to the user:
- Files moved successfully
- Files skipped (conflicts)
- Files failed (errors)
- Suggest next steps (e.g., "want me to organize another directory?")

## Cross-Filesystem Support

The organizer works on any path accessible from the host:

| Target | Path Format | Notes |
|--------|-------------|-------|
| Local disk | Any local path | Direct filesystem access |
| Network mount | NFS, SMB/CIFS, SSHFS mounts | Use smaller chunk sizes for latency |
| Remote filesystem | Any path Python `shutil.move` can handle | SSHFS, FUSE, etc. |

## Key Guardrails

1. **Never delete** — only move and rename. If the user wants deletions, that's a
   separate task with its own confirmation flow.
2. **Never overwrite** — if a destination file exists, skip and log.
3. **Always gate** — present plan to user before executing. No silent moves.
4. **Chunk execution** — process in batches of 10 to manage failures gracefully.
5. **Agent LLM by default, cheap LLM opt-in** — `scan` and `execute` are pure
   filesystem I/O. The agent's own LLM does the reasoning by default. The `propose`
   subcommand is an opt-in for cheaper external models on large directories.

## Common Pitfalls

1. **Huge directories** — scanning 10,000+ files will produce massive output. Use
   `--depth 1` first to survey, then drill into subdirectories. Or scan by file type
   subsets.

2. **Binary files with no snippet** — images, audio, office docs get metadata only.
   The LLM must infer categories from filename, size, and mtime.

3. **Paths with spaces** — always quote paths in the plan JSON. The script handles
   this correctly via Python pathlib.

4. **Network filesystem latency** — organizing files on SSHFS/NFS/SMB mounts is
   slower due to network round-trips. Use smaller chunk sizes (5) for remote targets.

5. **Permission errors** — some files may not be readable. The scan script handles
   this gracefully (returns metadata with `snippet: null`).

## Verification Checklist

- [ ] Scan completed and returned JSON output
- [ ] Plan includes `source_dir`, `moves`, and `folders_to_create`
- [ ] Plan presented to user as a table with clear before → after mapping
- [ ] User explicitly confirmed the plan
- [ ] Plan written to temp JSON file
- [ ] Execution completed with chunked progress output
- [ ] Final summary reported (moved / failed / skipped counts)
- [ ] No files were deleted or overwritten

## One-Shot Recipes

### Organize Downloads folder
```bash
# 1. Scan
python3 scripts/organize.py scan --path ~/Downloads --depth 2 > /tmp/scan.json

# 2. Agent reasons over scan JSON, builds plan (default — uses agent's own LLM)
#    OR for large directories, use cheap LLM:
#    python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir ~/Downloads --provider deepseek > /tmp/plan.json

# 3. Agent presents plan to user (with cost-saving offer if 20+ files)

# 4. After confirmation:
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 10
```

### Organize a network-mounted directory
```bash
# 1. Scan
python3 scripts/organize.py scan --path /mnt/remote/Desktop --depth 2 > /tmp/scan.json

# 2. Agent reasons over scan JSON, builds plan (default)
#    OR: python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir /mnt/remote/Desktop --provider deepseek > /tmp/plan.json

# 3. Agent presents plan to user

# 4. After confirmation (smaller chunks for network latency):
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 5
```

### Dry run (preview only)
```bash
python3 scripts/organize.py execute --plan /tmp/plan.json --dry-run
```

### Cheap LLM (opt-in for large directories)
```bash
# Scan → Propose via deepseek → Execute
python3 scripts/organize.py scan --path ~/Downloads > /tmp/scan.json
python3 scripts/organize.py propose --scan /tmp/scan.json --source-dir ~/Downloads --provider deepseek > /tmp/plan.json
# Agent reviews plan, presents to user, then:
python3 scripts/organize.py execute --plan /tmp/plan.json --chunk-size 10
```

### Run self-tests
```bash
python3 scripts/organize.py --self-test
```

## Script Reference

| Command | Purpose |
|---------|---------|
| `scan --path <dir> [--depth N] [--max-snippet-chars N] [--include-hidden]` | Scan directory, output JSON with file metadata + snippets |
| `propose --scan <json> --source-dir <dir> [--provider <p>] [--model <m>]` | **Opt-in**: call a cheap external LLM to generate plan JSON |
| `execute --plan <json> [--chunk-size N] [--dry-run]` | Execute move plan in chunks, print progress per chunk |
| `--self-test` | Run built-in test suite (19 tests, self-contained in tempdir) |

Optional Python deps (degrade gracefully if missing):
- `Pillow` — image dimensions and EXIF dates
- `mutagen` — audio duration and ID3 tags
- `PyMuPDF` (fitz) — PDF first-page text extraction

Files in this skill

  • SKILL.md9.7 KB
  • scripts/organize.py27.3 KB
  • scripts/test_organize.py16.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.