1---2name: photos3description: Organize, index, and search local photo libraries with AI-powered metadata and safe file handling.4---56## Safety First78- **Never delete photos directly** — move to `.photo-trash/` folder with original path preserved in filename9- **Never overwrite originals** — edits go to `edited/` subfolder, originals stay untouched10- Before bulk operations, create manifest: `photos-pending.json` with planned actions for user review11- When user says "delete duplicates", move to trash and report count — let them empty trash manually1213## Indexing Strategy1415- Create `.photo-index/` in library root with one JSON sidecar per photo16- Sidecar filename: `{original-hash}.json` — survives renames and moves17- Index fields: `hash`, `path`, `date_taken`, `camera`, `gps`, `description`, `tags`, `indexed_at`18- Run indexing incrementally — skip files with matching hash already indexed19- Store description from vision analysis in sidecar, not in EXIF (non-destructive)2021## Vision Analysis (Token-Efficient)2223- Don't analyze every photo upfront — index on-demand when user searches or asks24- Cache vision results permanently in sidecar JSON — never re-analyze same photo25- For bulk analysis, process in batches of 20 with progress updates26- Use concise prompts: "Describe this photo in 2-3 sentences. List people, objects, location, activity."27- Skip screenshots and memes (detect by aspect ratio + lack of EXIF) unless explicitly requested2829## Duplicate Detection3031- Generate perceptual hash (pHash) alongside content hash — catches near-duplicates and resized copies32- Group duplicates by pHash similarity, keep highest resolution as "original"33- Report duplicates with thumbnails/paths, never auto-delete34- Consider EXIF date — oldest is likely the original, newer copies are backups3536## Search Patterns3738- **By content**: Search sidecar descriptions with simple text match first, vision re-analysis if no hits39- **By date**: Parse EXIF DateTimeOriginal, fall back to file mtime40- **By location**: Reverse geocode GPS once, store city/country in sidecar for text search41- **By person**: If user identifies someone once ("that's Maria"), tag all similar faces in index4243## EXIF Handling4445- Read: `exiftool -json photo.jpg` — returns all metadata as JSON46- Write date: `exiftool -DateTimeOriginal="2024:03:15 14:30:00" photo.jpg`47- Strip GPS before sharing: `exiftool -gps:all= photo.jpg` (operates on copy, not original)48- Batch read: `exiftool -json -r /photos/` — recursive, outputs array4950## File Organization5152- Propose structure, don't impose: `YYYY/MM/` or `YYYY/MM-DD/` based on user preference53- Rename pattern: `YYYYMMDD_HHMMSS_originalname.ext` — preserves original name, adds sortable prefix54- Handle timezone: EXIF dates are local time — ask user's timezone once, store in `.photo-index/config.json`55- HEIC to JPEG: `sips -s format jpeg input.heic --out output.jpg` (macOS) or `heif-convert` (Linux)5657## NAS/Remote Libraries5859- For Synology/NAS: work with mounted paths, don't assume local speeds60- Test connection before bulk operations: `ls /Volumes/photos | head -1`61- For slow connections, build local index cache that syncs periodically62- Respect `@eaDir` (Synology thumbnails) and `.DS_Store` — skip in indexing