Merge slideshow-titles into slideshow-templates (origin/main: batch 31; open_session keeps both the slide templates dir and main's apple_photos_background, formats locales merged, whats-new keeps main's Reliability entry, parity summary refreshed)

This commit is contained in:
Jason Baldwin
2026-10-11 17:16:36 +02:00
89 changed files with 5780 additions and 459 deletions
+19 -1
View File
@@ -168,7 +168,7 @@ per-request `_meta` receive `resultType: complete` and list/read cache hints; re
| `apply_preset {preset, amount?, ids?}` | Apply a preset (ids from `cmd_presets_list`) |
| `crop {id?, rect?, angle?, reset?}` | Normalized crop rect `[x0,y0,x1,y1]` and straighten angle; at least one of `rect`, `angle`, `reset: true`. The crop always ends inside the photo: an `angle` alone keeps the crop if it still fits, else shrinks it to the largest of its aspect that does |
| `render_photo {id?, size?, format?, path?}` | Render with current settings → **image content** (PNG, or JPEG with `format: "jpeg"`), long edge `size` (default 1024) |
| `export {path \| dir, id? \| ids?, format?, longEdge? \| shortEdge? \| width?/height? \| megapixels? \| percent?, dontEnlarge?, ppi?, quality?, colorSpace?, bitDepth?, …}` | Full-quality render to `.png` / `.jpg` / `.tif` / `.webp` / `.avif`; `format: "original"` copies the file + an XMP sidecar with the edits, `format: "dng"` writes raw photos as DNG with the edits embedded. No size param = 3000 px long edge; `longEdge: 0` = full size (cropped, native resolution); `width` + `height` fit either orientation; `dontEnlarge` defaults to true |
| `export {path \| dir, id? \| ids?, format?, longEdge? \| shortEdge? \| width?/height? \| megapixels? \| percent?, dontEnlarge?, ppi?, quality?, colorSpace?, bitDepth?, …}` | Full-quality render to `.png` / `.jpg` / `.tif` / `.webp` / `.avif` / `.jxl` (`jxlLossless`, `jxlEffort`, `jxlProgressive`); `format: "original"` copies the file + an XMP sidecar with the edits, `format: "dng"` writes raw photos as DNG with the edits embedded. No size param = 3000 px long edge; `longEdge: 0` = full size (cropped, native resolution); `width` + `height` fit either orientation; `dontEnlarge` defaults to true |
Tools taking `id` make that photo active first; without it they act on the active photo.
@@ -270,6 +270,7 @@ lightcraft-cli run --demo --script steps.jsonl --keep-going
lightcraft-cli render in.dng -o out.tif --opt colorSpace=displayP3 --opt bitDepth=16 --opt percent=50
lightcraft-cli render in.dng -o out.jpg --set light.exposure=0.5 --set light.contrast=20 --size 2048
lightcraft-cli render in.jpg -o out.png --settings look.json --preset <presetId>
lightcraft-cli render in.dng -o out.jpg --opt addToPhotos=true --opt photosAlbum=Trip # macOS: then into Apple Photos
lightcraft-cli commands [--json] # the command registry
lightcraft-cli controls [--json] # develop control ids and ranges
lightcraft-cli calibrate --max 300 ~/Pictures/2026 # camera colour profiles (docs/camera-preview-colour.md)
@@ -283,6 +284,23 @@ lightcraft-cli calibrate --max 300 ~/Pictures/2026 # camera colour profiles (d
- `apps/lightcraft-cli/tests/cli.rs` — spawns `lightcraft-cli mcp` with real pipes; `render`;
`commands`.
## Add to Apple Photos (macOS)
`app.export` (MCP `export` tool, `lightcraft-cli run`, the desktop app) takes `addToPhotos: true` and
`photosAlbum` to hand the files it wrote to Apple Photos, into that album (a top-level album of exactly that
name, made when missing). The result's `applePhotos` is the import job: `{job, running, requested, album}`
plus `{imported, ids, warning?}`, `{error}` or `{skipped}` once Photos is done; the files are written either
way. Headless (this server, `lightcraft-cli`) waits for Photos by default; the desktop app (connect mode)
answers with the running job and `export.photosImports {job}` gives the outcome. `export.addToPhotos {paths,
album?, wait?}` does the same for files already on disk (`wait` defaults to true headless, false in the desktop
app, which refuses `wait: true`; with `wait: false` headless, the server waits for the import before it exits at end of input). One import
runs at a time, and an export adding to Photos reserves it before it writes: another is refused, naming the
job in the way. On other platforms `addToPhotos: true` is refused before anything is written, and
`export.addToPhotos` is disabled with the reason. The first time, macOS asks the user to allow LightCraft (or
the terminal running `lightcraft-cli`) to control Photos. After that, any client can add any file LightCraft can
read to the user's Photos library (and so to iCloud Photos when that is on), not only exported ones: see [Who
can add what](apple-photos.md#how-it-works).
## Export progress and cancellation
Headless direct `export`, `command_run` / `run_command` with `app.export`, and `cmd_app_export`