SiftForge is a safe, cross-platform command-line tool for organizing cluttered directories.
It previews planned changes by default, requires --apply before moving files, avoids overwrites, renames conflicts safely, records operation history locally, and supports undo.
Tagline:
Forge order from clutter.
Early development.
SiftForge currently has a working MVP flow:
- Preview organization plans
- Apply organization plans
- Classify files by built-in extension rules
- Safely rename destination conflicts
- Save local operation history
- Show operation history
- Undo the latest undoable operation
- Generate starter configuration
- Load and validate YAML configuration
- Apply user-defined extension and filename rules
- Build GitHub Release binary archives and installers
Configuration files and custom rules are implemented. Recursive organization and shell completions are not implemented yet.
SiftForge is designed around conservative filesystem behavior:
- Preview mode is the default.
- Files are moved only when
--applyis passed. - Existing files are never overwritten.
- Destination conflicts are renamed safely, such as
report (1).pdf. - Existing directories are skipped by default.
- Hidden files are skipped by default.
- Incomplete downloads are skipped by default.
- Symbolic links and other non-regular entries are skipped.
- Operation history is saved locally.
- Undo restores recorded moves where possible.
SiftForge does not delete user files as part of organization.
Install with Cargo:
cargo install siftforgeOr install the latest GitHub Release binary with the shell installer:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/DavidAsrorxonov/siftforge/releases/latest/download/siftforge-installer.sh | shOn Windows PowerShell:
powershell -ExecutionPolicy Bypass -c "irm https://github.com/DavidAsrorxonov/siftforge/releases/latest/download/siftforge-installer.ps1 | iex"Prebuilt archives are also available from GitHub Releases for macOS, Linux, and Windows.
Verify installation:
siftforge --versionPreview a directory:
siftforge ~/DownloadsApply the proposed organization:
siftforge ~/Downloads --applyShow operation history:
siftforge historyUndo the latest undoable operation:
siftforge undoShow help:
siftforge --helpShow version:
siftforge --versionWhen running locally from this repository, prefix commands with cargo run --:
cargo run -- ~/Downloads
cargo run -- ~/Downloads --apply
cargo run -- history
cargo run -- undoScanning: /Users/example/Downloads
Proposed organization:
Images 4 files
Documents 3 files
Archives 1 file
Other 2 files
10 files would be moved.
4 directories would be created.
2 entries would be skipped.
0 conflicts would be renamed safely.
Run `siftforge /Users/example/Downloads --apply` to continue.
Preview mode does not create directories, history files, or move files.
SiftForge currently organizes files into these broad categories:
ImagesVideosAudioDocumentsArchivesCodeInstallersOther
Unknown extensions go to Other.
Spreadsheets, presentations, Markdown files, and common text/document formats currently belong to Documents.
The scanner skips:
- Existing directories
- Hidden Unix-style names such as
.envand.DS_Store - System metadata such as
.DS_Store,Thumbs.db, anddesktop.ini - Incomplete downloads ending with
.crdownload,.download,.part,.partial, or.tmp - SiftForge config files such as
siftforge.ymlandsiftforge.yaml - Non-regular filesystem entries
Recursive mode is not implemented yet.
Create a starter config:
siftforge initThis writes siftforge.yml in the current directory and refuses to overwrite an existing file.
SiftForge loads config in this order:
- explicit
--config <path> siftforge.ymlin the target directorysiftforge.yamlin the target directory- built-in defaults
Example:
siftforge ~/Downloads --config ~/rules/siftforge.ymlConfig rules support:
- custom categories
- extension matching
- filename starts-with matching
- filename contains matching
Rule priority:
- user
filename_starts_with - user
filename_contains - user
extensions - built-in extension mappings
Other
View effective rules:
siftforge rulesWith an explicit config:
siftforge --config ./siftforge.yml rulesMore detail: docs/configuration.md.
SiftForge never overwrites an existing destination.
If a planned destination already exists:
Documents/report.pdf
SiftForge plans a safe renamed destination:
Documents/report (1).pdf
Compound archive extensions are preserved:
Archives/backup.tar.gz
Archives/backup (1).tar.gz
Applied operations are saved as JSON records in a platform-specific local history directory.
On macOS:
~/Library/Application Support/siftforge/history/
On Linux:
$XDG_STATE_HOME/siftforge/history/
Fallback on Linux:
~/.local/state/siftforge/history/
On Windows:
%LOCALAPPDATA%\siftforge\history\
History records include:
- operation ID
- target directory
- created directories
- successful moves
- failures
- operation status
- undo metadata, once undo has been attempted
Undo restores the latest operation record that has not already been marked undone.
For each recorded move, SiftForge:
- Checks that the organized file still exists.
- Checks that the original source path is available.
- Moves the file back.
- Skips safely if either check fails.
After restoring files, SiftForge removes only directories recorded as created by SiftForge, and only if they are empty.
Undo metadata is written back to the history record so repeated undo attempts do not blindly target the same operation.
Requirements:
- Rust stable
- Cargo
This project declares:
rust-version = "1.80"
edition = "2021"Run the standard checks:
cargo fmt
cargo check
cargo clippy -- -D warnings
cargo testRun the CLI locally:
cargo run -- .Run against a disposable test directory:
cargo run -- /path/to/test-directory
cargo run -- /path/to/test-directory --applyDo not test --apply on a real Downloads directory until the behavior you want has been verified with a fixture directory.
Current source modules:
src/
├── classifier/
├── config/
├── executor/
├── history/
├── planner/
├── scanner/
├── undo/
├── lib.rs
└── main.rs
The library modules contain the reusable core behavior. main.rs contains the CLI wiring.
Near-term work:
- Add stronger integration tests
- Improve release automation and installer verification
- Improve CLI output polish
- Add more platform-specific filesystem tests
Longer-term possibilities:
- Recursive mode
- JSON output
- Shell completions
- Homebrew tap
- Additional package managers
SiftForge is not intended to be:
- A file deletion tool
- A duplicate remover
- A file converter
- A cloud service
- An AI content classifier
- A GUI file manager
- A background daemon
MIT