{"id":50833880,"url":"https://github.com/77aymeric/tidydrop","last_synced_at":"2026-06-14T02:02:29.833Z","repository":{"id":362801679,"uuid":"1260849327","full_name":"77Aymeric/tidydrop","owner":"77Aymeric","description":"Native macOS utility for safe local AI file sorting powered by Ollama","archived":false,"fork":false,"pushed_at":"2026-06-14T00:14:46.000Z","size":6045,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-14T00:22:27.368Z","etag":null,"topics":["fastapi","file-organization","local-ai","macos","ollama","privacy","swiftui"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/77Aymeric.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"docs/ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-06T00:11:02.000Z","updated_at":"2026-06-14T00:14:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/77Aymeric/tidydrop","commit_stats":null,"previous_names":["77aymeric/tidydrop"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/77Aymeric/tidydrop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/77Aymeric%2Ftidydrop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/77Aymeric%2Ftidydrop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/77Aymeric%2Ftidydrop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/77Aymeric%2Ftidydrop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/77Aymeric","download_url":"https://codeload.github.com/77Aymeric/tidydrop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/77Aymeric%2Ftidydrop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34306772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastapi","file-organization","local-ai","macos","ollama","privacy","swiftui"],"created_at":"2026-06-14T02:02:28.995Z","updated_at":"2026-06-14T02:02:29.824Z","avatar_url":"https://github.com/77Aymeric.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TidyDrop\n\n**A native macOS utility that uses local Ollama models to understand, rename, and safely organize files.**\n\n[![CI](https://github.com/77Aymeric/tidydrop/actions/workflows/ci.yml/badge.svg)](https://github.com/77Aymeric/tidydrop/actions/workflows/ci.yml)\n[![Latest Release](https://img.shields.io/github/v/release/77Aymeric/tidydrop?include_prereleases)](https://github.com/77Aymeric/tidydrop/releases/latest)\n[![macOS 26+](https://img.shields.io/badge/macOS-26%2B-black?logo=apple)](https://www.apple.com/macos/)\n[![Swift 6.2](https://img.shields.io/badge/Swift-6.2-F05138?logo=swift\u0026logoColor=white)](https://www.swift.org/)\n[![Python 3.11+](https://img.shields.io/badge/Python-3.11%2B-3776AB?logo=python\u0026logoColor=white)](https://www.python.org/)\n[![Ollama](https://img.shields.io/badge/AI-Ollama_local_only-white)](https://ollama.com/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n\n![TidyDrop main window](docs/assets/tidydrop-main.png)\n\nTidyDrop scans a folder without executing its contents, extracts bounded previews, studies the collection as a whole, and proposes meaningful folders based on projects, clients, subjects, events, and dates. Every proposed copy, move, category, and filename remains visible and editable before anything is applied.\n\nIt is not a cloud organizer, an automatic cleaner, or a deletion tool.\n\n## Download\n\nThe current public build is **TidyDrop v0.1.0-alpha.1** for Apple Silicon Macs running macOS 26 or later.\n\n[**Download the signed and notarized DMG**](https://github.com/77Aymeric/tidydrop/releases/download/v0.1.0-alpha.1/TidyDrop-0.1.0-alpha.1-macos-arm64.dmg)\n\nThe app is signed and notarized by Apple, and includes its local backend. Ollama and its models remain separate so TidyDrop never downloads multi-gigabyte models without permission. A ZIP archive and SHA-256 checksums are also available on the [release page](https://github.com/77Aymeric/tidydrop/releases/tag/v0.1.0-alpha.1).\n\n## Why TidyDrop\n\nMost file organizers group by extension. TidyDrop is designed to group by meaning.\n\nFiles such as `brief.pdf`, `logo.png`, `meeting-notes.md`, and `invoice.xlsx` can belong to the same client project even though their formats differ. TidyDrop first studies the entire folder, proposes semantic groups, then classifies each file against those groups. Uncertain decisions are rechecked by a stronger model and still fall back to `To Review` when confidence is insufficient.\n\n## Safety Guarantees\n\n| Guarantee | Behavior |\n| --- | --- |\n| Local only | File previews are sent only to Ollama on `localhost` |\n| Copy by default | Originals remain untouched unless Move is explicitly selected |\n| Never deletes | TidyDrop has no delete operation |\n| Never overwrites | Existing targets receive a conflict-safe alternate name |\n| Preview first | Apply is impossible until an explicit operation plan exists |\n| Undo enabled | Copy and move runs both have reversible workflows |\n| Bounded extraction | Large files and complex formats are sampled, not fully ingested |\n| No execution | Discovered scripts, binaries, and documents are never run |\n\nInvalid model output, invented categories, low confidence, and request failures are treated as review cases rather than trusted decisions.\n\n## Product Tour\n\n### A focused default\n\nThe initial screen exposes only the decisions that materially change the outcome: copy or move, output folder, semantic folder discovery, and reviewed filename application.\n\n### Advanced controls remain available\n\n![TidyDrop advanced settings](docs/assets/tidydrop-advanced-settings.png)\n\n`More Settings` contains scan boundaries, model routing, expert review thresholds, renaming suggestions, and request timeouts. No setting was removed to simplify the default experience.\n\n### Categories and templates\n\n![TidyDrop categories and sorting templates](docs/assets/tidydrop-categories.png)\n\nStarter templates provide an immediate category set, while every folder name, description, and rule remains editable. Smart folders can later replace broad starter categories with groups inferred from the collection.\n\n### Preview, history, and undo\n\n![TidyDrop preview and run history](docs/assets/tidydrop-history.png)\n\nThe lower workspace keeps file preview and previous runs close to the review plan. Completed runs expose Undo directly, without hiding the operation history.\n\n## End-to-End Workflow\n\n```mermaid\nflowchart LR\n    A[\"Drop or choose a folder\"] --\u003e B[\"Read-only scan\"]\n    B --\u003e C[\"Bounded content extraction\"]\n    C --\u003e D{\"Smart folders enabled?\"}\n    D -- Yes --\u003e E[\"Expert model studies the collection\"]\n    E --\u003e F[\"Create semantic categories\"]\n    D -- No --\u003e G[\"Use user categories\"]\n    F --\u003e H[\"Fast model classifies every file\"]\n    G --\u003e H\n    H --\u003e I{\"Uncertain or weak result?\"}\n    I -- Yes --\u003e J[\"Expert text or vision review\"]\n    I -- No --\u003e K[\"Build operation plan\"]\n    J --\u003e K\n    K --\u003e L[\"Review paths, names, reasons, confidence\"]\n    L --\u003e M[\"User edits or disables operations\"]\n    M --\u003e N[\"Explicit Apply\"]\n    N --\u003e O[\"Run history\"]\n    O --\u003e P[\"Undo preview and apply\"]\n```\n\nThe sequence is intentionally collection-first. New AI-created folders are available before per-file classification, so earlier files are not locked into an obsolete category set.\n\n## Model Routing\n\nTidyDrop supports a small-fast plus larger-expert workflow that is practical on a 16 GB Mac:\n\n| Role | Recommended model | Used for |\n| --- | --- | --- |\n| Fast pass | `qwen3.5:2b` | Initial classification of every file |\n| Expert text | `qwen3.5:9b` | Folder discovery and uncertain text/code/document review |\n| Expert vision | `gemma4:e4b-it-qat` | Uncertain image review |\n\nModels are used sequentially and explicitly unloaded between phases to reduce peak memory pressure. TidyDrop never downloads a model automatically.\n\n```mermaid\nsequenceDiagram\n    participant App as SwiftUI app\n    participant API as Local FastAPI engine\n    participant Expert as Expert text model\n    participant Fast as Fast model\n    participant Vision as Expert vision model\n\n    App-\u003e\u003eAPI: Scan folder\n    API--\u003e\u003eApp: Files and bounded previews\n    App-\u003e\u003eExpert: Discover semantic folders\n    Expert--\u003e\u003eApp: 3-5 project/subject groups\n    Note over App,Expert: Expert model is unloaded\n    loop Every file\n        App-\u003e\u003eFast: Classify against final category set\n        Fast--\u003e\u003eApp: Category, confidence, reason, filename\n    end\n    Note over App,Fast: Fast model is unloaded\n    opt Uncertain text files\n        App-\u003e\u003eExpert: Recheck selected files\n    end\n    opt Uncertain images\n        App-\u003e\u003eVision: Recheck selected images\n    end\n    App--\u003e\u003eApp: Build editable review plan\n```\n\nApproximate local model storage for this combination is 15.4 GB before Ollama overhead:\n\n```bash\nollama pull qwen3.5:2b\nollama pull qwen3.5:9b\nollama pull gemma4:e4b-it-qat\n```\n\nYou can select any installed Ollama models in `More Settings`. See [Model Strategy](docs/MODELS.md) for routing details and lower-storage alternatives.\n\n## File Understanding\n\n| Type | Read-only understanding |\n| --- | --- |\n| Images | Metadata; image bytes are loaded lazily for a vision request, up to the configured limit |\n| PDF | Text sampled from the first pages with PyMuPDF |\n| DOCX | First meaningful paragraphs with `python-docx` |\n| TXT, Markdown, CSV, JSON, XML, YAML | Bounded decoded text preview |\n| Source code | Extension detection and bounded source preview |\n| XLSX | Sheet names and sampled cells with `openpyxl` |\n| ZIP | Internal filename listing only; never extracted |\n| Other archives | Metadata only |\n| Audio and video | Metadata only |\n| Unknown or binary | Name, extension, size, path, dates, and MIME guess |\n\nFiles above the configured analysis size are still listed, but deep extraction is skipped.\n\n## Review Before Apply\n\nThe review plan exposes every operation:\n\n- original filename and full source path;\n- target folder and full target path;\n- editable proposed filename;\n- semantic reason and calibrated confidence;\n- copy or move action;\n- conflict status;\n- enabled/disabled toggle;\n- manual category override;\n- file preview, Open, and Show in Finder actions.\n\nChanging a category or filename recomputes the target before Apply. The user remains the final decision-maker.\n\n## Apply, History, and Undo\n\nCopy mode is the default. Completed runs are stored in `~/.tidydrop/runs/\u003crun_id\u003e.json`.\n\n- Copy undo moves generated copies into `~/.tidydrop/undone/\u003crun_id\u003e/`; it does not delete them.\n- Move undo restores originals in reverse order.\n- If a destination already exists, TidyDrop chooses an alternate path such as `Document (1).pdf`.\n- Missing files, disabled actions, conflicts, and errors remain visible in the run record.\n\n## Install and Run\n\n### App requirements\n\n- Apple Silicon Mac\n- macOS 26 or later\n- [Ollama](https://ollama.com/) for AI classification\n- at least one compatible local Ollama model\n\nPython and Xcode are **not** required when installing the release.\n\n### Installation\n\n1. Download [`TidyDrop-0.1.0-alpha.1-macos-arm64.dmg`](https://github.com/77Aymeric/tidydrop/releases/download/v0.1.0-alpha.1/TidyDrop-0.1.0-alpha.1-macos-arm64.dmg).\n2. Open the DMG and drag TidyDrop into `Applications`.\n3. Install Ollama, then start it:\n\n   ```bash\n   ollama serve\n   ```\n\n4. Pull the recommended models, or choose smaller installed alternatives:\n\n   ```bash\n   ollama pull qwen3.5:2b\n   ollama pull qwen3.5:9b\n   ollama pull gemma4:e4b-it-qat\n   ```\n\n5. Launch TidyDrop, choose or drop a folder, review the settings, then scan.\n\nThe app can scan and preview files while Ollama is unavailable. Semantic folder discovery and classification require Ollama to be running.\n\n### Verify the download\n\nThe release page includes `SHA256SUMS.txt`. From the directory containing the downloaded files:\n\n```bash\nshasum -a 256 -c SHA256SUMS.txt\n```\n\nmacOS should identify the installed app as a notarized Developer ID application:\n\n```bash\nspctl --assess --type execute -vv /Applications/TidyDrop.app\n```\n\n### Build from source\n\nSource development requires macOS 26+, Xcode 26 with Swift 6.2, and Python 3.11+.\n\n```bash\ngit clone https://github.com/77Aymeric/tidydrop.git\ncd tidydrop\n\npython3 -m venv .venv\nsource .venv/bin/activate\npython -m pip install --upgrade pip\npython -m pip install -e \".[dev]\"\n\n./script/build_and_run.sh\n```\n\nThe script builds `dist/TidyDrop.app`, opens the native app, and lets the app manage its local backend on `127.0.0.1:3838`. There is no browser UI.\n\n## Sorting Templates\n\nThe app includes five starting points, each with a `To Review` fallback:\n\n- Downloads Cleanup\n- Student Mode\n- Developer Mode\n- Photo Cleanup\n- Admin Papers\n\nCategories remain editable. Smart folders can also replace generic starter groups with collection-specific project, client, topic, event, or period folders.\n\nFrench category examples:\n\n- `Projet Atlas`\n- `Factures 2026`\n- `Cours de droit`\n- `Voyage Japon`\n- `A verifier`\n\n## Architecture\n\n```mermaid\ngraph TD\n    UI[\"Native SwiftUI app\u003cbr/\u003eSources/TidyDrop\"] --\u003e|\"HTTP on 127.0.0.1:3838\"| BE[\"FastAPI local engine\u003cbr/\u003ebackend/\"]\n    BE --\u003e SCAN[\"Scanner and extractors\"]\n    BE --\u003e AI[\"Ollama client\u003cbr/\u003elocalhost:11434\"]\n    BE --\u003e PLAN[\"Planner and safe operations\"]\n    PLAN --\u003e FS[\"User-selected folders\"]\n    PLAN --\u003e HIST[\"~/.tidydrop/runs\"]\n    HIST --\u003e UNDO[\"Undo engine\"]\n```\n\nSwiftUI owns the window, drag and drop, settings, progress, review, preview, history, and undo experience. Python owns format extraction, Ollama requests, output validation, path planning, file operations, and run persistence.\n\nSee [Architecture](docs/ARCHITECTURE.md) and [Workflow](docs/WORKFLOW.md) for the full contracts.\n\n## Local API\n\nThe backend binds only to `127.0.0.1:3838`.\n\n| Method | Endpoint | Purpose |\n| --- | --- | --- |\n| `GET` | `/api/health` | Backend and Ollama status |\n| `GET` | `/api/ollama/models` | Installed local models |\n| `POST` | `/api/scan` | Read-only folder scan |\n| `POST` | `/api/categories/discover` | Collection-level semantic folder discovery |\n| `POST` | `/api/classify` | Per-file classification |\n| `POST` | `/api/plan` | Create an explicit operation plan |\n| `POST` | `/api/apply` | Apply enabled plan operations |\n| `GET` | `/api/history` | List runs |\n| `GET` | `/api/history/{run_id}` | Read a run |\n| `POST` | `/api/undo/preview` | Preview reversal |\n| `POST` | `/api/undo/apply` | Apply reversal |\n| `POST` | `/api/open-folder` | Open a local folder in Finder |\n\nSee [Local API](docs/API.md) for request behavior.\n\n## Prompts and AI Contract\n\nTidyDrop does not hide its model instructions. The exact current prompts, JSON schemas, generation options, confidence rules, and response recovery behavior are documented in [System Prompts](docs/PROMPTS.md). The executable source of truth remains [`backend/ollama_client.py`](backend/ollama_client.py).\n\nImportant runtime constraints:\n\n- structured JSON schema output;\n- `temperature: 0`;\n- reasoning disabled with `think: false`;\n- 4,096-token context for classification;\n- 8,192-token context for collection discovery;\n- bounded output lengths;\n- category validation and confidence fallback after generation.\n\n## Development\n\n```bash\nswift build\npython -m pytest\npython -m ruff check backend tests\n./script/build_and_run.sh --verify\n```\n\nCI runs backend lint/tests on Linux and builds the native SwiftUI app on macOS 26.\n\n```text\nSources/TidyDrop/       Native macOS product\nbackend/                Local FastAPI engine\nbackend/extractors/     Bounded format understanding\ntests/                  Backend safety and workflow tests\nscript/                 Build and run entrypoint\ndocs/                   Architecture and product documentation\n.github/                CI and contribution templates\n```\n\n## Documentation\n\n- [Workflow](docs/WORKFLOW.md)\n- [Architecture](docs/ARCHITECTURE.md)\n- [Model Strategy](docs/MODELS.md)\n- [System Prompts](docs/PROMPTS.md)\n- [Safety Model](docs/SAFETY.md)\n- [Local API](docs/API.md)\n- [Development Guide](docs/DEVELOPMENT.md)\n- [Release Guide](docs/RELEASING.md)\n- [Roadmap](docs/ROADMAP.md)\n- [Contributing](CONTRIBUTING.md)\n- [Security Policy](SECURITY.md)\n- [Changelog](CHANGELOG.md)\n\n## Project Status\n\nTidyDrop is an alpha-stage open-source project. The native scan/classify/plan/apply workflow, semantic folder discovery, reviewed renaming, file preview, history, cancellation, and undo are implemented.\n\nThe first public Apple Silicon build, [`v0.1.0-alpha.1`](https://github.com/77Aymeric/tidydrop/releases/tag/v0.1.0-alpha.1), is signed, hardened, notarized by Apple, and available as a DMG or ZIP. Current alpha limitations include metadata-only understanding for audio/video and many archive formats, model-dependent classification quality, and limited end-to-end UI automation.\n\n## License\n\nTidyDrop is available under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F77aymeric%2Ftidydrop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F77aymeric%2Ftidydrop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F77aymeric%2Ftidydrop/lists"}