immich-sdcard-sync-prunelisted
Install: claude install-skill jackson2w/claude-code-skills
# Immich SD card auto-sync + safe prune
Pattern for automatically uploading a camera's SD card to Immich when it's inserted on a Mac, plus
a companion tool to safely prune Immich assets after the user deletes their local originals. Built
for a Canon SD card reader on macOS; the mechanics generalize to any camera/reader that mounts as a
normal volume with a `DCIM` folder.
## Architecture
1. **`immich upload` via `@immich/cli`** (`npm install -g @immich/cli`) — not `immich-go`, not the
deprecated Docker-based CLI. Auth via `immich login-key <server-url> <api-key>`, which writes
`~/.config/immich/auth.yml`. That file is created world-readable by the CLI —
[immich#6911](https://github.com/immich-app/immich/issues/6911) — `chmod 600` it immediately.
2. **A macOS `launchd` LaunchAgent with `StartOnMount`** fires the sync script on *any* volume
mount. The script itself filters for volumes with a top-level `DCIM` folder rather than matching
a specific volume name/label — camera-formatted cards often mount with a generic name like
`Untitled`, and the name isn't stable across reformats anyway.
3. **Dedup two different ways for two different purposes:**
- A `synced.log` state file keyed by **Volume UUID** (`diskutil info "$vol" | grep "Volume UUID"`)
stops the same already-fully-synced card from re-triggering a full re-upload on every
incidental `/Volumes` change while it sits mounted.
- Immich's own upload does checksum-based dedup server-side — re-