AI-powered photo culling CLI. Drop a folder, get Keep / Review / Reject.
ss ./photosAutomatically classifies every photo with a 0–100 score across five quality dimensions. Results land in organized folders with an interactive HTML report.
| Feature | macOS | Linux | Windows |
|---|---|---|---|
| Core scanning | ✅ | ✅ | ✅ |
| RAW file decode | ✅ | ✅ | ✅ (needs Visual C++ Redistributable) |
| GPU acceleration | ✅ Metal | ✅ CUDA | ✅ CUDA (needs CUDA torch, see below) |
| Symlinks in output | ✅ | ✅ | |
Cloud VLM (-e) |
✅ | ✅ | ✅ |
Local VLM (setup --vlm) |
✅ | ✅ | ✅ |
| Lightroom XMP import | ✅ | ✅ | ✅ |
| Python version | 3.11 / 3.12 | 3.11 / 3.12 | 3.11 recommended |
mediapipe on Windows: Python 3.12 may have compatibility issues. Use Python 3.11 if installation fails.
From PyPI (once published):
pip install shuttersiftFrom the latest GitHub release (available now):
pip install https://github.com/host452b/ShutterSift/releases/download/v0.1.0/shuttersift-0.1.0-py3-none-any.whlDirectly from source:
pip install git+https://github.com/host452b/ShutterSift.gitApple Silicon (M1/M2/M3): If
mediapipefails to install:pip install mediapipe-silicon pip install shuttersift --no-deps
GPU acceleration on Mac (Metal):
pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/metal
Windows — Python 3.11 recommended: If
mediapipefails on Python 3.12, switch to 3.11.Windows — GPU acceleration (CUDA): The default
torchfrom PyPI is CPU-only. Install the CUDA build before installing ShutterSift:pip install torch --index-url https://download.pytorch.org/whl/cu124 pip install shuttersiftMatch the index to your driver:
cu124(CUDA 12.4+) ·cu121(12.1) ·cu118(11.8). Verify withss info— GPU should show ✓.Windows —
ss/shuttersiftcommand not found: Python'sScriptsfolder is not always on PATH. Fix with one of:Option A — Virtual environment (recommended):
python -m venv ss-env ss-env\Scripts\activate pip install git+https://github.com/host452b/ShutterSift.git ss --helpOption B — Add Scripts to PATH permanently:
- Search for "Edit the system environment variables"
- Click Environment Variables → Path → Edit
- Add:
C:\Users\<you>\AppData\Local\Programs\Python\Python311\Scripts- Restart your terminal
Windows — symlinks: Output folders use symlinks by default. Without the steps below, files are copied instead (a yellow warning will appear):
- Open Settings → Privacy & Security → For Developers
- Enable Developer Mode
Or simply run your terminal as Administrator.
# Step 1 — download required model files (one time only)
ss setup
# Step 2 — scan your photos
ss ./photos
# Step 3 — open the report
open shuttersift_output/report.html # macOS
xdg-open shuttersift_output/report.html # Linux
start shuttersift_output\report.html # WindowsSharpness thresholds are calibrated automatically on first run based on your photo library. No configuration needed.
Both ss and shuttersift are valid command names — use whichever you prefer.
Both -h and --help are supported on every command.
shuttersift_output/
├── keep/ ← high-scoring photos (symlinks + XMP sidecar)
├── review/ ← borderline photos worth a second look
├── reject/ ← blurry, closed eyes, duplicates
├── report.html ← interactive visual report with scores and thumbnails
└── results.json ← machine-readable, versioned
Lightroom users: import the keep/ folder — XMP sidecars set star ratings
and color labels automatically.
ss ./photos -e # enable VLM explanation for Review photos
ss ./photos -n # dry run — analyze only, write nothing
ss ./photos -f # force reanalysis (ignore cached results)
ss ./photos --recalibrate # redo sharpness calibration for this library
ss ./photos -o ./sorted # custom output directory
ss ./photos --keep 75 --reject 35 # custom score thresholds
ss ./photos -j 8 # use 8 parallel workers
ss ./photos -v # verbose logging| Flag | Long form | Default | Description |
|---|---|---|---|
-e |
--explain |
off | VLM explanation for borderline photos |
-n |
--dry-run |
off | Analyze only, do not move or link files |
-f |
--force |
off | Ignore cached results, reanalyze all |
-o |
--output <dir> |
../shuttersift_output |
Output directory |
-j |
--jobs <n> |
4 | Parallel worker count |
-v |
--verbose |
off | Print debug logs to stderr |
-c |
--config <file> |
auto | Path to config file |
--keep <n> |
70 | Minimum score to Keep | |
--reject <n> |
40 | Maximum score before Reject | |
--recalibrate |
off | Force redo sharpness calibration |
When -e / --explain is passed, borderline Review photos get an
AI-generated text description explaining what's wrong or interesting. Typically
20–30% of photos land in Review.
Cloud API (Anthropic or OpenAI):
export ANTHROPIC_API_KEY=sk-ant-...
ss ./photos -eexport OPENAI_API_KEY=sk-...
ss ./photos -eFully local (no internet required):
ss setup --vlm # downloads moondream2 GGUF, ~1.7 GB, one-time
ss ./photos -e # uses local model, no API key neededEvery photo receives a 0–100 composite score:
| Dimension | Weight | Method |
|---|---|---|
| Sharpness | 30% | Laplacian variance |
| Exposure | 15% | Histogram analysis |
| Aesthetic | 25% | MUSIQ (GPU) / BRISQUE (CPU) |
| Face quality | 20% | MediaPipe eye-open + smile |
| Composition | 10% | Rule-of-thirds engine |
Default thresholds: ≥ 70 → Keep · 40–69 → Review · < 40 → Reject
Override with --keep and --reject.
ShutterSift looks for a config file in this order:
--config <path>(explicit)./shuttersift.yaml(current directory)./config.yaml(current directory)~/.shuttersift/config.yaml(user global)
Full reference (~/.shuttersift/config.yaml):
calibrated: true # set automatically on first run
scoring:
thresholds:
keep: 70 # minimum score for Keep
reject: 40 # maximum score for Reject
hard_reject_sharpness: 42.3 # written by auto-calibration
eye_open_min: 0.25 # minimum eye-openness ratio (0–1)
burst_gap_seconds: 2.0 # photos within this window = burst
workers: 4 # parallel workers
log_retention_runs: 30 # how many log files to keepss calibrate ./photosSamples up to 300 photos and prints the full Laplacian variance distribution,
then saves the recommended hard_reject_sharpness to ~/.shuttersift/config.yaml.
Useful when switching cameras or shooting styles.
ss info # show GPU, VLM, and RAW support status
ss setup --vlm # download local moondream2 VLM modelA desktop and web GUI client is planned. See clients/desktop/ and
clients/web/ for the early scaffolding.