From 6cbc0eb5a9751c75c0952dda474fc3e27b0a4976 Mon Sep 17 00:00:00 2001 From: Andrew Frahn Date: Sat, 10 Oct 2026 10:30:06 +1100 Subject: [PATCH] Phase 0: configurable brand, MIT licence, plan/ and Immich tracker - brand.toml is the only place the product name lives; every crate and app reads it through dac-brand (env vars with legacy fallback, settings folder with copy-only migration, default library, preset extensions, i18n {app}) - cargo xtask brand check|test, run|install|package, docs, rename-crates, deny and immich; packaging files are templates rendered from brand.toml - icons regenerated from brand/icon.svg; upstream branding removed - MIT licence (segment and fetch stay Apache-2.0); cargo deny licence policy - clean-room rules in AGENTS.md/CLAUDE.md; docs/upstream-merge.md - plan/ rebuilt and committed; parity tracker reopens Classic rows, adds PLAN.md section 2 rows and the IMM Immich section; plan/immich.md and a pinned Immich test server Co-Authored-By: Claude Opus 5.5 (1M context) --- .github/workflows/brand.yml | 62 ++ .github/workflows/packaging-lint.yml | 33 +- .github/workflows/release.yml | 70 +- .github/workflows/windows-arm64.yml | 21 +- .gitignore | 3 +- AGENTS.md | 60 +- CLAUDE.md | 60 +- Cargo.lock | 30 + Cargo.toml | 6 +- LICENSE-MIT => LICENSE | 4 +- NOTICE | 28 +- PLAN.md | 746 ++++++++++++++++++ PLAN_phase_0.md | 262 ++++++ PLAN_phase_1.md | 251 ++++++ PLAN_phase_2.md | 231 ++++++ PLAN_phase_3.md | 189 +++++ PLAN_phase_4.md | 217 +++++ README.md | 220 ++---- ROADMAP.md | 6 +- apps/app/Cargo.toml | 4 +- apps/app/build.rs | 29 +- apps/app/src/control_server.rs | 2 +- apps/app/src/logging.rs | 137 ++-- apps/app/src/main.rs | 129 +-- apps/app/src/native_menu.rs | 10 +- apps/cli/Cargo.toml | 4 +- apps/cli/src/main.rs | 188 +++-- apps/cli/tests/cli.rs | 48 +- apps/web/Cargo.toml | 3 +- apps/web/index.html | 28 +- apps/web/src/backend.rs | 4 +- apps/web/src/backup.rs | 8 +- apps/web/src/bench.rs | 2 +- apps/web/src/legacy.rs | 7 + apps/web/src/lib.rs | 4 +- apps/web/src/safety.rs | 29 +- apps/web/src/store.rs | 2 +- apps/web/src/web.rs | 67 +- apps/web/src/workers.rs | 6 +- apps/web/worker.js | 2 +- assets/ATTRIBUTION.md | 6 +- assets/app-icon/LICENSE.txt | 15 +- assets/app-icon/README.md | 53 +- assets/app-icon/app-1024.png | Bin 0 -> 68664 bytes assets/app-icon/app-macos-512.png | Bin 0 -> 26048 bytes assets/app-icon/app.icns | Bin 0 -> 176667 bytes assets/app-icon/app.ico | Bin 0 -> 34376 bytes .../apps/ai.storyteller.lightcraft.png | Bin 16635 -> 0 bytes assets/app-icon/hicolor/128x128/apps/app.png | Bin 0 -> 7235 bytes .../16x16/apps/ai.storyteller.lightcraft.png | Bin 663 -> 0 bytes assets/app-icon/hicolor/16x16/apps/app.png | Bin 0 -> 698 bytes .../24x24/apps/ai.storyteller.lightcraft.png | Bin 1113 -> 0 bytes assets/app-icon/hicolor/24x24/apps/app.png | Bin 0 -> 1083 bytes .../apps/ai.storyteller.lightcraft.png | Bin 55310 -> 0 bytes assets/app-icon/hicolor/256x256/apps/app.png | Bin 0 -> 14916 bytes .../32x32/apps/ai.storyteller.lightcraft.png | Bin 1813 -> 0 bytes assets/app-icon/hicolor/32x32/apps/app.png | Bin 0 -> 1562 bytes .../48x48/apps/ai.storyteller.lightcraft.png | Bin 3245 -> 0 bytes assets/app-icon/hicolor/48x48/apps/app.png | Bin 0 -> 2438 bytes .../apps/ai.storyteller.lightcraft.png | Bin 146129 -> 0 bytes assets/app-icon/hicolor/512x512/apps/app.png | Bin 0 -> 31172 bytes .../64x64/apps/ai.storyteller.lightcraft.png | Bin 5189 -> 0 bytes assets/app-icon/hicolor/64x64/apps/app.png | Bin 0 -> 3386 bytes .../apps/ai.storyteller.lightcraft.svg | 1 - assets/app-icon/hicolor/scalable/apps/app.svg | 7 + assets/app-icon/lightcraft-1024.png | Bin 344217 -> 0 bytes assets/app-icon/lightcraft-macos-512.png | Bin 112295 -> 0 bytes assets/app-icon/lightcraft-small.svg | 1 - assets/app-icon/lightcraft.icns | Bin 680493 -> 0 bytes assets/app-icon/lightcraft.ico | Bin 87512 -> 0 bytes assets/app-icon/lightcraft.svg | 1 - brand/icon.svg | 7 + brand/logo.svg | 7 + crates/brand/src/lib.rs | 4 +- crates/catalog/Cargo.toml | 3 +- crates/catalog/src/journal.rs | 12 +- crates/catalog/src/lib.rs | 6 +- crates/catalog/src/lock.rs | 10 +- crates/catalog/src/model.rs | 2 +- crates/catalog/src/safe_file.rs | 2 +- crates/catalog/src/tests_background.rs | 2 +- crates/catalog/src/tests_format_version.rs | 2 +- crates/catalog/src/tests_lock.rs | 28 +- crates/codecs/Cargo.toml | 3 +- crates/codecs/README.md | 2 +- crates/codecs/src/heif.rs | 2 +- crates/codecs/src/lib.rs | 2 +- crates/codecs/src/sniff.rs | 2 +- crates/codecs/tests/corpus.rs | 4 +- crates/color/Cargo.toml | 3 +- crates/color/src/lib.rs | 2 +- crates/denoise-core/Cargo.toml | 3 +- crates/denoise-core/src/known.rs | 8 +- crates/denoise-core/src/licence.rs | 2 +- crates/denoise-core/src/run.rs | 4 +- crates/denoise/Cargo.toml | 3 +- crates/denoise/src/cpu.rs | 2 +- crates/denoise/src/cpu/tests.rs | 2 +- crates/denoise/src/lib.rs | 4 +- crates/develop/Cargo.toml | 3 +- crates/develop/src/lib.rs | 2 +- crates/develop/src/settings.rs | 2 +- crates/engine/Cargo.toml | 3 +- crates/engine/examples/render_bench.rs | 6 +- crates/engine/src/camera_preview.rs | 10 +- crates/engine/src/camera_profiles.rs | 16 +- crates/engine/src/cmd/curves.rs | 2 +- crates/engine/src/cmd/denoise.rs | 18 +- crates/engine/src/cmd/export.rs | 2 +- crates/engine/src/cmd/face_models.rs | 8 +- crates/engine/src/cmd/lut_profiles.rs | 2 +- crates/engine/src/cmd/masks.rs | 2 +- crates/engine/src/cmd/query.rs | 2 +- crates/engine/src/config.rs | 26 +- crates/engine/src/demo.rs | 2 +- crates/engine/src/denoise.rs | 10 +- crates/engine/src/devices.rs | 8 +- crates/engine/src/export.rs | 6 +- crates/engine/src/faces_index.rs | 2 +- crates/engine/src/faces_worker.rs | 8 +- crates/engine/src/files.rs | 4 +- crates/engine/src/fonts.rs | 2 +- crates/engine/src/import.rs | 12 +- crates/engine/src/legacy.rs | 12 + crates/engine/src/lib.rs | 9 +- crates/engine/src/library.rs | 34 +- crates/engine/src/lightroom_archive.rs | 2 +- crates/engine/src/lightroom_catalog.rs | 12 +- crates/engine/src/lightroom_job.rs | 4 +- crates/engine/src/logging.rs | 35 +- crates/engine/src/media.rs | 2 +- crates/engine/src/memory.rs | 6 +- crates/engine/src/merge.rs | 2 +- crates/engine/src/originals.rs | 6 +- crates/engine/src/preset_import.rs | 2 +- crates/engine/src/presets.rs | 12 +- crates/engine/src/segment/mod.rs | 8 +- crates/engine/src/sidecar.rs | 14 +- crates/engine/src/smart.rs | 2 +- crates/engine/src/tests_denoise.rs | 2 +- crates/engine/src/tests_face_models.rs | 2 +- crates/engine/src/tests_import.rs | 2 +- crates/engine/src/tests_import_move.rs | 4 +- crates/engine/src/tests_persist.rs | 2 +- crates/engine/src/tests_segment.rs | 2 +- crates/engine/src/tests_xmp.rs | 6 +- crates/faces/Cargo.toml | 3 +- crates/faces/src/catalog.rs | 8 +- crates/faces/src/known.rs | 10 +- crates/faces/src/lib.rs | 2 +- crates/faces/src/manifest.rs | 4 +- crates/faces/src/net.rs | 4 +- crates/faces/src/runtime.rs | 2 +- crates/faces/src/suggest.rs | 2 +- crates/faces/src/yunet.rs | 2 +- crates/fetch/Cargo.toml | 5 +- LICENSE-APACHE => crates/fetch/LICENSE-APACHE | 0 crates/fetch/src/http.rs | 3 +- crates/fetch/src/lib.rs | 6 +- crates/geom/Cargo.toml | 3 +- crates/geom/src/lib.rs | 2 +- crates/gpu/Cargo.toml | 3 +- crates/gpu/src/backend.rs | 29 +- crates/gpu/src/ctx.rs | 8 +- crates/gpu/src/lib.rs | 28 +- crates/gpu/src/nn.rs | 8 +- crates/gpu/src/render.rs | 4 +- crates/heif/Cargo.toml | 3 +- crates/heif/README.md | 4 +- crates/heif/src/lib.rs | 2 +- crates/mcp/Cargo.toml | 3 +- crates/mcp/src/backend.rs | 9 +- crates/mcp/src/headless.rs | 4 +- crates/mcp/src/lib.rs | 8 +- crates/mcp/src/server.rs | 20 +- crates/mcp/src/tests.rs | 16 +- crates/mcp/src/tools.rs | 6 +- crates/mcp/tests/e2e.rs | 4 +- crates/merge/Cargo.toml | 3 +- crates/merge/src/lib.rs | 2 +- crates/merge/src/output.rs | 2 +- crates/merge/src/synth.rs | 2 +- crates/meta/Cargo.toml | 3 +- crates/meta/README.md | 2 +- crates/meta/src/cr3.rs | 2 +- crates/meta/src/legacy.rs | 5 + crates/meta/src/lib.rs | 7 +- crates/meta/src/xmp.rs | 12 +- crates/meta/src/xmp_merge.rs | 2 +- crates/pipeline/Cargo.toml | 3 +- crates/pipeline/src/lib.rs | 8 +- crates/preview/Cargo.toml | 3 +- crates/raster/Cargo.toml | 3 +- crates/raster/src/lib.rs | 2 +- crates/raw/Cargo.toml | 3 +- crates/raw/src/dngwrite.rs | 4 +- crates/raw/src/lib.rs | 2 +- crates/raw/src/vendor/crx.rs | 2 +- crates/raw/src/vendor/rw2.rs | 2 +- crates/raw/tests/corpus.rs | 4 +- crates/raw/tests/cr3_corpus.rs | 2 +- crates/scenes/Cargo.toml | 3 +- crates/segment/Cargo.toml | 3 +- crates/segment/LICENSE-APACHE | 177 +++++ ...ghtcraft-sam3-worker.rs => sam3-worker.rs} | 4 +- crates/segment/src/clip.rs | 2 +- crates/segment/src/detector.rs | 2 +- crates/segment/src/fetch/mod.rs | 23 +- crates/segment/src/lib.rs | 8 +- crates/segment/src/mask.rs | 2 +- crates/segment/src/neck.rs | 2 +- crates/segment/src/nn.rs | 2 +- crates/segment/src/remote.rs | 5 +- crates/segment/src/tokenizer.rs | 2 +- crates/segment/src/tracker.rs | 2 +- crates/segment/src/vit.rs | 2 +- crates/segment/tests/reference.rs | 8 +- crates/sysmem/Cargo.toml | 3 +- crates/sysmem/src/lib.rs | 2 +- crates/tiff/Cargo.toml | 3 +- crates/tiff/src/lib.rs | 2 +- crates/ui-egui/Cargo.toml | 4 +- crates/ui-egui/build.rs | 12 +- crates/ui-egui/examples/grid_bench.rs | 2 +- crates/ui-egui/locales/de-formats.json | 12 +- crates/ui-egui/locales/de.json | 83 +- crates/ui-egui/locales/es-formats.json | 12 +- crates/ui-egui/locales/es.json | 47 +- crates/ui-egui/locales/ja-formats.json | 12 +- crates/ui-egui/locales/ja.json | 49 +- crates/ui-egui/locales/pt-br-formats.json | 12 +- crates/ui-egui/locales/pt-br.json | 47 +- crates/ui-egui/locales/ru-formats.json | 12 +- crates/ui-egui/locales/ru.json | 44 +- crates/ui-egui/locales/zh-hans-formats.json | 12 +- crates/ui-egui/locales/zh-hans.json | 47 +- crates/ui-egui/locales/zh-hant-formats.json | 12 +- crates/ui-egui/locales/zh-hant.json | 47 +- crates/ui-egui/src/control.rs | 9 +- crates/ui-egui/src/headless.rs | 6 +- crates/ui-egui/src/i18n.rs | 60 +- crates/ui-egui/src/icons.rs | 2 +- crates/ui-egui/src/lib.rs | 8 +- crates/ui-egui/src/lightroom_import.rs | 2 +- crates/ui-egui/src/links.rs | 39 +- crates/ui-egui/src/menubar.rs | 5 +- crates/ui-egui/src/menus.rs | 24 +- crates/ui-egui/src/panels/denoise.rs | 11 +- crates/ui-egui/src/panels/detail.rs | 2 +- crates/ui-egui/src/panels/dialogs.rs | 28 +- crates/ui-egui/src/panels/faces.rs | 17 +- crates/ui-egui/src/panels/library_problem.rs | 4 +- crates/ui-egui/src/panels/right.rs | 2 +- crates/ui-egui/src/panels/second.rs | 4 +- crates/ui-egui/src/panels/settings.rs | 10 +- crates/ui-egui/src/panels/topbar.rs | 3 +- crates/ui-egui/src/pick.rs | 4 +- crates/ui-egui/src/shortcuts.rs | 2 +- crates/ui-egui/src/tests_grid.rs | 2 +- crates/ui-egui/src/tests_library_problem.rs | 8 +- crates/ui-egui/src/tests_masking.rs | 2 +- crates/ui-egui/src/tests_offline.rs | 4 +- crates/ui-egui/src/tests_titlebar.rs | 2 +- crates/ui-egui/src/widgets.rs | 2 +- deny.toml | 43 + docs/ai-masks.md | 51 +- docs/brand/LICENSE-brand.txt | 42 - docs/brand/artcraft-logo-white.png | Bin 32161 -> 0 bytes docs/brand/artcraft-logo-white.svg | 7 - docs/brand/artcraft-logo.png | Bin 31302 -> 0 bytes docs/brand/artcraft-logo.svg | 7 - docs/brand/artcraft-mark-black.png | Bin 26793 -> 0 bytes docs/brand/artcraft-mark-black.svg | 4 - docs/brand/artcraft-mark.png | Bin 24715 -> 0 bytes docs/brand/artcraft-mark.svg | 4 - docs/camera-preview-colour.md | 11 +- docs/contributors.md | 9 +- docs/control-protocol.md | 15 +- docs/cr3.md | 2 +- docs/denoise.md | 5 +- docs/faces.md | 41 +- docs/gpu-pipeline.md | 55 +- docs/library-shortcuts.md | 6 +- docs/lightroom-catalog-import.md | 19 +- docs/localization-de.md | 9 +- docs/localization-es.md | 10 +- docs/localization-ja.md | 10 +- docs/localization-pt-br.md | 11 +- docs/localization-ru.md | 9 +- docs/localization-zh-hans.md | 12 +- docs/localization-zh-hant.md | 10 +- docs/localization.md | 20 +- docs/mcp.md | 77 +- docs/merge.md | 7 +- docs/parity.md | 138 ++-- docs/raf-compression.md | 2 +- docs/releasing.md | 17 +- docs/showcase/README.md | 2 +- docs/showcase/demo.jsonl | 2 +- docs/showcase/pd-edits.jsonl | 2 +- docs/upstream-merge.md | 70 ++ docs/vertical-watermarks.md | 2 +- docs/web.md | 15 +- docs/whats-new.md | 46 +- docs/xmp-interop.md | 43 +- flake.nix | 26 +- nix/package.nix | 78 +- packaging/env.sh | 103 ++- packaging/freebsd/package.sh | 45 +- packaging/icons.sh | 50 +- .../ai.storyteller.lightcraft.metainfo.xml.in | 61 -- packaging/linux/flatpak-bundle.sh | 23 +- ...raft.bundle.yml => {app_id}.bundle.yml.in} | 29 +- ...yteller.lightcraft.yml => {app_id}.yml.in} | 51 +- packaging/linux/{nfpm.yaml => nfpm.yaml.in} | 28 +- packaging/linux/package.sh | 70 +- ...lightcraft.desktop => {app_id}.desktop.in} | 10 +- packaging/linux/{app_id}.metainfo.xml.in | 54 ++ ...ghtcraft.mime.xml => {app_id}.mime.xml.in} | 0 packaging/macos/Info.plist.in | 40 +- packaging/macos/dmg/README.md | 8 +- packaging/macos/dmg/background.svg | 2 +- packaging/macos/dmg/generate.py | 10 +- packaging/macos/entitlements.plist | 2 +- packaging/macos/import-cert.sh | 4 +- packaging/macos/package.sh | 55 +- packaging/web/{README.md => HOSTING.md.in} | 18 +- packaging/web/package.sh | 10 +- packaging/windows/app.wxs.in | 61 ++ packaging/windows/brand.ps1 | 39 + packaging/windows/lightcraft.wxs | 60 -- packaging/windows/package.ps1 | 45 +- packaging/windows/sign.ps1 | 7 +- plan/README.md | 14 + plan/STATUS.md | 65 ++ plan/architecture.md | 93 +++ plan/execution-plan.md | 36 + plan/immich.md | 146 ++++ plan/lightroom-classic/README.md | 18 + plan/lightroom-classic/feature-catalog.md | 741 +++++++++++++++++ plan/lightroom-classic/menus.md | 38 + plan/lightroom-classic/modules.md | 121 +++ plan/lightroom-classic/shortcuts.md | 29 + plan/phase-0.md | 264 +++++++ plan/phase-1.md | 253 ++++++ plan/phase-2.md | 233 ++++++ plan/phase-3.md | 191 +++++ plan/phase-4.md | 219 +++++ tools/install-sam3.ps1 | 11 +- tools/install-sam3.sh | 19 +- tools/sam3_reference.py | 17 +- xtask/immich/compose.yml | 69 ++ xtask/src/brand.rs | 621 +++++++++++++++ xtask/src/dist.rs | 377 +++++++++ xtask/src/docs.rs | 56 ++ xtask/src/ico.rs | 2 +- xtask/src/immich.rs | 375 +++++++++ xtask/src/layers.rs | 8 + xtask/src/main.rs | 52 +- xtask/src/parity.rs | 19 +- xtask/src/rename.rs | 211 +++++ xtask/src/web.rs | 4 +- xtask/test-brand.toml | 35 + 363 files changed, 9081 insertions(+), 2129 deletions(-) create mode 100644 .github/workflows/brand.yml rename LICENSE-MIT => LICENSE (89%) create mode 100644 PLAN.md create mode 100644 PLAN_phase_0.md create mode 100644 PLAN_phase_1.md create mode 100644 PLAN_phase_2.md create mode 100644 PLAN_phase_3.md create mode 100644 PLAN_phase_4.md create mode 100644 apps/web/src/legacy.rs create mode 100644 assets/app-icon/app-1024.png create mode 100644 assets/app-icon/app-macos-512.png create mode 100644 assets/app-icon/app.icns create mode 100644 assets/app-icon/app.ico delete mode 100644 assets/app-icon/hicolor/128x128/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/128x128/apps/app.png delete mode 100644 assets/app-icon/hicolor/16x16/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/16x16/apps/app.png delete mode 100644 assets/app-icon/hicolor/24x24/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/24x24/apps/app.png delete mode 100644 assets/app-icon/hicolor/256x256/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/256x256/apps/app.png delete mode 100644 assets/app-icon/hicolor/32x32/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/32x32/apps/app.png delete mode 100644 assets/app-icon/hicolor/48x48/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/48x48/apps/app.png delete mode 100644 assets/app-icon/hicolor/512x512/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/512x512/apps/app.png delete mode 100644 assets/app-icon/hicolor/64x64/apps/ai.storyteller.lightcraft.png create mode 100644 assets/app-icon/hicolor/64x64/apps/app.png delete mode 100644 assets/app-icon/hicolor/scalable/apps/ai.storyteller.lightcraft.svg create mode 100644 assets/app-icon/hicolor/scalable/apps/app.svg delete mode 100644 assets/app-icon/lightcraft-1024.png delete mode 100644 assets/app-icon/lightcraft-macos-512.png delete mode 100644 assets/app-icon/lightcraft-small.svg delete mode 100644 assets/app-icon/lightcraft.icns delete mode 100644 assets/app-icon/lightcraft.ico delete mode 100644 assets/app-icon/lightcraft.svg create mode 100644 brand/icon.svg create mode 100644 brand/logo.svg create mode 100644 crates/engine/src/legacy.rs rename LICENSE-APACHE => crates/fetch/LICENSE-APACHE (100%) create mode 100644 crates/meta/src/legacy.rs create mode 100644 crates/segment/LICENSE-APACHE rename crates/segment/src/bin/{lightcraft-sam3-worker.rs => sam3-worker.rs} (78%) create mode 100644 deny.toml delete mode 100644 docs/brand/LICENSE-brand.txt delete mode 100644 docs/brand/artcraft-logo-white.png delete mode 100644 docs/brand/artcraft-logo-white.svg delete mode 100644 docs/brand/artcraft-logo.png delete mode 100644 docs/brand/artcraft-logo.svg delete mode 100644 docs/brand/artcraft-mark-black.png delete mode 100644 docs/brand/artcraft-mark-black.svg delete mode 100644 docs/brand/artcraft-mark.png delete mode 100644 docs/brand/artcraft-mark.svg create mode 100644 docs/upstream-merge.md delete mode 100644 packaging/linux/ai.storyteller.lightcraft.metainfo.xml.in rename packaging/linux/flatpak/{ai.storyteller.lightcraft.bundle.yml => {app_id}.bundle.yml.in} (63%) rename packaging/linux/flatpak/{ai.storyteller.lightcraft.yml => {app_id}.yml.in} (51%) rename packaging/linux/{nfpm.yaml => nfpm.yaml.in} (69%) rename packaging/linux/{ai.storyteller.lightcraft.desktop => {app_id}.desktop.in} (71%) create mode 100644 packaging/linux/{app_id}.metainfo.xml.in rename packaging/linux/{ai.storyteller.lightcraft.mime.xml => {app_id}.mime.xml.in} (100%) rename packaging/web/{README.md => HOSTING.md.in} (91%) create mode 100644 packaging/windows/app.wxs.in create mode 100644 packaging/windows/brand.ps1 delete mode 100644 packaging/windows/lightcraft.wxs create mode 100644 plan/README.md create mode 100644 plan/STATUS.md create mode 100644 plan/architecture.md create mode 100644 plan/execution-plan.md create mode 100644 plan/immich.md create mode 100644 plan/lightroom-classic/README.md create mode 100644 plan/lightroom-classic/feature-catalog.md create mode 100644 plan/lightroom-classic/menus.md create mode 100644 plan/lightroom-classic/modules.md create mode 100644 plan/lightroom-classic/shortcuts.md create mode 100644 plan/phase-0.md create mode 100644 plan/phase-1.md create mode 100644 plan/phase-2.md create mode 100644 plan/phase-3.md create mode 100644 plan/phase-4.md create mode 100644 xtask/immich/compose.yml create mode 100644 xtask/src/brand.rs create mode 100644 xtask/src/dist.rs create mode 100644 xtask/src/docs.rs create mode 100644 xtask/src/immich.rs create mode 100644 xtask/src/rename.rs create mode 100644 xtask/test-brand.toml diff --git a/.github/workflows/brand.yml b/.github/workflows/brand.yml new file mode 100644 index 0000000000..1b992c9ef0 --- /dev/null +++ b/.github/workflows/brand.yml @@ -0,0 +1,62 @@ +# The product name lives only in brand.toml (PLAN_phase_0.md §0.2.4), and the licence policy is +# enforced by cargo-deny (§0.4.6): +# - check: `cargo xtask brand check` (no product name outside brand.toml and the allowlist), +# `cargo xtask docs --check` (rendered docs up to date); +# - deny: `cargo deny check licenses` with deny.toml; +# - throw-away brand: `cargo xtask brand test` builds the CLI with xtask/test-brand.toml +# ("Zzyzx Test") and checks its help, headless UI snapshot, MCP serverInfo and config/log paths. +name: Brand + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: brand-${{ github.ref }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: 0 + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + key: brand-check + - name: brand check + run: cargo xtask brand check + - name: docs up to date + run: cargo xtask docs --check + + deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/install-action@v2 + with: + tool: cargo-deny + - name: cargo deny check licenses + run: cargo deny check licenses + + test-brand: + name: throw-away brand + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + key: brand-test + workspaces: ". -> target/brand-test" + - name: cargo xtask brand test + run: cargo xtask brand test diff --git a/.github/workflows/packaging-lint.yml b/.github/workflows/packaging-lint.yml index 0e2388a620..e645ff5608 100644 --- a/.github/workflows/packaging-lint.yml +++ b/.github/workflows/packaging-lint.yml @@ -5,9 +5,9 @@ name: Packaging lint on: push: branches: [main, release] - paths: [".github/workflows/**", "packaging/**", "assets/app-icon/**"] + paths: [".github/workflows/**", "packaging/**", "assets/app-icon/**", "brand.toml"] pull_request: - paths: [".github/workflows/**", "packaging/**", "assets/app-icon/**"] + paths: [".github/workflows/**", "packaging/**", "assets/app-icon/**", "brand.toml"] workflow_dispatch: permissions: @@ -44,22 +44,33 @@ jobs: if ($errors) { $errors | ForEach-Object { Write-Output "::error file=$($f.Name)::$_" }; exit 1 } Write-Output "ok $($f.Name)" } + - name: Render the packaging templates (brand.toml) + run: | + . packaging/env.sh + OUT="$RUNNER_TEMP/pkg" + for t in packaging/linux/*.in packaging/linux/flatpak/*.in packaging/macos/*.in packaging/windows/*.in; do + rel="${t#packaging/}"; rel="${rel%.in}"; rel="${rel//\{app_id\}/$BRAND_APP_ID}" + brand_render "$t" "$OUT/$rel" + done + echo "OUT=$OUT" >>"$GITHUB_ENV" + echo "APP_ID=$BRAND_APP_ID" >>"$GITHUB_ENV" + echo "APP_BINARY=$BRAND_BINARY" >>"$GITHUB_ENV" - name: XML, desktop entry, AppStream, Flatpak manifest run: | - xmllint --noout packaging/windows/lightcraft.wxs packaging/macos/*.plist* packaging/linux/*.xml* + xmllint --noout "$OUT"/windows/app.wxs "$OUT"/macos/*.plist "$OUT"/linux/*.xml packaging/macos/entitlements.plist # Windows Installer needs Icon ids ending in .ico or .exe, or shortcuts show a blank icon. - if grep -oE '"$RUNNER_TEMP/ai.storyteller.lightcraft.metainfo.xml" - appstreamcli validate --no-net --explain "$RUNNER_TEMP/ai.storyteller.lightcraft.metainfo.xml" + desktop-file-validate "$OUT/linux/$APP_ID.desktop" + appstreamcli validate --no-net --explain "$OUT/linux/$APP_ID.metainfo.xml" python3 - <<'EOF' - import yaml - src = yaml.safe_load(open("packaging/linux/flatpak/ai.storyteller.lightcraft.yml")) - bundle = yaml.safe_load(open("packaging/linux/flatpak/ai.storyteller.lightcraft.bundle.yml")) + import os, yaml + out, app_id, binary = os.environ["OUT"], os.environ["APP_ID"], os.environ["APP_BINARY"] + src = yaml.safe_load(open(f"{out}/linux/flatpak/{app_id}.yml")) + bundle = yaml.safe_load(open(f"{out}/linux/flatpak/{app_id}.bundle.yml")) for m in (src, bundle): - assert m["id"] == "ai.storyteller.lightcraft" and m["command"] == "lightcraft", m["id"] + assert m["id"] == app_id and m["command"] == binary, m["id"] for key in ("runtime", "runtime-version", "sdk", "finish-args"): assert src[key] == bundle[key], f"Flatpak manifests disagree on {key}: {src[key]} vs {bundle[key]}" print("Flatpak manifests ok") diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b9c3a1ea32..19480e4c45 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,5 @@ # Release pipeline: every push to `release` builds platform artifacts (signed where credentials -# are configured) and creates or updates the draft GitHub Release "LightCraft v". +# are configured) and creates or updates the draft GitHub Release " v". # See docs/releasing.md. # # The signing jobs (macOS, Windows) and the draft-release job run in the `release` environment @@ -31,7 +31,7 @@ env: CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 RUST_BACKTRACE: 1 - LIGHTCRAFT_BUILD_SHA: ${{ github.sha }} + BUILD_SHA: ${{ github.sha }} INPUT_VERSION: ${{ inputs.version }} jobs: @@ -43,6 +43,11 @@ jobs: version: ${{ steps.v.outputs.version }} date: ${{ steps.v.outputs.date }} prerelease: ${{ steps.v.outputs.prerelease }} + # brand.toml (the product name lives only there) + display_name: ${{ steps.v.outputs.display_name }} + binary: ${{ steps.v.outputs.binary }} + cli_binary: ${{ steps.v.outputs.cli_binary }} + app_id: ${{ steps.v.outputs.app_id }} steps: - uses: actions/checkout@v4 - id: v @@ -60,8 +65,12 @@ jobs: echo "version=$v" echo "date=$(date -u +%Y-%m-%d)" echo "prerelease=$pre" + echo "display_name=$BRAND_DISPLAY_NAME" + echo "binary=$BRAND_BINARY" + echo "cli_binary=$BRAND_CLI_BINARY" + echo "app_id=$BRAND_APP_ID" } >>"$GITHUB_OUTPUT" - echo "### LightCraft v$v (\`${GITHUB_SHA::9}\`)" >>"$GITHUB_STEP_SUMMARY" + echo "### $BRAND_DISPLAY_NAME v$v (\`${GITHUB_SHA::9}\`)" >>"$GITHUB_STEP_SUMMARY" macos: name: macOS universal @@ -69,8 +78,8 @@ jobs: runs-on: macos-15-xlarge # M2 Pro larger runner; use only in release.yml (actions_macos_xl budget caps spend) environment: release env: - LIGHTCRAFT_VERSION: ${{ needs.version.outputs.version }} - LIGHTCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + PACKAGE_VERSION: ${{ needs.version.outputs.version }} + BUILD_DATE: ${{ needs.version.outputs.date }} steps: - uses: actions/checkout@v4 # Fonts (optional build input; required for releases): see craftrules standards/fonts.md. @@ -87,7 +96,7 @@ jobs: key: release-macos-universal - name: Apply version override if: inputs.version != '' - run: cargo xtask version set "$LIGHTCRAFT_VERSION" + run: cargo xtask version set "$PACKAGE_VERSION" - name: Import signing certificate env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} @@ -127,8 +136,8 @@ jobs: # .github/workflows/windows-arm64.yml installs and runs it on ARM64 hardware. - { arch: arm64, target: aarch64-pc-windows-msvc } env: - LIGHTCRAFT_VERSION: ${{ needs.version.outputs.version }} - LIGHTCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + PACKAGE_VERSION: ${{ needs.version.outputs.version }} + BUILD_DATE: ${{ needs.version.outputs.date }} steps: - uses: actions/checkout@v4 # Fonts (optional build input; required for releases): see craftrules standards/fonts.md. @@ -146,7 +155,7 @@ jobs: - name: Apply version override if: inputs.version != '' shell: bash - run: cargo xtask version set "$LIGHTCRAFT_VERSION" + run: cargo xtask version set "$PACKAGE_VERSION" - name: Install WiX shell: pwsh run: dotnet tool install --global wix --version 5.0.2 @@ -183,8 +192,8 @@ jobs: - { arch: x86_64, runner: ubuntu-22.04, deb: amd64 } - { arch: aarch64, runner: ubuntu-22.04-arm, deb: arm64 } env: - LIGHTCRAFT_VERSION: ${{ needs.version.outputs.version }} - LIGHTCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + PACKAGE_VERSION: ${{ needs.version.outputs.version }} + BUILD_DATE: ${{ needs.version.outputs.date }} NFPM_VERSION: 2.47.0 steps: - uses: actions/checkout@v4 @@ -209,7 +218,7 @@ jobs: key: release-linux-${{ matrix.arch }} - name: Apply version override if: inputs.version != '' - run: cargo xtask version set "$LIGHTCRAFT_VERSION" + run: cargo xtask version set "$PACKAGE_VERSION" - name: Build and package (AppImage, deb, rpm, tar.gz) env: CRAFT_FONTS_DIR: ${{ github.workspace }}/craft-fonts @@ -218,9 +227,11 @@ jobs: - name: Check the packages run: | dpkg-deb --info dist/release/*.deb - dpkg-deb --contents dist/release/*.deb | grep -E 'usr/bin/lightcraft$|metainfo|applications' - ldd target/release/lightcraft - python3 -c "import yaml; m = yaml.safe_load(open('packaging/linux/flatpak/ai.storyteller.lightcraft.yml')); assert m['id'] == 'ai.storyteller.lightcraft'" + . packaging/env.sh + dpkg-deb --contents dist/release/*.deb | grep -E "usr/bin/$BRAND_BINARY\$|metainfo|applications" + ldd target/release/app + cargo xtask package --render-only + python3 -c "import yaml, os; a = os.environ['BRAND_APP_ID']; m = yaml.safe_load(open(f'target/package/linux/flatpak/{a}.yml')); assert m['id'] == a" for appimage in dist/release/*.AppImage; do chmod +x "$appimage" APPIMAGE_EXTRACT_AND_RUN=1 "$appimage" --version @@ -247,8 +258,8 @@ jobs: - { arch: x86_64, runner: ubuntu-24.04 } - { arch: aarch64, runner: ubuntu-24.04-arm } env: - LIGHTCRAFT_VERSION: ${{ needs.version.outputs.version }} - LIGHTCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + PACKAGE_VERSION: ${{ needs.version.outputs.version }} + BUILD_DATE: ${{ needs.version.outputs.date }} steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 @@ -264,7 +275,7 @@ jobs: # Ubuntu 24.04's AppArmor blocks the unprivileged user namespaces bubblewrap needs. sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 - name: Build the Flatpak bundle - run: packaging/linux/flatpak-bundle.sh "dist/linux/lightcraft-$LIGHTCRAFT_VERSION-linux-${{ matrix.arch }}.tar.gz" + run: packaging/linux/flatpak-bundle.sh "dist/linux/${{ needs.version.outputs.binary }}-$PACKAGE_VERSION-linux-${{ matrix.arch }}.tar.gz" - uses: actions/upload-artifact@v4 with: name: release-flatpak-${{ matrix.arch }} @@ -279,8 +290,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 180 env: - LIGHTCRAFT_VERSION: ${{ needs.version.outputs.version }} - LIGHTCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + PACKAGE_VERSION: ${{ needs.version.outputs.version }} + BUILD_DATE: ${{ needs.version.outputs.date }} steps: - uses: actions/checkout@v4 # Fonts (optional build input; required for releases): see craftrules standards/fonts.md. @@ -298,7 +309,7 @@ jobs: cpu: 4 mem: 12288 # Passed into the VM by name; never templated into the script below. - envs: "LIGHTCRAFT_VERSION LIGHTCRAFT_BUILD_DATE LIGHTCRAFT_BUILD_SHA INPUT_VERSION" + envs: "PACKAGE_VERSION BUILD_DATE BUILD_SHA INPUT_VERSION" # The FreeBSD CI packages, plus bash for the packaging script. prepare: | pkg install -y bash git curl pkgconf cmake python3 libxkbcommon wayland libX11 libXcursor libXrandr libXi libxcb mesa-libs vulkan-loader gtk3 fontconfig freetype2 alsa-lib @@ -309,13 +320,14 @@ jobs: git config --global --add safe.directory "$PWD" # Build outside the checkout so only dist/ is copied back out of the VM (copying the # target dir back fails on large builds). 4 jobs: more runs the VM out of memory. - export CARGO_TARGET_DIR=/var/tmp/lightcraft-target CARGO_BUILD_JOBS=4 - if [ -n "$INPUT_VERSION" ]; then cargo xtask version set "$LIGHTCRAFT_VERSION"; fi + export CARGO_TARGET_DIR=/var/tmp/app-target CARGO_BUILD_JOBS=4 + if [ -n "$INPUT_VERSION" ]; then cargo xtask version set "$PACKAGE_VERSION"; fi # craft-fonts was checked out next to the sources and synced into the VM with them. export CRAFT_FONTS_DIR="$PWD/craft-fonts" CRAFT_FONTS_REQUIRED=1 bash packaging/freebsd/package.sh - tar -tzf dist/release/lightcraft-*-freebsd-x86_64.tar.gz \ - | grep -E '/bin/lightcraft$|/bin/lightcraft-cli$|/share/applications/ai\.storyteller\.lightcraft\.desktop$|/share/doc/lightcraft/LICENSE-MIT$' + . packaging/env.sh + tar -tzf "dist/release/$BRAND_BINARY-"*-freebsd-x86_64.tar.gz \ + | grep -E "/bin/$BRAND_BINARY\$|/bin/$BRAND_CLI_BINARY\$|/share/applications/$BRAND_APP_ID\.desktop\$|/share/doc/$BRAND_BINARY/LICENSE\$" - uses: actions/upload-artifact@v4 with: name: release-freebsd-x86_64 @@ -327,8 +339,8 @@ jobs: needs: version runs-on: ubuntu-latest env: - LIGHTCRAFT_VERSION: ${{ needs.version.outputs.version }} - LIGHTCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }} + PACKAGE_VERSION: ${{ needs.version.outputs.version }} + BUILD_DATE: ${{ needs.version.outputs.date }} WASM_BINDGEN_VERSION: 0.2.129 steps: - uses: actions/checkout@v4 @@ -353,7 +365,7 @@ jobs: wasm-bindgen --version - name: Apply version override if: inputs.version != '' - run: cargo xtask version set "$LIGHTCRAFT_VERSION" + run: cargo xtask version set "$PACKAGE_VERSION" - name: Build and zip env: CRAFT_FONTS_DIR: ${{ github.workspace }}/craft-fonts @@ -391,7 +403,7 @@ jobs: working-directory: artifacts run: | tag="v$VERSION" - title="LightCraft v$VERSION" + title="${{ needs.version.outputs.display_name }} v$VERSION" pre=() if [ "$PRERELEASE" = true ]; then pre=(--prerelease); fi if draft="$(gh release view "$tag" --json isDraft --jq .isDraft 2>/dev/null)"; then diff --git a/.github/workflows/windows-arm64.yml b/.github/workflows/windows-arm64.yml index d6067b3f24..73a9b12324 100644 --- a/.github/workflows/windows-arm64.yml +++ b/.github/workflows/windows-arm64.yml @@ -53,7 +53,7 @@ jobs: run: ./packaging/windows/package.ps1 -Arch arm64 - uses: actions/upload-artifact@v4 with: - name: lightcraft-windows-arm64 + name: app-windows-arm64 path: dist/arm64/* if-no-files-found: error retention-days: 7 @@ -64,19 +64,24 @@ jobs: runs-on: windows-11-arm timeout-minutes: 30 steps: + # for brand.toml and packaging/windows/brand.ps1 (the product name lives only there) + - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: - name: lightcraft-windows-arm64 + name: app-windows-arm64 path: dist - name: Install the MSI, check it, run it, uninstall it shell: pwsh run: | $ErrorActionPreference = 'Stop' + . ./packaging/windows/brand.ps1 + $appExe = "$($Brand.binary).exe" + $cliExe = "$($Brand.cli_binary).exe" $msi = (Get-ChildItem dist/*.msi | Select-Object -First 1).FullName $p = Start-Process msiexec.exe -ArgumentList '/i', "`"$msi`"", '/qn', '/l*v', 'install.log' -Wait -PassThru if ($p.ExitCode -ne 0) { Get-Content install.log -Tail 60; throw "msiexec /i exited $($p.ExitCode)" } - $dir = Join-Path $env:ProgramFiles 'LightCraft' - foreach ($exe in 'lightcraft.exe', 'lightcraft-cli.exe') { + $dir = Join-Path $env:ProgramFiles $Brand.display_name + foreach ($exe in $appExe, $cliExe) { $path = Join-Path $dir $exe if (-not (Test-Path $path)) { throw "$exe not installed in $dir" } $bytes = [System.IO.File]::ReadAllBytes($path) @@ -85,11 +90,11 @@ jobs: Write-Output "ok $path (ARM64)" } # The installed CLI runs natively on ARM64. - $cli = Join-Path $dir 'lightcraft-cli.exe' + $cli = Join-Path $dir $cliExe $out = & $cli --version 2>&1 | Out-String - if ($LASTEXITCODE -ne 0) { Write-Output $out; throw "lightcraft-cli --version exited $LASTEXITCODE" } - Write-Output "ok lightcraft-cli --version: $($out.Trim())" + if ($LASTEXITCODE -ne 0) { Write-Output $out; throw "$cliExe --version exited $LASTEXITCODE" } + Write-Output "ok $cliExe --version: $($out.Trim())" $p = Start-Process msiexec.exe -ArgumentList '/x', "`"$msi`"", '/qn' -Wait -PassThru if ($p.ExitCode -ne 0) { throw "msiexec /x exited $($p.ExitCode)" } - if (Test-Path (Join-Path $dir 'lightcraft.exe')) { throw 'uninstall left lightcraft.exe behind' } + if (Test-Path (Join-Path $dir $appExe)) { throw "uninstall left $appExe behind" } Write-Output 'ok uninstalled' diff --git a/.gitignore b/.gitignore index 8c2047fe6b..87a4be29c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *~ -plan/ +# plan/ is committed; only private observation notes about the reference app stay local +/plan/observations/ /target /target-*/ /dist diff --git a/AGENTS.md b/AGENTS.md index 1e889b730d..8d73eba0c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,22 @@ -# LightCraft — instructions for agents +# Instructions for agents -LightCraft is a clean-room, open-source, pure-Rust photo library + non-destructive raw developer targeting Adobe Lightroom parity (and beyond). Native on macOS, Windows, Linux; web via WASM. Sibling of `../pdfcraft` (Acrobat), `../photocraft` (Photoshop), `../vectorcraft` (Illustrator) and `../filmcraft` (Premiere), with the same conventions. +The app is a clean-room, open-source, pure-Rust photo library + non-destructive raw developer targeting Adobe Lightroom parity (and beyond). Native on macOS, Windows, Linux; web via WASM. It is a fork of an upstream project (see `NOTICE`; merge procedure in `docs/upstream-merge.md`). + +## The name lives in `brand.toml` only +- The product name, binary names, app id, settings folder, env-var prefix, MCP server id, URL scheme and file + extensions are defined once, in [`brand.toml`](brand.toml), and reach code through the `dac-brand` crate. Never write + the product name (or a legacy upstream name) in code, UI strings, docs or tests: say "the app" in prose, use `{app}` + (display name), `{cli}` and `{env}` in i18n catalogs, and `dac_brand::…` constants in code. +- `cargo xtask brand check` (part of `cargo xtask ci`) fails if the name appears anywhere else. Allowed exceptions: + `brand.toml`, `[legacy]` handling, `NOTICE`, `LICENSE`, `assets/ATTRIBUTION.md`, `docs/upstream-merge.md`. +- Docs that genuinely need the name are written as `X.md.in` templates with `{{app}}`, `{{binary}}`, `{{cli_binary}}`, + `{{env_prefix}}`, `{{app_id}}`, `{{settings_dir}}`, rendered by `cargo xtask docs`; otherwise docs write ``, + ``, ``, ``, `` for the `brand.toml` values. +- Crates are `dac-*`; the packages with binaries are `dac-app` (desktop), `dac-cli` and `dac-web`. Inside `target/` the + binaries are always `app` and `app-cli`; `cargo xtask run`, `cargo xtask package` and `cargo xtask install` give them + the brand names. +- Environment variables are `_X`, where `PREFIX` is `env_prefix` from `brand.toml` (e.g. `_LOG`, + `_GPU`, `_PROFILE`); the legacy upstream prefix in `[legacy]` is still read. ## Start every session here 1. Read `plan/STATUS.md` (current milestone, next unchecked task, blockers). @@ -13,7 +29,7 @@ LightCraft is a clean-room, open-source, pure-Rust photo library + non-destructi 4. **Pick work** from [`docs/parity.md`](docs/parity.md) → *Top gaps* (ordered by user impact; the tracker has one row per feature, menu item and shortcut). When you land a feature, update its row(s) and the gap list in the same commit, and the *Where we stand* / *Where we're going* sections of `ROADMAP.md` when a listed gap closes; `cargo xtask parity` (part of `ci`) checks that every `cmd:`/`ctl:` id and path the tracker cites still exists, and `cargo xtask parity --write` refreshes its summary. 5. Follow the autonomous operation protocol (`plan/execution-plan.md` §7). Don't stop to ask unless §7 lists the decision as the user's. -`plan/` is gitignored (local-only). +`plan/observations/` (Adobe-observation notes) is gitignored (local-only). **Merging agent branches:** merge one branch, run `cargo xtask ci`, fix, commit — then the next. Two individually green branches can still break each other (e.g. a new struct field vs. a new constructor). @@ -23,7 +39,7 @@ branches can still break each other (e.g. a new struct field vs. a new construct and often so a crash loses minutes, not hours. ## Never crash (outranks feature work) -People trust LightCraft with their photo libraries and edits; a crash loses their work. A malformed raw/JPEG/XMP, a bad +People trust the app with their photo libraries and edits; a crash loses their work. A malformed raw/JPEG/XMP, a bad command, control or MCP argument, a corrupt catalog or settings file, or a full disk must produce an error the user (or agent) can act on, never a panic. Don't ship a feature by adding a panic path, and fix a crash before building on top of it. Full standard: `../craftrules/standards/never-crash.md` @@ -59,6 +75,19 @@ of it. Full standard: `../craftrules/standards/never-crash.md` - **Quality gates** before every commit: `cargo xtask ci` (fmt, clippy -D warnings, tests, layers, assets, wasm). - **Commits:** one task id per commit (`M2.3: local Laplacian highlights/shadows`). Only green states. End messages with the attribution line required by the environment. +## Clean-room sources (in addition to the non-negotiables) +- darktable and Ansel may be used **as running applications, manuals and prose design notes only**. +- Their source trees in `../darktable` and `../ansel` are **off-limits to agents**: never open, grep, read or copy + them. The same goes for GPL data tables wherever they appear: `noiseprofiles.json`, `wb_presets.json`, + `colormatrices.c`, basecurves. +- Camera matrices are **never harvested from Adobe-converted DNGs**: check the DNG's `Software` tag (Adobe DNG + Converter, Lightroom, Camera Raw) and reject those. Camera-native DNGs (written by the camera itself) are fine. +- Every PR that adds an algorithm has a **"Sources:"** line naming what it was built from: a paper, a prose spec, or + "own design". +- No GPL/LGPL/AGPL/MPL dependency may enter the build; `cargo deny` enforces the licence allow-list. +- Licence: the workspace is MIT (`LICENSE`, `license = "MIT"`); `crates/segment` and `crates/fetch` stay Apache-2.0 + only, with their own `LICENSE-APACHE`. Keep the upstream notices in `LICENSE` and `NOTICE`. + ## Assets: icons, images, fonts (ABSOLUTE RULE — never violate) - **Never use any iconography, image, artwork, font, sound or other asset from Adobe products** (no Lightroom/Creative Cloud icons, no screenshots, no presets/profiles/LUTs, no UI bitmaps — not even as a temporary placeholder or "reference copy"). Observing Adobe's UI to imitate *layout and behaviour* is allowed; copying or tracing its assets is not. - **This includes Adobe's open-licensed assets**: no Source Sans/Serif/Code or Source Han fonts, no Adobe Fonts, no @@ -68,12 +97,13 @@ of it. Full standard: `../craftrules/standards/never-crash.md` text, because nearly every OFL Chinese face derives from it. Use it unmodified under its OFL; this does not open the door to Source Han under Adobe's name or to any other Adobe asset. - Every asset in the repository must be one of: **our own original work** (e.g. icons drawn in code as vectors, procedurally generated demo photos), **public domain / CC0**, **Creative Commons** (CC-BY / CC-BY-SA with attribution honoured), **OFL** (fonts), or **permissive open-source** (MIT/Apache-2.0/BSD/ISC) — or contributed by a person who created the asset and licenses it openly. -- **Exception: `docs/brand/`.** The ArtCraft name, wordmark and logos there are ArtCraft Team trademarks, not open source and not covered by LightCraft's MIT OR Apache-2.0 licence (`LICENSE-MIT`, `LICENSE-APACHE`, `NOTICE`); their terms are in `docs/brand/LICENSE-brand.txt`. Use them only unmodified and never redraw, recolour or derive from them. +- The placeholder brand art is `brand/icon.svg` and `brand/logo.svg` (original work, MIT); every generated icon is + derived from `icon_svg` in `brand.toml`. - **Every asset must have an entry in `assets/ATTRIBUTION.md`** (path, title, author/creator, source URL or "original work", licence, date added, modifications) and its licence text when required (e.g. `assets/fonts/OFL-*.txt`). Add the entry in the same commit as the asset. Assets without an attribution entry must not be committed. - **Fonts live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts), never in this repo.** Don't commit - font files here (Inter, already in `assets/fonts/`, is the one exception); add new fonts to craft-fonts. LightCraft + font files here (Inter, already in `assets/fonts/`, is the one exception); add new fonts to craft-fonts. The app uses it as the optional build input `CRAFT_FONTS_DIR`: `git clone https://github.com/storytold/craft-fonts ../craft-fonts` - then `CRAFT_FONTS_DIR=../craft-fonts cargo run -p dac-app` (or any cargo/xtask command). `crates/engine/build.rs` + then `CRAFT_FONTS_DIR=../craft-fonts cargo xtask run` (or any cargo/xtask command). `crates/engine/build.rs` embeds the manifest's fonts as `dac_engine::CRAFT_FONTS` (wasm32: BIZ UDPGothic Regular only); `cargo xtask web` ships Noto Sans CJK SC Regular as a separate asset loaded by the UI before startup. The UI (`theme::font_definitions`) and the export watermark renderer use CJK faces (picked by script) as fallbacks after Inter. Unset, @@ -90,17 +120,17 @@ of it. Full standard: `../craftrules/standards/never-crash.md` - When in doubt about an asset's licence: don't use it. ## Running and looking at the app -- `cargo run --release -p dac-app -- --control 7980` opens the desktop app with the JSON-lines control server (see `docs/control-protocol.md`). +- `cargo xtask run -- --control 7980` (or `cargo run --release -p dac-app -- --control 7980`) opens the desktop app with the JSON-lines control server (see `docs/control-protocol.md`). - **Never send OS-level synthetic input** (osascript/System Events keystrokes or clicks, `cliclick`, accessibility - automation): it goes to whatever window is frontmost — the user's terminal or other apps. Drive LightCraft only + automation): it goes to whatever window is frontmost — the user's terminal or other apps. Drive the app only through its control channel (`ui.key`, `ui.pointer`, `ui.clickWidget`, `ui.menu.invoke`) or headless snapshots. - For UI work, **look at the result**: drive via the control channel and take `ui.screenshot`, compare with `plan/lightroom/screenshots/`. - **Unattended (display asleep/locked, CI, nightly runs): prefer headless snapshots** — no window needed: - `lightcraft-cli snapshot --demo --script tour.jsonl -o out.png --size 1600x1000` (control-protocol requests, + `cargo run --release -p dac-cli -- snapshot --demo --script tour.jsonl -o out.png --size 1600x1000` (control-protocol requests, one per line; see `docs/control-protocol.md` → Headless rendering). In a running app use `ui.screenshot {"path": …, "headless": true}`; windowed screenshots fall back to headless after 2 s. -- MCP: `lightcraft-cli mcp` (headless, `--demo` for the procedural library) or `lightcraft-cli mcp --connect` (drives - the running app). See `docs/mcp.md`. Quick non-UI checks: `lightcraft-cli render in.jpg -o out.jpg --set light.exposure=1`. +- MCP: `cargo run -p dac-cli -- mcp` (headless, `--demo` for the procedural library) or `… mcp --connect` (drives + the running app). See `docs/mcp.md`. Quick non-UI checks: `cargo run -p dac-cli -- render in.jpg -o out.jpg --set light.exposure=1`. - Export goes through `dac_engine::export` (one encoder for app, CLI, MCP and web); UI-only commands live in `crates/ui-egui/src/menus.rs`. - Shell gotcha: `mv`/`cp` are aliased interactive here — use `/bin/mv -f` / `/bin/cp -f`. @@ -115,15 +145,15 @@ of it. Full standard: `../craftrules/standards/never-crash.md` (`docs/showcase/run.py file.jsonl`), take `ui.screenshot`, and look at it. Check `ui.inspect` → `perf`. - **Benchmarks:** `cargo xtask bench` (24 MP raw from corpus; CPU and GPU columns) appends to `target/bench/history.jsonl` and flags CPU-time regressions > 20 % vs the previous run (`--strict` to fail). Run it before and after perf work. -- **Measure, don't guess**: `LIGHTCRAFT_PROFILE=1` prints per-stage pipeline timings to stderr; time CLI renders +- **Measure, don't guess**: `_PROFILE=1` (`PREFIX` = `env_prefix` from `brand.toml`) prints per-stage pipeline timings to stderr; time CLI renders with `/usr/bin/time`. Record numbers in `plan/STATUS.md` → Metrics. Budgets: slider update ≤ 16 ms (draft) / loupe ≤ 60 ms on ~2.5 MP; export ≤ 1 s per 24 MP JPEG. - Never commit media: test images are procedural (`dac-scenes`) or CC0 downloads in the gitignored `corpus/`. ## Map of the code `geom`, `color`, `raster`, `tiff` (L0) → `raw`, `codecs`, `meta`, `develop` (L1) → `pipeline` → `catalog` → `engine` -→ `ui-egui`, `mcp` (L5) → apps `lightcraft` (desktop), `lightcraft-cli` (render/commands/MCP). `scenes` generates demo -photos. `xtask` = tooling (`ci`, `layers`, `assets`, `parity`, `wasm`, `corpus`, `stats`). `flake.nix` + +→ `ui-egui`, `mcp` (L5) → apps `dac-app` (desktop, binary `app`), `dac-cli` (render/commands/MCP, binary `app-cli`), `dac-web`; `brand` (`dac-brand`) carries `brand.toml` into code. `scenes` generates demo +photos. `xtask` = tooling (`ci`, `layers`, `assets`, `parity`, `wasm`, `corpus`, `stats`, `brand check`, `docs`, `run`, `package`, `install`). `flake.nix` + `nix/package.nix` = the Nix package (`nix build` builds both binaries with the craft-fonts input, installs the desktop file/icons/AppStream metadata and runs `cargo test --workspace`; `nix develop` = dev shell). Community-maintained and not in CI: it may lag behind the workspace; see README → Quick start. diff --git a/CLAUDE.md b/CLAUDE.md index 7e678f38b4..39baec4812 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,22 @@ -# LightCraft — instructions for agents +# Instructions for agents -LightCraft is a clean-room, open-source, pure-Rust photo library + non-destructive raw developer targeting Adobe Lightroom parity (and beyond). Native on macOS, Windows, Linux; web via WASM. Sibling of `../pdfcraft` (Acrobat), `../photocraft` (Photoshop), `../vectorcraft` (Illustrator) and `../filmcraft` (Premiere), with the same conventions. +The app is a clean-room, open-source, pure-Rust photo library + non-destructive raw developer targeting Adobe Lightroom parity (and beyond). Native on macOS, Windows, Linux; web via WASM. It is a fork of an upstream project (see `NOTICE`; merge procedure in `docs/upstream-merge.md`). + +## The name lives in `brand.toml` only +- The product name, binary names, app id, settings folder, env-var prefix, MCP server id, URL scheme and file + extensions are defined once, in [`brand.toml`](brand.toml), and reach code through the `dac-brand` crate. Never write + the product name (or a legacy upstream name) in code, UI strings, docs or tests: say "the app" in prose, use `{app}` + (display name), `{cli}` and `{env}` in i18n catalogs, and `dac_brand::…` constants in code. +- `cargo xtask brand check` (part of `cargo xtask ci`) fails if the name appears anywhere else. Allowed exceptions: + `brand.toml`, `[legacy]` handling, `NOTICE`, `LICENSE`, `assets/ATTRIBUTION.md`, `docs/upstream-merge.md`. +- Docs that genuinely need the name are written as `X.md.in` templates with `{{app}}`, `{{binary}}`, `{{cli_binary}}`, + `{{env_prefix}}`, `{{app_id}}`, `{{settings_dir}}`, rendered by `cargo xtask docs`; otherwise docs write ``, + ``, ``, ``, `` for the `brand.toml` values. +- Crates are `dac-*`; the packages with binaries are `dac-app` (desktop), `dac-cli` and `dac-web`. Inside `target/` the + binaries are always `app` and `app-cli`; `cargo xtask run`, `cargo xtask package` and `cargo xtask install` give them + the brand names. +- Environment variables are `_X`, where `PREFIX` is `env_prefix` from `brand.toml` (e.g. `_LOG`, + `_GPU`, `_PROFILE`); the legacy upstream prefix in `[legacy]` is still read. ## Start every session here 1. Read `plan/STATUS.md` (current milestone, next unchecked task, blockers). @@ -13,7 +29,7 @@ LightCraft is a clean-room, open-source, pure-Rust photo library + non-destructi 4. **Pick work** from [`docs/parity.md`](docs/parity.md) → *Top gaps* (ordered by user impact; the tracker has one row per feature, menu item and shortcut). When you land a feature, update its row(s) and the gap list in the same commit, and the *Where we stand* / *Where we're going* sections of `ROADMAP.md` when a listed gap closes; `cargo xtask parity` (part of `ci`) checks that every `cmd:`/`ctl:` id and path the tracker cites still exists, and `cargo xtask parity --write` refreshes its summary. 5. Follow the autonomous operation protocol (`plan/execution-plan.md` §7). Don't stop to ask unless §7 lists the decision as the user's. -`plan/` is gitignored (local-only). +`plan/observations/` (Adobe-observation notes) is gitignored (local-only). **Merging agent branches:** merge one branch, run `cargo xtask ci`, fix, commit — then the next. Two individually green branches can still break each other (e.g. a new struct field vs. a new constructor). @@ -23,7 +39,7 @@ branches can still break each other (e.g. a new struct field vs. a new construct and often so a crash loses minutes, not hours. ## Never crash (outranks feature work) -People trust LightCraft with their photo libraries and edits; a crash loses their work. A malformed raw/JPEG/XMP, a bad +People trust the app with their photo libraries and edits; a crash loses their work. A malformed raw/JPEG/XMP, a bad command, control or MCP argument, a corrupt catalog or settings file, or a full disk must produce an error the user (or agent) can act on, never a panic. Don't ship a feature by adding a panic path, and fix a crash before building on top of it. Full standard: `../craftrules/standards/never-crash.md` @@ -59,6 +75,19 @@ of it. Full standard: `../craftrules/standards/never-crash.md` - **Quality gates** before every commit: `cargo xtask ci` (fmt, clippy -D warnings, tests, layers, assets, wasm). - **Commits:** one task id per commit (`M2.3: local Laplacian highlights/shadows`). Only green states. End messages with the attribution line required by the environment. +## Clean-room sources (in addition to the non-negotiables) +- darktable and Ansel may be used **as running applications, manuals and prose design notes only**. +- Their source trees in `../darktable` and `../ansel` are **off-limits to agents**: never open, grep, read or copy + them. The same goes for GPL data tables wherever they appear: `noiseprofiles.json`, `wb_presets.json`, + `colormatrices.c`, basecurves. +- Camera matrices are **never harvested from Adobe-converted DNGs**: check the DNG's `Software` tag (Adobe DNG + Converter, Lightroom, Camera Raw) and reject those. Camera-native DNGs (written by the camera itself) are fine. +- Every PR that adds an algorithm has a **"Sources:"** line naming what it was built from: a paper, a prose spec, or + "own design". +- No GPL/LGPL/AGPL/MPL dependency may enter the build; `cargo deny` enforces the licence allow-list. +- Licence: the workspace is MIT (`LICENSE`, `license = "MIT"`); `crates/segment` and `crates/fetch` stay Apache-2.0 + only, with their own `LICENSE-APACHE`. Keep the upstream notices in `LICENSE` and `NOTICE`. + ## Assets: icons, images, fonts (ABSOLUTE RULE — never violate) - **Never use any iconography, image, artwork, font, sound or other asset from Adobe products** (no Lightroom/Creative Cloud icons, no screenshots, no presets/profiles/LUTs, no UI bitmaps — not even as a temporary placeholder or "reference copy"). Observing Adobe's UI to imitate *layout and behaviour* is allowed; copying or tracing its assets is not. - **This includes Adobe's open-licensed assets**: no Source Sans/Serif/Code or Source Han fonts, no Adobe Fonts, no @@ -68,12 +97,13 @@ of it. Full standard: `../craftrules/standards/never-crash.md` text, because nearly every OFL Chinese face derives from it. Use it unmodified under its OFL; this does not open the door to Source Han under Adobe's name or to any other Adobe asset. - Every asset in the repository must be one of: **our own original work** (e.g. icons drawn in code as vectors, procedurally generated demo photos), **public domain / CC0**, **Creative Commons** (CC-BY / CC-BY-SA with attribution honoured), **OFL** (fonts), or **permissive open-source** (MIT/Apache-2.0/BSD/ISC) — or contributed by a person who created the asset and licenses it openly. -- **Exception: `docs/brand/`.** The ArtCraft name, wordmark and logos there are ArtCraft Team trademarks, not open source and not covered by LightCraft's MIT OR Apache-2.0 licence (`LICENSE-MIT`, `LICENSE-APACHE`, `NOTICE`); their terms are in `docs/brand/LICENSE-brand.txt`. Use them only unmodified and never redraw, recolour or derive from them. +- The placeholder brand art is `brand/icon.svg` and `brand/logo.svg` (original work, MIT); every generated icon is + derived from `icon_svg` in `brand.toml`. - **Every asset must have an entry in `assets/ATTRIBUTION.md`** (path, title, author/creator, source URL or "original work", licence, date added, modifications) and its licence text when required (e.g. `assets/fonts/OFL-*.txt`). Add the entry in the same commit as the asset. Assets without an attribution entry must not be committed. - **Fonts live in [storytold/craft-fonts](https://github.com/storytold/craft-fonts), never in this repo.** Don't commit - font files here (Inter, already in `assets/fonts/`, is the one exception); add new fonts to craft-fonts. LightCraft + font files here (Inter, already in `assets/fonts/`, is the one exception); add new fonts to craft-fonts. The app uses it as the optional build input `CRAFT_FONTS_DIR`: `git clone https://github.com/storytold/craft-fonts ../craft-fonts` - then `CRAFT_FONTS_DIR=../craft-fonts cargo run -p dac-app` (or any cargo/xtask command). `crates/engine/build.rs` + then `CRAFT_FONTS_DIR=../craft-fonts cargo xtask run` (or any cargo/xtask command). `crates/engine/build.rs` embeds the manifest's fonts as `dac_engine::CRAFT_FONTS` (wasm32: BIZ UDPGothic Regular only); `cargo xtask web` ships Noto Sans CJK SC Regular as a separate asset loaded by the UI before startup. The UI (`theme::font_definitions`) and the export watermark renderer use CJK faces (picked by script) as fallbacks after Inter. Unset, @@ -90,17 +120,17 @@ of it. Full standard: `../craftrules/standards/never-crash.md` - When in doubt about an asset's licence: don't use it. ## Running and looking at the app -- `cargo run --release -p dac-app -- --control 7980` opens the desktop app with the JSON-lines control server (see `docs/control-protocol.md`). +- `cargo xtask run -- --control 7980` (or `cargo run --release -p dac-app -- --control 7980`) opens the desktop app with the JSON-lines control server (see `docs/control-protocol.md`). - **Never send OS-level synthetic input** (osascript/System Events keystrokes or clicks, `cliclick`, accessibility - automation): it goes to whatever window is frontmost — the user's terminal or other apps. Drive LightCraft only + automation): it goes to whatever window is frontmost — the user's terminal or other apps. Drive the app only through its control channel (`ui.key`, `ui.pointer`, `ui.clickWidget`, `ui.menu.invoke`) or headless snapshots. - For UI work, **look at the result**: drive via the control channel and take `ui.screenshot`, compare with `plan/lightroom/screenshots/`. - **Unattended (display asleep/locked, CI, nightly runs): prefer headless snapshots** — no window needed: - `lightcraft-cli snapshot --demo --script tour.jsonl -o out.png --size 1600x1000` (control-protocol requests, + `cargo run --release -p dac-cli -- snapshot --demo --script tour.jsonl -o out.png --size 1600x1000` (control-protocol requests, one per line; see `docs/control-protocol.md` → Headless rendering). In a running app use `ui.screenshot {"path": …, "headless": true}`; windowed screenshots fall back to headless after 2 s. -- MCP: `lightcraft-cli mcp` (headless, `--demo` for the procedural library) or `lightcraft-cli mcp --connect` (drives - the running app). See `docs/mcp.md`. Quick non-UI checks: `lightcraft-cli render in.jpg -o out.jpg --set light.exposure=1`. +- MCP: `cargo run -p dac-cli -- mcp` (headless, `--demo` for the procedural library) or `… mcp --connect` (drives + the running app). See `docs/mcp.md`. Quick non-UI checks: `cargo run -p dac-cli -- render in.jpg -o out.jpg --set light.exposure=1`. - Export goes through `dac_engine::export` (one encoder for app, CLI, MCP and web); UI-only commands live in `crates/ui-egui/src/menus.rs`. - Shell gotcha: `mv`/`cp` are aliased interactive here — use `/bin/mv -f` / `/bin/cp -f`. @@ -115,15 +145,15 @@ of it. Full standard: `../craftrules/standards/never-crash.md` (`docs/showcase/run.py file.jsonl`), take `ui.screenshot`, and look at it. Check `ui.inspect` → `perf`. - **Benchmarks:** `cargo xtask bench` (24 MP raw from corpus; CPU and GPU columns) appends to `target/bench/history.jsonl` and flags CPU-time regressions > 20 % vs the previous run (`--strict` to fail). Run it before and after perf work. -- **Measure, don't guess**: `LIGHTCRAFT_PROFILE=1` prints per-stage pipeline timings to stderr; time CLI renders +- **Measure, don't guess**: `_PROFILE=1` (`PREFIX` = `env_prefix` from `brand.toml`) prints per-stage pipeline timings to stderr; time CLI renders with `/usr/bin/time`. Record numbers in `plan/STATUS.md` → Metrics. Budgets: slider update ≤ 16 ms (draft) / loupe ≤ 60 ms on ~2.5 MP; export ≤ 1 s per 24 MP JPEG. - Never commit media: test images are procedural (`dac-scenes`) or CC0 downloads in the gitignored `corpus/`. ## Map of the code `geom`, `color`, `raster`, `tiff` (L0) → `raw`, `codecs`, `meta`, `develop` (L1) → `pipeline` → `catalog` → `engine` -→ `ui-egui`, `mcp` (L5) → apps `lightcraft` (desktop), `lightcraft-cli` (render/commands/MCP). `scenes` generates demo -photos. `xtask` = tooling (`ci`, `layers`, `assets`, `parity`, `wasm`, `corpus`, `stats`). `flake.nix` + +→ `ui-egui`, `mcp` (L5) → apps `dac-app` (desktop, binary `app`), `dac-cli` (render/commands/MCP, binary `app-cli`), `dac-web`; `brand` (`dac-brand`) carries `brand.toml` into code. `scenes` generates demo +photos. `xtask` = tooling (`ci`, `layers`, `assets`, `parity`, `wasm`, `corpus`, `stats`, `brand check`, `docs`, `run`, `package`, `install`). `flake.nix` + `nix/package.nix` = the Nix package (`nix build` builds both binaries with the craft-fonts input, installs the desktop file/icons/AppStream metadata and runs `cargo test --workspace`; `nix develop` = dev shell). Community-maintained and not in CI: it may lag behind the workspace; see README → Quick start. diff --git a/Cargo.lock b/Cargo.lock index a419eb4a2b..db69000f24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1179,6 +1179,7 @@ dependencies = [ name = "dac-app" version = "0.4.0" dependencies = [ + "dac-brand", "dac-codecs", "dac-engine", "dac-raster", @@ -1202,6 +1203,7 @@ name = "dac-catalog" version = "0.4.0" dependencies = [ "crc32fast", + "dac-brand", "dac-develop", "dac-meta", "log", @@ -1216,6 +1218,7 @@ dependencies = [ name = "dac-cli" version = "0.4.0" dependencies = [ + "dac-brand", "dac-codecs", "dac-engine", "dac-mcp", @@ -1224,6 +1227,7 @@ dependencies = [ "dac-sysmem", "dac-ui-egui", "dhat", + "log", "serde_json", ] @@ -1232,6 +1236,7 @@ name = "dac-codecs" version = "0.4.0" dependencies = [ "bytemuck", + "dac-brand", "dac-color", "dac-geom", "dac-heif", @@ -1257,6 +1262,7 @@ dependencies = [ name = "dac-color" version = "0.4.0" dependencies = [ + "dac-brand", "dac-geom", "proptest", "serde", @@ -1266,6 +1272,7 @@ dependencies = [ name = "dac-denoise" version = "0.4.0" dependencies = [ + "dac-brand", "dac-denoise-core", "dac-raster", "faer-core", @@ -1283,6 +1290,7 @@ dependencies = [ name = "dac-denoise-core" version = "0.4.0" dependencies = [ + "dac-brand", "dac-raster", "miniz_oxide 0.8.9", "proptest", @@ -1298,6 +1306,7 @@ dependencies = [ name = "dac-develop" version = "0.4.0" dependencies = [ + "dac-brand", "dac-color", "dac-geom", "miniz_oxide 0.8.9", @@ -1311,6 +1320,7 @@ name = "dac-engine" version = "0.4.0" dependencies = [ "ab_glyph", + "dac-brand", "dac-catalog", "dac-codecs", "dac-color", @@ -1346,6 +1356,7 @@ dependencies = [ name = "dac-faces" version = "0.4.0" dependencies = [ + "dac-brand", "matrixmultiply", "ndarray", "proptest", @@ -1360,6 +1371,7 @@ dependencies = [ name = "dac-fetch" version = "0.4.0" dependencies = [ + "dac-brand", "log", "rustls", "rustls-rustcrypto", @@ -1371,6 +1383,7 @@ dependencies = [ name = "dac-geom" version = "0.4.0" dependencies = [ + "dac-brand", "proptest", "serde", ] @@ -1380,6 +1393,7 @@ name = "dac-gpu" version = "0.4.0" dependencies = [ "bytemuck", + "dac-brand", "dac-color", "dac-denoise", "dac-develop", @@ -1396,6 +1410,7 @@ dependencies = [ name = "dac-heif" version = "0.4.0" dependencies = [ + "dac-brand", "heic-rs", ] @@ -1403,6 +1418,7 @@ dependencies = [ name = "dac-mcp" version = "0.4.0" dependencies = [ + "dac-brand", "dac-codecs", "dac-engine", "dac-raster", @@ -1414,6 +1430,7 @@ dependencies = [ name = "dac-merge" version = "0.4.0" dependencies = [ + "dac-brand", "dac-codecs", "dac-color", "dac-geom", @@ -1430,6 +1447,7 @@ dependencies = [ name = "dac-meta" version = "0.4.0" dependencies = [ + "dac-brand", "dac-geom", "dac-tiff", "proptest", @@ -1442,6 +1460,7 @@ dependencies = [ name = "dac-pipeline" version = "0.4.0" dependencies = [ + "dac-brand", "dac-color", "dac-develop", "dac-geom", @@ -1459,6 +1478,7 @@ dependencies = [ name = "dac-preview" version = "0.4.0" dependencies = [ + "dac-brand", "dac-raster", "jpeg-encoder", "log", @@ -1471,6 +1491,7 @@ dependencies = [ name = "dac-raster" version = "0.4.0" dependencies = [ + "dac-brand", "dac-color", "dac-geom", "libc", @@ -1483,6 +1504,7 @@ dependencies = [ name = "dac-raw" version = "0.4.0" dependencies = [ + "dac-brand", "dac-color", "dac-geom", "dac-meta", @@ -1505,6 +1527,7 @@ dependencies = [ name = "dac-scenes" version = "0.4.0" dependencies = [ + "dac-brand", "dac-color", "dac-raster", "image", @@ -1518,6 +1541,7 @@ version = "0.4.0" dependencies = [ "candle-core", "candle-nn", + "dac-brand", "dac-fetch", "log", "serde", @@ -1528,11 +1552,15 @@ dependencies = [ [[package]] name = "dac-sysmem" version = "0.4.0" +dependencies = [ + "dac-brand", +] [[package]] name = "dac-tiff" version = "0.4.0" dependencies = [ + "dac-brand", "proptest", "serde", "thiserror 2.0.21", @@ -1542,6 +1570,7 @@ dependencies = [ name = "dac-ui-egui" version = "0.4.0" dependencies = [ + "dac-brand", "dac-catalog", "dac-codecs", "dac-color", @@ -1567,6 +1596,7 @@ name = "dac-web" version = "0.4.0" dependencies = [ "crc32fast", + "dac-brand", "dac-codecs", "dac-engine", "dac-preview", diff --git a/Cargo.toml b/Cargo.toml index 7b84593f0f..9f6bf52342 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,9 +5,9 @@ members = ["crates/*", "apps/*", "xtask"] [workspace.package] version = "0.4.0" edition = "2024" -license = "MIT OR Apache-2.0" +license = "MIT" rust-version = "1.90" -repository = "https://github.com/storytold/lightcraft" +repository = "https://example.invalid/repo" [workspace.dependencies] # internal @@ -49,7 +49,7 @@ bytemuck = { version = "1", features = ["derive"] } crc32fast = "1" siphasher = "1" libc = "0.2" # dev-only: process CPU time in benches -dhat = "0.3" # opt-in heap profiling (lightcraft-cli --features dhat-heap); never in default builds +dhat = "0.3" # opt-in heap profiling (dac-cli --features dhat-heap); never in default builds # formats quick-xml = "0.38" diff --git a/LICENSE-MIT b/LICENSE similarity index 89% rename from LICENSE-MIT rename to LICENSE index d050b29c63..03125091b9 100644 --- a/LICENSE-MIT +++ b/LICENSE @@ -1,6 +1,8 @@ MIT License -Copyright (c) 2026 ArtCraft Team and the LightCraft contributors +Copyright (c) the LightCraft contributors +Copyright (c) the PhotoCraft contributors +Copyright (c) the project contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/NOTICE b/NOTICE index b4115d0b6b..13fbf7d587 100644 --- a/NOTICE +++ b/NOTICE @@ -1,11 +1,18 @@ -LightCraft -Copyright (c) 2026 ArtCraft Team and the LightCraft contributors. -Licensed under the MIT License or the Apache License, Version 2.0, at your option -(LICENSE-MIT, LICENSE-APACHE). +This software is licensed under the MIT License (LICENSE), except crates/segment and +crates/fetch, which are licensed under the Apache License 2.0 only (see LICENSE-APACHE in each +of those crate folders). -The ArtCraft name, wordmark and logos in docs/brand/ are trademarks of the ArtCraft Team. They are -not open source and are not covered by the license above; their terms are in -docs/brand/LICENSE-brand.txt. +Upstream attribution + +This project is a fork of LightCraft (https://github.com/storytold/lightcraft), +Copyright (c) 2026 ArtCraft Team and the LightCraft contributors, licensed under the MIT +License or the Apache License, Version 2.0. It also includes code from PhotoCraft, +Copyright (c) the PhotoCraft contributors. Code inherited from these projects is used here +under the MIT License; the upstream copyright notices are kept in LICENSE and in this file. + +The ArtCraft name, wordmark and logos are trademarks of the ArtCraft Team and are not part of +this project. The upstream LightCraft app icon in assets/app-icon/ is covered by its own +licence file (assets/app-icon/LICENSE.txt). Third-party material @@ -20,14 +27,15 @@ crates/segment (dac-segment) ports the SAM 3 model code of Hugging Face Transfor Copyright The HuggingFace Team and Meta Platforms, Inc., licensed under the Apache License 2.0. The port was modified by the LightCraft contributors (2026): translated from Python/PyTorch to Rust on candle and restructured; each ported file says so. Because of this, crates/segment is -licensed under the Apache License 2.0 only (LICENSE-APACHE), not under the MIT option. +licensed under the Apache License 2.0 only (crates/segment/LICENSE-APACHE), not under MIT. +crates/fetch is likewise licensed under the Apache License 2.0 only (crates/fetch/LICENSE-APACHE). -The SAM 3 weights are not part of LightCraft and are never distributed with it. A user downloads +The SAM 3 weights are not part of this software and are never distributed with it. A user downloads the facebook/sam3 checkpoint only when they choose to (in the app, or by hand), under Meta's SAM License (https://github.com/facebookresearch/sam3/blob/main/LICENSE), a separate, non-OSI licence. See docs/ai-masks.md. -AI denoise weights are not part of LightCraft and are never distributed with it. +AI denoise weights are not part of this software and are never distributed with it. The default build offers user-supplied models only. The optional rawnind-model feature offers a separately downloaded RawNIND UtNet2 Bayer checkpoint under GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html), after the user accepts its terms. diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000000..a76ab185b6 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,746 @@ +# Lightroom Classic clone in pure Rust: feature list, inputs and plan to completion + +*Written 2026-10-10 from a survey of the five folders next to this one: `darktable`, `ansel`, `lightcraft`, +`photocraft` and this empty `nonameyet`.* + +**Detailed phase plans:** [Phase 0](PLAN_phase_0.md) · [Phase 1](PLAN_phase_1.md) · [Phase 2](PLAN_phase_2.md) · +[Phase 3](PLAN_phase_3.md) · [Phase 4](PLAN_phase_4.md). Phases 5–6 are described in §6 below. + +**Product name:** not chosen yet, and never hard-coded. It lives in one file, `brand.toml`, and can be changed at any +time; see [Phase 0 §0.2](PLAN_phase_0.md#02-the-name-lives-in-one-config-file-brandtoml). "NoNameYet" below is a +placeholder. + +--- + +## 0. TL;DR + +1. **Fork LightCraft; don't start from zero.** + - LightCraft is about 174k lines of pure Rust and compiles cleanly (`cargo check --workspace` passes). + - It already covers about 80% of Lightroom features by row count (P0 core features 98%). Its own honest estimate + is 60–70% of a real day-to-day replacement, and about 45% for a *Lightroom Classic* power user. + - Rebuilding that from scratch would cost hundreds of agent-hours and gain nothing. + - "From scratch in Rust" still holds: every line of the product stays Rust we wrote. No C/C++ is linked and no + foreign code is pasted in. +2. **LightCraft is built on the *cloud* Lightroom model.** It has a single window with view modes and a right-hand + panel. Classic is a **module** application (Library | Develop | Map | Book | Slideshow | Print | Web) with a + **catalog** and Classic panels and keys. The fork's first real job is the Classic shell and a catalog that scales. +3. **What remains is mostly quality, data and output modules, not buttons.** In order of pain: + - camera colour calibration + - lens-profile database + - CR3 and compressed ORF/SRW raws + - full-resolution zoom + - the output modules: Map, Print, Book, Slideshow, Web, publish services and tethering + - AI masks and denoise + - HDR and video +4. **PhotoCraft donates finished parts.** These are a real Remove tool (PatchMatch content-aware fill), a full ICC + colour-management engine (printer soft proofing), text shaping (Print, Book, identity plate), pressure-sensitive + brushes, a layered PSD writer ("Edit in…" round trips), a WASM plugin sandbox and action recording. +5. **Licence: MIT (decided).** darktable and Ansel are GPL-3.0+, so they serve as **behaviour and design references + only**: run the apps, read their manuals and prose design notes, never their source code or GPL data tables + (section 4). Camera colour, noise and white-balance data are measured by us (Phase 2). + +--- + +## 1. What is in this folder + +| Project | Language / licence | Size | What it is | Role in this plan | +|---|---|---|---|---| +| **lightcraft** | Rust, MIT OR Apache-2.0 | ~174k LoC, 1,117 commits, active (last commit 2026-10-09) | Clean-room Lightroom (cloud-style) clone: egui UI, wgpu compute pipeline, command engine, MCP, WASM build | **Fork base** | +| **photocraft** | Rust, MIT OR Apache-2.0 | ~365k LoC, ~1,049 commits | Clean-room Photoshop clone, same conventions as LightCraft (no shared code; crates were copied and have diverged) | **Donor of crates** | +| **darktable** | C/C++, GPL-3.0+ | 96 IOP modules | The most complete open-source raw developer: lighttable, darkroom, map, print, slideshow, tethering, Lua, ONNX AI, MCP | **Behaviour and feature reference** (app and manual only, no source: §4) | +| **ansel** | C, GPL-3.0+ | darktable fork from May 2022 | darktable re-engineered: incremental pipeline cache, simplified UI, LensSerious lens DB, dependency-free ML raw denoise | **Design reference** (prose notes in `ansel/doc/`, no source) | + +--- + +## 2. Complete Lightroom Classic feature list + +Status column `LC`: LightCraft today. ✅ works · 🟡 partial · ⬜ missing · ? not verified. +"Src" is where the missing piece can come from: **PC** = PhotoCraft, **DT** = darktable, **AN** = Ansel (both as running app, manual or prose notes only, never source: §4), **new** = write it. + +### 2.1 Application shell and cross-cutting features + +| Feature | LC | Src / notes | +|---|---|---| +| Module picker (Library, Develop, Map, Book, Slideshow, Print, Web), with configurable hidden modules | ⬜ | new: LightCraft has no module system | +| Identity plate (text or graphic, custom fonts) and activity centre/progress | 🟡 | PC `text` for identity plate; LightCraft has an Activity panel | +| Panel system: left/right/top/bottom panels, auto hide/show, solo mode, Tab/⇧Tab/F5–F8, T toolbar | ⬜ | new (KEYC-PANELS) | +| Screen modes (normal, full screen, full screen with menu bar), lights out (dim/off) | 🟡 | new (KEYC-VIEWS) | +| Secondary display window: Grid, Loupe (normal/live/locked), Compare, Survey, Slideshow | 🟡 | second window exists; keys and locked/live modes missing | +| Filmstrip with source indicator, filters, thumbnail badges | ✅ | | +| Classic keyboard map (all module keys, Ctrl+Alt+1..7 module switches) | 🟡 | new: LightCraft deliberately remaps some keys; add a "Classic keymap" layer | +| Keyboard shortcut editor | 🟡 | settings exist; editor is a M16 item | +| Preferences: General, Presets, External Editing, File Handling, Interface, Performance, Display, Network | 🟡 | partial in LC | +| Catalog settings: backup schedule, preview size and quality, auto-discard of 1:1 previews, XMP auto-write, address lookup, face detection | 🟡 | new pieces | +| Undo/redo across modules, history | ✅ | engine op log | +| Plugin manager and SDK (Lua in Lightroom Classic) | ⬜ | PC `plugins` (WASM sandbox); see §6.5 | +| Help, keyboard cheat-sheet overlay per module (⌘/), What's new | 🟡 | | +| Localisation, accessibility | 🟡 | 8 languages in LC | + +### 2.2 Catalog + +| Feature | LC | Src / notes | +|---|---|---| +| Single-file catalog of hundreds of thousands of photos, crash safe | 🟡 | LC op-log plus snapshot works to about 85k photos; the whole catalog sits in RAM. Needs an on-disk indexed store for over 500k (§6.2) | +| Multiple catalogs: open, create, open recent, choose at startup | ? | | +| Backup on exit with integrity test and optimise | ⬜ | new | +| Export as Catalog (subset, with or without negatives and previews) / Import from another catalog (merge, conflict policy) | ⬜ | new; LC already has a `.lrcat` read-only importer | +| Upgrade/migrate from a Lightroom Classic `.lrcat` (ratings, keywords, collections, develop settings, history) | 🟡 | LC has it (pure-Rust SQLite reader); history replay and Adobe-profile mapping are incomplete. mapping comes from published `crs:` descriptions and our own measurements (Phase 4.5) | +| Previews: minimal, embedded and sidecar, standard, 1:1; Smart Previews (lossy DNG) for offline editing | 🟡 | smart previews exist in LC | +| Missing file and folder detection, relink, "Find missing photos" | 🟡 | relink exists for the catalog import | +| Metadata ↔ XMP sync, conflict badges ("metadata changed on disk"), read/save metadata from/to file | 🟡 | XMP read/write exists; conflict UI missing | + +### 2.3 Import + +| Feature | LC | Src / notes | +|---|---|---| +| Import dialog: source panel (devices, folders), Copy as DNG / Copy / Move / Add | ✅ | | +| Grid with checkboxes, "new photos" / destination-folder views, suspected duplicates greyed out | ✅ | | +| File handling: build previews, smart previews, don't import duplicates, second copy (backup) to, add to collection | 🟡 | verify "make a second copy" | +| File renaming templates (template editor with tokens) | ✅ | | +| Apply during import: develop preset, metadata preset, keywords | ✅ | | +| Destination: into subfolder, organise by date (formats) | ✅ | | +| Import presets | ? | | +| Auto Import (watched folder) | ✅ | | +| Tethered capture: camera controls bar, shot naming, session, develop preset on capture, live view | ⬜ | new pure-Rust PTP/USB (`nusb`); AN's "studio capture" folder watch is a cheap first step | +| Formats: all raws (CR3, compressed ORF/SRW and the long tail), DNG, JPEG, TIFF, PSD, PNG, HEIC/HEIF, AVIF, JXL, video files | 🟡 | see §2.6 Raw | + +### 2.4 Library module + +| Feature | LC | Src / notes | +|---|---|---| +| Views: Grid (compact/expanded cells, cell styles, badges), Loupe (info overlays 1/2), Compare (select/candidate, linked zoom), Survey, People | 🟡 | People view lacks cluster separators | +| Navigator panel with zoom levels (Fit/Fill/1:1/custom) | ? | | +| Catalog panel: All Photographs, Quick Collection, Previous Import, Missing photos | 🟡 | Quick Collection ⬜ | +| Folders panel: volumes with free space, hierarchy, show parent, add/move/rename/remove folders, synchronise folder, update location, show in Finder | 🟡 | rename/move pending | +| Collections: collection, smart collection (full rule editor, nested AND/OR), collection set, target collection (B key), sync with mobile (out of scope) | 🟡 | smart albums ✅; target collection and sets need checking | +| Publish Services panel | ⬜ | §2.12 | +| Library Filter bar: Text / Attribute / Metadata (columns: date, camera, lens, keyword, label, etc.) / None, filter presets, lock | ✅ | KEYC filter-bar keys partial | +| Flags (P/X/U, ` to toggle), auto-advance, star ratings, colour labels and label sets, `[`/`]` rating up/down | 🟡 | `[`/`]` and flag cycling missing | +| Stacking: group, unstack, collapse/expand, auto-stack by capture time, move to top of stack | ✅ | | +| Virtual copies, set copy as master | ✅ | | +| Quick Develop panel (relative ± buttons, presets, crop ratio, treatment) | ? | check; Classic-specific | +| Keywording panel: keyword tags, suggestions, keyword sets (Ctrl+Alt+0–9) | 🟡 | keyword sets ⬜ | +| Keyword List: hierarchy, synonyms, export flags, import/export keyword lists, filter by keyword | 🟡 | | +| Painter tool (spray keywords, labels, flags, ratings, metadata, settings, rotation, target collection) | ⬜ | | +| Metadata panel: default, EXIF, IPTC, IPTC Extension, Location, Large Caption, custom; metadata presets; edit many; copy/paste metadata | 🟡 | metadata copy/paste ⬜ | +| Comments panel (from shared collections) | ⬜ | low value without cloud; can drop | +| Edit capture time (shift, set, use file date), batch | ? | | +| Convert to DNG, Find previous process version, Update DNG previews | 🟡 | DNG export exists | +| Face detection and People view (named, unnamed, cluster, confirm) | 🟡 | LC faces MVP | +| Show in Explorer/Finder, Edit In external editor, Open as Layers / Smart Object (Photoshop round trip) | 🟡 | external editor ✅; PC `psd` writer for layered round trip | +| Slideshow (impromptu, ⌘↵) | ✅ | basic | + +### 2.5 Develop module + +| Feature | LC | Src / notes | +|---|---|---| +| Left panel: Navigator, Presets (groups, favourites, amount), Snapshots, History (named steps, clear), Collections | ✅ | snapshots and versions exist | +| Toolbar: Before/After (left-right, top-bottom, split), loupe, grid overlays, soft proofing toggle | ✅ | | +| Histogram with clipping indicators (J), RGB readout, interactive drag on histogram | 🟡 | KEY-HISTOGRAM partial | +| Tool strip: Crop and Straighten (aspect lock, angle, auto, constrain), Remove/Spot Removal (content-aware, heal, clone; visualize spots), Red Eye/Pet Eye, Masking | 🟡 | content-aware is heal from an auto source: port PC `algo/inpaint.rs` (PatchMatch) and `content_aware.rs` | +| Basic: treatment (colour/B&W), profile browser, WB (as shot, auto, presets, eyedropper, temp/tint), exposure, contrast, highlights, shadows, whites, blacks, texture, clarity, dehaze, vibrance, saturation, Auto | ✅ | tone tuned by eye; fidelity suite is §6.3 | +| Tone Curve: parametric (regions, split points), point curve (RGB, R, G, B), targeted adjustment, refine saturation | ✅ | curves apply after display encoding: check against LR behaviour | +| HSL/Color: hue/saturation/luminance per 8 bands, targeted adjustment; B&W mix | ✅ | | +| Point Color (sample, range, ranges visualisation) | ✅ | | +| Color Grading (3 wheels plus global, blending, balance) / legacy split toning | ✅ | | +| Detail: sharpening (amount, radius, detail, masking with Alt preview), NR (luminance, detail, contrast; colour, detail, smoothness) | ✅ | profiled NR with our own measured noise profiles (Phase 2.6); DT's profiled denoise is the behaviour benchmark | +| Enhance: AI Denoise, Raw Details, Super Resolution (outputs a DNG) | 🟡 | Bayer AI denoise only; design from AN's prose note on `rawdenoiseai` (deterministic U-Net, no runtime) | +| Lens Corrections: profile (auto lens lookup, custom), remove CA, defringe (purple/green with eyedroppers), manual distortion and vignetting | 🟡 | **No lens-profile DB**: §6.3 | +| Transform: Upright (Auto, Level, Vertical, Full, Guided), manual transforms | ✅ | | +| Effects: post-crop vignette (styles), grain | ✅ | | +| Calibration: process version, shadow tint, RGB primaries hue/saturation | ✅ | process versions are LC's own | +| Profiles: Adobe-style looks, camera-matching profiles (Camera Standard, Portrait…), creative profiles with amount, LUT profiles, legacy | 🟡 | own looks ✅; **camera-matching** and **measured camera colour** ⬜ | +| Masking: brush (auto mask, flow, density, pressure), linear, radial, luminance range, colour range, depth range, Select Subject, Select Sky, Background, Objects, People (face, eyes, lips, hair, body, clothes), Landscape (water, vegetation, mountains…), add/subtract/intersect, invert, mask overlay modes, update AI masks, adaptive presets | 🟡 | AI masks are heuristics; SAM 3 path exists without hosted weights; pressure brushes from PC `paint`/`tablet` | +| Lens Blur (AI depth, bokeh shapes, focal range) | ⬜ | needs a depth model | +| Generative Remove | 🚫 | Adobe cloud; local PatchMatch instead | +| Copy/paste/sync settings (selective), Auto Sync, Previous, Reset | ✅ | | +| Presets: create from groups, import (`.xmp`, `.lrtemplate`), amount slider, adaptive presets | ✅ | adaptive ⬜ | +| Reference View (side by side with a reference photo) | ✅ | | +| Soft proofing: profile, rendering intent (perceptual/relative), Simulate Paper & Ink, destination gamut warning, create proof copy | 🟡 | **use PC `cms`** (ICC v2/v4, LUT profiles, BPC, gamut check) | +| HDR editing (extended range, HDR display, visualise, SDR preview, HDR export) | ⬜ | §6.6 | +| Photo Merge: HDR (deghost, auto align, auto settings), Panorama (projections, boundary warp, fill edges), HDR Panorama | ✅ | | +| Develop view options (info overlay, show messages) | ⬜ | small | +| Zoom: true 1:1 and higher from the original pixels | 🟡 | 2,560 px preview cap; region renderer exists for loupe only (§6.2) | + +### 2.6 Raw and camera support + +| Feature | LC | Src / notes | +|---|---|---| +| DNG all variants incl. 1.7 JXL, opcodes, semantic masks | ✅ | | +| CR2, NEF, ARW, RAF incl. X-Trans compressed, RW2/RWL, PEF, uncompressed ORF/SRW | ✅ | | +| **CR3** (all CRX variants, sRAW/mRAW), **compressed ORF**, **compressed SRW**, NEF lossy-after-split | 🟡/⬜ | LC: only M50/R100/R8 verified. Most common missing format | +| Long tail: 3FR, IIQ, MOS, ERF, KDC, DCR, MRW, X3F, NRW, etc. | ⬜ | | +| Per-camera colour matrices, WB presets, noise profiles, black/white levels, crop masks | 🟡 | **biggest quality gap**; measured by us (Phase 2.1, rules in §4) | +| Lens-correction profiles for camera/lens pairs | 🟡 | DNG and RW2 embedded only | + +### 2.7 Map module + +| Feature | LC | Src / notes | +|---|---|---| +| Map view with styles (road, satellite, terrain, light/dark), zoom, search location | ⬜ | new: slippy-map tile renderer in egui, configurable tile server plus disk cache | +| Pins and clusters for geotagged photos, hover previews | ⬜ | | +| Drag photos onto the map to geotag | ⬜ | | +| Tracklog import (GPX), auto-tag with time offset | 🟡 | GPX geotagging ✅; map display ⬜ | +| Saved locations (radius, private flag to strip GPS on export) | ⬜ | | +| Location filter bar (visible on map, tagged, untagged) | ⬜ | | +| Reverse geocoding (city, state, country fill) | 🚫 in LC | opt-in online service, or offline GeoNames (CC-BY) | + +### 2.8 Book module + +| Feature | LC | Src / notes | +|---|---|---| +| Book settings: type (Blurb/PDF/JPEG), size, cover, paper, logo page | ⬜ | Blurb upload is proprietary; ship PDF and JPEG | +| Auto Layout with presets, page templates (1–4+ photos, text), custom pages | ⬜ | new | +| Page and spread editing, page numbers, guides (bleed, safe text, filler text) | ⬜ | | +| Cell padding, photo zoom/pan in cell, photo text and page text, text styles (font, size, tracking, baseline, leading, kerning, alignment) | ⬜ | **PC `text`** (parley shaping, CJK) | +| Background (graphic, colour, photo), multi-page and spread views | ⬜ | | +| Export book to PDF (embedded fonts, ICC, multi-page) and JPEG | ⬜ | needs a real PDF writer (PC's is single page and has no font embedding) | +| Saved books (special collection type) | ⬜ | | + +### 2.9 Slideshow module + +| Feature | LC | Src / notes | +|---|---|---| +| Templates (built-in, user), template browser preview | ⬜ | | +| Options: zoom to fill, stroke border, cast shadow | ⬜ | | +| Layout guides and margins, overlays (identity plate, rating stars, text overlays with tokens, watermark) | ⬜ | PC `text` | +| Backdrop: colour wash, image, background colour | ⬜ | | +| Titles: intro/ending screens | ⬜ | | +| Music: multiple tracks, sync slides to music, audio balance | ⬜ | pure-Rust decode (`symphonia`) + output (§6.5 notes) | +| Playback: duration, fades, random order, repeat, pan and zoom, quality | 🟡 | impromptu basic only | +| Export to PDF, JPEG sequence, video (MP4/H.264) | ⬜ | video encode: pure-Rust AV1 (`rav1e`) feasible; H.264 is a risk (§6.6) | +| Saved slideshows | ⬜ | | + +### 2.10 Print module + +| Feature | LC | Src / notes | +|---|---|---| +| Layout styles: Single Image/Contact Sheet, Picture Package, Custom Package | ⬜ | new | +| Image settings: zoom to fill, rotate to fit, repeat one photo per page, stroke border | ⬜ | | +| Layout: margins, page grid, cell spacing and size, keep square; rulers, guides, page bleed, dimensions | ⬜ | | +| Page: background colour, identity plate, watermark, page options (numbers, info, crop marks), photo info, text | ⬜ | PC `text`; PC `print_cmds.rs` has crop/registration marks | +| Print job: to printer or JPEG file, draft mode, print resolution, sharpening (low/standard/high, matte/glossy), 16-bit output, colour management (printer ICC, rendering intent, print adjustment brightness/contrast) | ⬜ | **PC `cms`**; OS printing through IPP/CUPS (pure-Rust `ipp`) on Linux and macOS; Windows needs Win32 print API in an isolated `unsafe` crate | +| Page setup / printer settings, Print One | ⬜ | | +| Templates and saved prints | ⬜ | | + +### 2.11 Web module + +| Feature | LC | Src / notes | +|---|---|---| +| Layout styles (HTML grid, track/square/etc. galleries) with templates | 🚫 in LC | new: static HTML/CSS/JS templates we write; DT's web-gallery export is a behaviour reference | +| Site info, colour palette, appearance, image info, output settings (size, quality, watermark, metadata) | ⬜ | reuse export pipeline | +| Upload settings (FTP/SFTP) and Export to folder | ⬜ | pure-Rust SFTP (`russh`); plain FTP optional | +| Saved web galleries | ⬜ | | + +### 2.12 Export, publish and sharing + +| Feature | LC | Src / notes | +|---|---|---| +| Export dialog: location, naming, video, file settings (JPEG/PSD/TIFF/PNG/DNG/AVIF/JXL/HEIF/Original), colour space, bit depth, resize, output sharpening, metadata policy, watermark, post-processing action | ✅ | JXL encode and HDR ⬜; PSD export via PC `psd` | +| Export presets, export with previous, background export queue | ✅ | | +| Watermark editor (text/graphic, shadows, anchors) | ✅ | text shaping upgrade with PC `text` | +| Publish services: Hard Drive, Flickr, Adobe Stock, Facebook, etc.; publish collections, "modified photos to re-publish", comments | ⬜ | new: framework plus Hard Drive first; third-party APIs as plugins | +| Email photos | ⬜ | low priority (mailto with attachments or SMTP) | +| Post-processing: open in other app, export actions | ? | | + +### 2.13 Video + +| Feature | LC | Src / notes | +|---|---|---| +| Import and catalog video | ✅ | | +| Playback, trim, poster frame, capture frame as JPEG | ⬜ | **riskiest pure-Rust item** (§6.6) | +| Quick Develop/presets on video, export video | ⬜ | | + +### 2.14 Immich integration (beyond Lightroom) + +[Immich](https://immich.app) is a self-hosted photo server (AGPL-3.0). We talk to it only over its HTTP API, with a +client we write ourselves. Tracker section **IMM**. + +| Feature | Id | Phase | +|---|---|---| +| Connect to one or more Immich servers (URL + API key in the OS keychain), version check, self-signed TLS trust | IMM-CONNECT | 1 | +| Link catalog photos to Immich assets by SHA-1 checksum; "in Immich" badge, filter, smart-collection rule, Open in Immich | IMM-LINK | 1 | +| Immich as an Import source (timeline, albums, people, favourites); copy originals or add linked | IMM-IMPORT | 1 | +| Shared-originals mode: Immich external library over the same folders, path mapping, no duplicate uploads | IMM-EXTLIB | 1 | +| Immich shared links from Web/Slideshow/Publish (expiry, password, download) | IMM-SHARELINK | 3 | +| Immich publish service: collections → albums; renders, originals, or both stacked; re-publish; trash-only removal | IMM-PUBLISH | 4 | +| Two-way metadata sync: rating, favourite ↔ pick, caption ↔ description, keywords ↔ tags, collections ↔ albums, GPS/time; conflict view | IMM-SYNC | 4 | +| Import Immich people and face regions; push names back | IMM-PEOPLE | 4 | +| Immich smart (CLIP) and metadata search from the Library filter bar | IMM-SEARCH | 4 | +| All Immich actions as commands (CLI, control channel, MCP) | IMM-MCP | 4 | + +### 2.15 Automation (beyond Lightroom) + +| Feature | LC | Notes | +|---|---|---| +| Every action is a command; CLI; JSON control channel; MCP server; headless UI snapshots | ✅ | Strong differentiator; keep it. DT's `src/mcp` tool list is a good checklist for MCP coverage | +| Recordable actions / batch scripts | ⬜ | PC `engine/src/actions_cmds.rs` | + +--- + +## 3. What each existing project gives us + +### 3.1 LightCraft (fork base): keep almost everything + +- **Workspace and quality bar.** It has layered crates enforced by `cargo xtask layers` (L0 geom/color/raster through + L5 UI). Production code may not panic, and `unsafe` is confined to one crate. CI runs fmt, clippy, tests, layers + and wasm, plus a parity tracker with an automatic checker. +- **Develop pipeline** (`crates/pipeline`, `crates/develop`, `crates/gpu`): + - scene-referred float pipeline in linear Rec.2020, with OkLab/OkLCh colour tools; + - per-stage cache; + - a wgpu compute twin that matches the CPU within 1/255. +- **Raw** (`crates/raw`, 18.5k lines): the most complete pure-Rust clean-room decoder set around. It covers DNG 1.7, + CR2, partial CR3, NEF, ARW, RAF X-Trans, every RW2 format and PEF, plus AHD/PPG/X-Trans demosaic and a DNG writer. +- **Library and catalog:** + - crash-safe op-log catalog; + - albums, smart albums, stacks, virtual copies; + - filter and search, XMP interop; + - `.lrcat` importer, GPX geotagging, faces MVP. +- **Edit tools:** every global slider, masking, heal/clone, red eye, Upright, HDR/panorama merge, presets, versions + and sync. +- **Export:** JPEG, PNG, TIFF, WebP, AVIF and DNG, with naming templates, watermarks and background jobs. +- **Automation:** the command engine, CLI, control channel and MCP server. +- **Platforms:** desktop builds plus a web build. +- **Must change or remove:** + - The ArtCraft brand (`docs/brand/` is not open licensed). + - Names (`lightcraft-*` crates). + - The cloud-style UI shell. + - The in-RAM catalog at very large scale. + - Rebuild the missing local `plan/` reference folder that the tracker ids point at. + - The 45k-line `engine` crate needs splitting before Print, Book and the other new modules go into it. + +### 3.2 PhotoCraft (donor): port these crates with copy-and-rename, as LightCraft already did with `heif` + +| PhotoCraft piece | Gives the clone | Where it lands | +|---|---|---| +| `algo/src/inpaint.rs`, `content_aware.rs` (PatchMatch, Wexler EM, Poisson blend) | Real content-aware Remove, auto heal source | Develop → Remove | +| `algo/src/segment/` (GrabCut, maxflow, SLIC, saliency, sky) | Classical fallback and edge refinement for AI masks | Masking | +| `cms` (5k lines, own ICC v2/v4 engine, LUT/CMYK, BPC, gamut check, profile writing) | Printer soft proofing, Print module colour management, gamut warning | Develop soft proof, Print | +| `text` (parley shaping, CJK/vertical, craft-fonts) | Print/Book/Slideshow text, identity plate, watermarks | Output modules | +| `paint`, `tablet`, `ui-egui/src/stylus.rs` | Pressure/tilt-aware masking brush (macOS and X11; Windows still to write) | Masking brush | +| `psd` + `io/src/psd_export.rs` | Layered PSD/PSB export, "Edit In → Open as Layers", PSD import | Export / external edit | +| `plugins` (wasmi sandbox) | Plugin SDK for publish services, export filters, metadata providers | §6.5 | +| `engine/src/actions_cmds.rs` | Recordable actions / batch automation | Automation | +| `codecs` (EXR, deep EXR) | EXR import/export (HDR) | Export | +| `vector` | Book/Print layout shapes, mask paths | Output modules | +| `engine/src/print_cmds.rs` (minimal PDF writer, crop marks) | Starting point only; replace with a multi-page PDF writer with font embedding | Print/Book | + +Not worth taking: PhotoCraft's `raw` (weaker than LightCraft's), its `gpu` (a compositor, not a develop pipeline) and +its `codecs` JXL (it has none). + +### 3.3 darktable and Ansel (behaviour and design reference only) + +The project is MIT (§4), so darktable and Ansel are used **as running applications, user manuals and prose design +notes**. Their source code is never opened. File paths that appear below only show *where a feature lives*, so it can +be tried in the running app. They are not reading material. + +**Features and design to emulate:** + +- The **output views** exist and work, so they are a functional reference for Map, Print, Slideshow, tethering, + web gallery, photo book and publishing. Try them in the app: the map, print, slideshow and tethering views; the + print settings, map locations and geotagging panels; and the gallery, LaTeX book and Piwigo export storages. +- **Colour-science algorithms** that are published in papers and documented in the darktable and Ansel docs: + - colour calibration / CAT with chart fitting (`channelmixerrgb`); + - filmic, sigmoid and AgX tone mapping; + - diffuse-or-sharpen (PDE-based detail); + - tone equalizer; + - profiled denoise (Poisson-Gaussian noise model); + - highlight reconstruction (Ansel's harmonic version, `ansel/doc/highlights-reconstruction.md`). +- **Ansel's engineering notes** (`ansel/doc/*.md`): + - incremental pipeline cache that recomputes only downstream stages (5–40× faster); + - lazy-loaded SQLite lens DB; + - "studio capture" folder-watch tethering; + - a deterministic, dependency-free ML raw denoiser (`rawdenoiseai`). + - LightCraft already does most of the pipeline-cache part. +- **darktable-chart**, as described in the darktable manual: chart shots, thin-plate-spline fitting, ΔE report. + This is the method for making our own camera profiles; we implement it from the published description. +- **darktable's MCP feature list**, as documented for users: a checklist for agent coverage. + +**Data that is not used.** It is listed here so nobody imports it by accident; only the last row is allowed: + +| Data | Path | Licence | Gap it fills | +|---|---|---|---| +| ~100 chart-measured camera matrices | `darktable/src/common/colormatrices.c` | GPL-3+ | Camera colour calibration | +| Noise profiles, 437 cameras (Poisson-Gaussian per ISO) | `darktable/data/noiseprofiles.json` | GPL-3+ | Profiled denoise, AI denoise sigma maps | +| WB presets, 485 models | `darktable/data/wb_presets.json` | GPL-3+ | WB presets per camera | +| Per-camera base curves (535 styles) | `darktable/data/styles/`, `src/iop/basecurve.c` | GPL-3+ | "Camera Standard"-like default looks | +| Colour checker reference values, illuminants, CIE observer | `src/common/colorchecker.h`, `illuminants.h`, `src/external/cie_colorimetric_tables.c` | GPL-3+ (CIE data itself is public) | Our own chart calibration | +| rawspeed `cameras.xml` (matrices, crops, black/white levels, CFA) | submodule **not checked out**; `git submodule update --init` | LGPL-2.1 | Camera coverage and colour | +| LibRaw (CR3 and many long-tail decoders) | submodule **not checked out** | LGPL-2.1 / CDDL | CR3, compressed ORF and other decoders | +| lensfun lens DB (~1,500 lenses) | not bundled; separate download | **CC-BY-SA 3.0** (data) | **Allowed**: shipped as a separate, attributed CC-BY-SA data file (Phase 2.5); lensfun's LGPL *code* is not read | + +--- + +## 4. Licence: MIT (decided 2026-10-10) + +The fork is licensed **MIT**. LightCraft and PhotoCraft are "MIT OR Apache-2.0", and the fork takes the MIT option of +that dual licence. + +### 4.1 What MIT means in practice + +- **Upstream copyright stays.** `LICENSE` names the LightCraft and PhotoCraft contributors (for inherited code) and + "the project contributors" (for new code). No product name appears in it; the name is in `brand.toml`. +- **Two exceptions stay Apache-2.0 only, and that's allowed.** + - LightCraft's `crates/segment` ports Hugging Face SAM 3 code that is Apache-2.0, so it can't be relicensed. + - `crates/fetch` was split out of it. + - Both keep `license = "Apache-2.0"` and their `NOTICE` entries. The app as a whole is MIT with two + Apache-2.0-licensed components, which is compatible. + - The planned `net` crate (Phase 1.7) is **written fresh under MIT** rather than grown from `fetch`. +- **Merging continues both ways.** + - Upstream LightCraft changes can be merged at any time, taking the MIT option. + - Our changes could go back upstream if wanted. +- **Commercial use and app stores are unrestricted.** +- **Dependencies:** `cargo deny` allows only MIT, Apache-2.0, BSD-2/3, ISC, Zlib, Unicode-3.0, CC0-1.0 and MIT-0. + GPL, LGPL, AGPL, MPL and SSPL are denied in the dependency tree. +- **Data files** may be CC-BY or CC-BY-SA if they ship as separate, attributed data files, never compiled into code. + This covers the lensfun DB and GeoNames. + +### 4.2 Clean-room rules (inherited from LightCraft, unchanged) + +- **Never read or copy GPL, LGPL or AGPL source:** darktable, Ansel, RawTherapee, ART, LibRaw, rawspeed, lensfun's + code, dcraw-derived code, Immich. Agents must not open their `.c`, `.cc`, `.h` or `.rs` files. +- **Allowed sources:** + - running darktable and Ansel as *applications* and watching their behaviour; + - their user manuals and prose design notes (for example `ansel/doc/*.md`), skipping any code excerpts in them; + - published papers and format descriptions written in prose. + - LightCraft has decided the same for raw formats (2026-10-05). +- **No GPL data tables** such as darktable's `noiseprofiles.json`, `wb_presets.json`, `colormatrices.c` or + basecurves. The equivalents are measured ourselves (Phase 2.1). +- **Adobe:** + - no assets, DCP, LCP, presets, profiles or matrices; + - never look inside Adobe application bundles; + - camera matrices are never harvested from Adobe-converted DNGs. Matrices in camera-native DNGs (written by the + camera maker's own software, checked via the `Software` tag) are manufacturer data and may be used. + +### 4.3 Cost of this choice + +Camera colour, noise profiles, white-balance presets and long-tail raw decoders must be **measured or +reverse-engineered by us**. That makes Phase 2 larger (110–180 h instead of 80–160 h) and turns it partly into a +**data-collection project**: chart shots, flat-field and ISO series, and CC0 raw samples. It needs a community +contribution pipeline (Phase 2.2). The upside is a clean, permissively licensed camera and lens database that we own. + +--- + +## 5. Target architecture (deltas from LightCraft) + +``` +L0 geom color raster tiff sysmem fetch heif (LightCraft) +L1 raw codecs meta develop denoise faces scenes (LightCraft) + cms (from PhotoCraft) + camdb ← NEW: camera matrices, WB presets, noise profiles, crops, levels (data crate) + lensdb ← NEW: lens profiles (lensfun data + our own), lookup by EXIF + text ← from PhotoCraft (parley) pdf ← NEW: multi-page PDF writer, font embedding, ICC +L2 pipeline (LightCraft) + region/tiled full-res renders + inpaint ← from PhotoCraft algo (PatchMatch, content-aware, GrabCut refinement) +L3 gpu catalog preview merge segment (LightCraft) catalog → indexed on-disk store + layout ← NEW: page/cell/template model shared by Print, Book, Slideshow, Web, Contact sheet + geo ← NEW: tile fetch/cache, projections, clustering, GPX, saved locations, geocoding + tether ← NEW: PTP over USB (nusb) / PTP-IP; folder-watch fallback + media ← NEW: audio (slideshow), video decode/encode (highest risk) +L4 engine → split: engine-core (commands, session, jobs), engine-library, engine-develop, + engine-export, engine-output (print/book/slideshow/web), engine-publish + plugins ← from PhotoCraft (wasmi), publish/export SDK +L5 ui-egui → Classic shell: Module trait {Library, Develop, Map, Book, Slideshow, Print, Web}, + panel framework (left/right/top/filmstrip, solo, auto-hide), Classic keymap layer + mcp + net ← promoted from fetch's pure-Rust HTTPS client: JSON, multipart upload, proxies, custom CAs + credentials← OS keychain / encrypted-file secrets immich ← NEW: Immich client, link, publish, sync + brand ← NEW (L0): every product name/id, generated from brand.toml +Apps: internal binaries `app`, `app-cli` (and optional web build), renamed from brand.toml at packaging time +``` + +**Upstream strategy.** LightCraft is moving fast: 1,117 commits, many in the last week. Treat the fork as a +**downstream** that merges `lightcraft/main` regularly. + +- Keep LightCraft's crates as unchanged as you can. +- Put Classic-only work in **new crates and new UI modules**, so merges stay cheap. +- Rename crates only once, mechanically, at fork time. + +--- + +## 6. Plan to completion + +Estimates are in **agent-hours**, calibrated on LightCraft's own log (4–6 parallel agents built M0–M13 in about 25 +active hours, roughly 105–145 agent-hours in total). Treat them as relative sizes: the heavy items depend on data and +licences, not on typing speed. Each phase ends with an **exit gate** checked by tests or measurement, not by +ticking boxes. + +### Phase 0: Fork, brand config and foundations (≈ 12–22 h) → [PLAN_phase_0.md](PLAN_phase_0.md) + +1. Fork `lightcraft` into `nonameyet/` with full git history (`git clone` + new remote). +2. **Product name in one config file (`brand.toml`)**, read by a `brand` crate. No source file contains the name; a CI + check enforces it, and settings/libraries migrate automatically on rename. Remove the ArtCraft brand + (`docs/brand/`, README hero, logos). Give crates and binaries neutral internal names. +3. **Licence (MIT, §4):** `LICENSE` (MIT), `NOTICE`, `cargo deny` policy; keep the clean-room rules in + `AGENTS.md`/`CLAUDE.md`; `segment` and `fetch` stay Apache-2.0. +4. Rebuild `plan/`: a Lightroom Classic reference (feature catalog, menus, Classic shortcuts) **written in our own + words**, the Classic module map from §2, and `STATUS.md`. Extend `docs/parity.md`: + - reopen the 🚫 Classic rows (KEYC-MODULES, Web module, reverse geocoding); + - fix the garbled "Top gaps" list. +5. Bring in shared infrastructure: `craft-fonts` (CJK) and the photo corpus (`cargo xtask corpus`). Add an + `upstream` remote and a merge routine (merge, `cargo xtask ci`, fix, commit). +6. Add Immich tracker rows (IMM-*), the `plan/immich.md` research note, and a pinned Immich test server + (`cargo xtask immich up`). + +**Gate:** `cargo xtask ci` green; renaming = editing `brand.toml` only; the app launches; parity tracker counts Classic rows. + +### Phase 1: The Classic shell, a catalog that scales, Immich link (≈ 50–85 h) → [PLAN_phase_1.md](PLAN_phase_1.md) + +1. **Module system** in `ui-egui`: + - a `Module` trait with its own panels, toolbar and keymap; + - module picker, identity plate, panel framework (auto hide/show, solo mode, Tab/⇧Tab/F5–F8/T), screen modes, + lights out; + - a secondary window with Grid/Loupe(live/locked)/Compare/Survey. + - Re-home LightCraft's existing views into **Library** and **Develop**. +2. **Classic keymap layer** (KEYC-*), with LightCraft's layout as an option. +3. **Library panels Classic-style:** + - Navigator; Catalog panel (Quick Collection, Previous Import); + - Folders (rename/move/sync, volumes); + - Collections with sets and target collection; Quick Develop; + - Keywording (keyword sets, suggestions); Keyword List (synonyms, export flags, import/export); + - Metadata panel views plus presets and copy/paste; + - Painter tool. +4. **Catalog v4:** + - benchmark the current op-log at 250k and 1M photos; + - move to an on-disk, indexed store (pure Rust, e.g. `redb`, with secondary indices) behind the existing + `catalog` API; + - lazy photo records; + - backup-on-exit with integrity check and optimise; + - multiple catalogs; Export as Catalog / Import from Catalog with conflict rules; + - metadata-conflict badges against XMP. +5. **Split `engine`** (45k lines) into the sub-crates of §5 before the output modules land. +6. **Full-resolution zoom:** + - generalise `ui-egui/src/region.rs` to tile/region rendering at 1:1 and above, for loupe, compare, soft proof and + overlays; + - 1:1 preview cache with auto-discard. + +7. **Network groundwork and Immich link:** + - `net` and `credentials` crates; `remote_identity` catalog table; SHA-1 checksums at import; + - IMM-CONNECT, IMM-LINK, IMM-IMPORT and IMM-EXTLIB. + +**Gate:** +- A 500k-photo synthetic catalog opens in under 2 s and filters in under 100 ms. +- Every Library and Develop panel and every Classic shortcut row in the tracker is ✅. +- 1:1 zoom matches export pixels. + +### Phase 2: Image quality and camera coverage (≈ 110–180 h, partly data collection) → [PLAN_phase_2.md](PLAN_phase_2.md) + +1. **`camdb` crate:** per-camera matrices (dual illuminant), WB presets, noise profiles, black/white levels and crops. + - sources: data the file carries itself, our own chart calibration, noise profiles measured from ISO series and + the corpus, WB presets read from maker notes, and LightCraft's JPEG fitting as the fallback; + - our own chart calibration tool, built from the published description of the darktable-chart method + (ColorChecker / IT8, thin-plate-spline LUT), for "measured" profiles; + - a community pipeline for CC0 chart and ISO-series submissions. +2. **Camera-matching profiles** (Standard/Portrait/Landscape/Neutral/Vivid per maker): fitted to camera JPEGs with + LightCraft's existing fitter, stored as our own LUT profiles. +3. **Raw decoders:** + - remaining CR3 CRX variants and sRAW/mRAW; + - compressed ORF and SRW; + - NEF lossy-after-split; + - then the long tail (3FR, IIQ, MOS, ERF, KDC, DCR, MRW, NRW, X3F if feasible). + - clean-room: black-box analysis and prose format descriptions, as LightCraft does now. + - Corpus: one CC0 sample per model from raw.pixls.us, with a decode and colour sanity test per model. +4. **`lensdb` crate:** + - lensfun DB (CC-BY-SA, attributed), converted at build time to a compact lazy-loaded table (Ansel's lesson: + don't parse 1,500 XML entries at startup); + - auto lookup from EXIF lens id, distortion/TCA/vignetting models, custom profile import; + - later, our own calibration tool. +5. **Remove tool:** port PhotoCraft's PatchMatch inpaint and content-aware fill; spot pin editing; Detect (dust spots). +6. **Denoise:** + - profiled classical NR using noise profiles (Poisson-Gaussian variance stabilisation); + - AI denoise across Bayer, X-Trans and linear raws, following the deterministic no-runtime design in Ansel's prose + notes, and needing + permissively licensed or our own trained weights; + - Raw Details and Super Resolution (DNG output). +7. **Render-fidelity suite:** + - reference renders made locally from CC0 raws (never committed); + - ΔE2000 and SSIM per slider sweep; + - tune tone/highlights/clarity/texture/NR/sharpening against the numbers. + - Also settle tone-curve placement (LightCraft applies curves after display encoding). +8. **Soft proofing:** switch to PhotoCraft `cms`: + - printer ICC profiles, perceptual/relative intent, BPC; + - Simulate Paper & Ink; + - destination gamut warning, create proof copy. + +**Gate:** +- ≥ 95% of models in the corpus decode from sensor data. +- Median ΔE2000 ≤ 2 against camera JPEGs for supported bodies. +- Lens profile found for ≥ 80% of corpus lens EXIFs. +- Fidelity suite runs in CI on a small set. + +### Phase 3: Output modules (≈ 72–124 h; can run in parallel with Phase 2 after Phase 1) → [PLAN_phase_3.md](PLAN_phase_3.md) + +Shared first: **`layout`** (pages, cells, guides, templates, text blocks), **`text`** (from PhotoCraft) and a real +**`pdf`** writer (multi-page, font subsetting and embedding, ICC output intents, JPEG/Flate images). + +1. **Print:** + - Single Image/Contact Sheet, Picture Package, Custom Package; + - guides, rulers, crop marks, page/photo info, identity plate, watermark; + - print sharpening and 16-bit output; + - colour management with printer ICC and intent; + - print to JPEG/PDF; + - OS printing: IPP/CUPS in pure Rust on Linux and macOS; Win32 spooler on Windows in an isolated `unsafe` crate; + - templates and saved prints. +2. **Map:** + - egui slippy map with a configurable tile server, disk cache and attribution; + - pins and clusters, drag-to-geotag; + - GPX tracklog display plus auto-tag; + - saved locations with privacy (strip GPS on export); + - location filter; + - opt-in reverse geocoding (online service or offline GeoNames). +3. **Slideshow:** + - templates, overlays, backdrop, titles, pan and zoom, fades; + - music with sync-to-music (pure-Rust decode with `symphonia`; audio output through `cpal`, which links system + ALSA on Linux, so accept it or add a pure-Rust PipeWire/PulseAudio backend); + - export to PDF and JPEG; + - video export (AV1 via `rav1e` in WebM/MP4 first, H.264 depends on §6.6); + - saved slideshows. +4. **Book:** + - settings (size, cover, paper); + - Auto Layout with presets, page templates, custom pages; + - cells, page and photo text with full type controls; + - backgrounds, guides, spread view; + - export to PDF and JPEG (Blurb is proprietary, so out of scope); + - saved books. +5. **Web:** + - gallery templates we write ourselves (HTML/CSS/JS, responsive, no external CDN); + - site info, palette, image info, output settings; + - export to folder plus SFTP upload (`russh`); + - saved galleries; + - "Share via Immich": album plus shared link (IMM-SHARELINK). + +**Gate:** each module's tracker rows are ✅; golden-image tests of the layout engine (PDF raster compare); a print +round trip through a known ICC profile measures within ΔE tolerance. + +### Phase 4: Workflow power features and full Immich integration (≈ 60–105 h) → [PLAN_phase_4.md](PLAN_phase_4.md) + +1. **Tethered capture:** + - start with "studio capture" (watched folder plus auto-apply preset), which is cheap and works with any vendor + app; + - then native PTP over USB (`nusb`) and PTP-IP for Canon/Nikon/Sony: shoot, settings bar, live view, naming, + sessions. +2. **Publish services framework:** + - publish collections, the modified-for-republish state, remote id tracking; + - built-in **Hard Drive** publisher; + - Immich built in (item 8); WebDAV/Piwigo/PhotoPrism/Nextcloud as plugins; + - optional Flickr and other OAuth services. +3. **Plugin SDK:** + - PhotoCraft's wasmi sandbox extended with a host API (catalog read/query, export hooks, metadata providers, + publish service interface, menu commands); + - capability-based permissions (network, filesystem roots); + - pure Rust, unlike Lightroom's Lua. +4. **Edit In:** + - external editor presets; + - "Open as Layers" / "Open as Smart Object"-style round trip to PhotoCraft, using PhotoCraft's layered PSD writer; + - re-import and stack the result. +5. **Actions:** record and replay of command sequences, built on PhotoCraft's `actions_cmds`; batch on a selection. +6. **People:** face clusters with separators, write face regions to XMP (MWG regions), small-face detection on + large images. +7. **`.lrcat` migration v2:** history replay, snapshot import, profile mapping table, and a fidelity report per + photo. + +8. **Immich, two-way:** + - publish service (albums; renders, originals, or both stacked); + - metadata sync with conflict handling; + - people and face import; + - smart search; + - MCP commands. + +**Gate:** a scripted end-to-end session through MCP: tethered shoot → import preset → cull → develop → publish to +folder, SFTP and Immich → rating changed in Immich syncs back → print to PDF. It runs headless in CI (with a simulated camera). + +### Phase 5: AI, HDR and video (≈ 100–200 h, highest uncertainty) + +1. **AI model strategy (an owner decision).** Use permissively licensed weights, or train our own; pure-Rust + inference on candle or LightCraft's own interpreter; host the downloads. + - Subject, Sky, Background, People parts, Landscape parts, depth (for Depth Range and Lens Blur). + - Update AI masks after edits; adaptive presets. + - Semantic search with CLIP-like embeddings on device. + - Assisted culling: eyes closed, focus, near duplicates. + - darktable's `src/ai` shows a working model set (SAM 2.1, NIND denoise, RealPLKSR), but check each model's + licence on its own. +2. **HDR:** + - HDR editing range (extended highlights in the scene-referred pipeline, which LightCraft already has); + - HDR display via wgpu with an HDR swapchain (platform-dependent); + - visualise high dynamic range, SDR preview settings; + - export as JPEG with gain map (ISO 21496-1), AVIF/JXL HDR, and EXR (PhotoCraft codecs). +3. **Video:** + - playback, trim, poster frame, frame capture, presets on video, export. + - **Pure-Rust decoding is the risk.** AV1 via `rav1d` (Rust) is fine, but there is no mature pure-Rust H.264 or + HEVC decoder, and HEVC also has patent issues. + - Options: + - (a) write a pure-Rust H.264 baseline/main decoder: large; + - (b) allow OS decoders (VideoToolbox, Media Foundation, VA-API) in an isolated FFI crate, as LightCraft + already does for one macOS call; + - (c) share FilmCraft's crates if and when they exist. + - Recommendation: (b). It breaks "pure Rust" only at a thin, optional platform edge. + +**Gate:** AI masks reach IoU ≥ 0.85 on an annotated CC0 test set; an HDR export round-trips gain maps; MP4 from the +main camera brands plays and trims. + +### Phase 6: 1.0 hardening (≈ 30–50 h) + +- Performance budgets: + - slider ≤ 16 ms at preview size on 24 MP; + - 1:1 tile ≤ 100 ms; + - import 1,000 raws with standard previews in under 2 min; + - catalog at 1M photos. +- Robustness: fuzzing raw/XMP/catalog/plugin inputs (the never-crash rule), corrupt-catalog recovery, and a disk-full + test. +- Accessibility (AccessKit through egui), localisation, a Classic-style help overlay per module. +- Packaging: AppImage/Flatpak, .deb/.rpm, dmg (notarised), msi. Decide whether to keep or drop the web build (it + costs CI time and constrains crates). +- Documentation: user manual, plugin SDK docs, migration guide from Lightroom Classic. + +**Gate:** tracker ≥ 98% of in-scope rows; fidelity and performance suites green; a beta with real Lightroom Classic +users migrating real catalogs. + +### Totals + +| Phase | Agent-hours | +|---|---:| +| 0 Fork, brand config and foundations | 12–22 | +| 1 Classic shell, catalog, Immich link | 50–85 | +| 2 Quality and camera coverage | 110–180 | +| 3 Output modules | 72–124 | +| 4 Workflow power features, Immich two-way | 60–105 | +| 5 AI, HDR, video | 100–200 | +| 6 Hardening | 30–50 | +| **Total** | **≈ 434–766** | + +Order and parallelism: +- Phases 0 → 1 must come first; they are the architectural changes everything else sits on. +- Phases 2, 3 and 4 then run in parallel on separate crates. +- Phase 5 depends mostly on the model decision and can start research early. +- With 4–6 parallel agents at about 70% efficiency, that is roughly **110–190 hours of wall-clock work**, plus the + non-coding time for data (chart shots, corpus), model licensing and testing with real users. +- Without Phase 5 (AI, HDR, video), a complete Classic-module application with Lightroom-grade colour is about + **335–565 agent-hours**. + +--- + +## 7. Risks + +| Risk | Impact | Mitigation | +|---|---|---| +| Clean-room data collection is slow (MIT, no GPL tables) | Some cameras stay "estimated" for a long time | Community CC0 chart/ISO-series submissions; automatic noise estimation from corpus raws; maker-note WB presets; JPEG fitting fallback | +| Contamination: an agent reads GPL source | Licence breach | Clean-room rule in AGENTS.md; GPL trees are never referenced by path in tasks; every algorithm PR names its sources | +| LightCraft keeps moving; merges get painful | Lost upstream fixes | New work in new crates; merge weekly; keep shared crate names unchanged after the one-time rename | +| Catalog redesign breaks existing libraries | Data loss | Keep the catalog API; migration with backup; crash/fuzz tests from LightCraft | +| AI weights not licensable | AI masks stay heuristic | Classical fallbacks (PhotoCraft GrabCut/maxflow); train our own small models | +| Video decoding in pure Rust | No video | Isolated OS-decoder FFI crate (§Phase 5) | +| Look fidelity vs Adobe never matches | Users notice a different look | Measured fidelity suite; camera-matching profiles; accept "different but good" where needed | +| Printing on Windows needs FFI | Print module incomplete on Windows | Isolated `unsafe` crate like `sysmem`; PDF export always works | +| Immich API changes between releases | Sync breaks after a server upgrade | Pin and test the minimum and latest releases nightly; version check on connect; feature-detect optional endpoints | +| Name hard-coded again by upstream merges or new code | Rename gets expensive | `cargo xtask brand check` in CI plus a throw-away-brand build | +| Adobe IP | Legal | Keep LightCraft's rules: no Adobe assets, DCP, LCP, presets or bundle inspection; feature names in our own words | + +--- + +## 8. Immediate next steps + +1. ~~Licence~~: **MIT** (decided 2026-10-10). The name can wait: `brand.toml` makes it a one-line change at any time. +2. Phase 0 ([PLAN_phase_0.md](PLAN_phase_0.md)): fork, brand config, debrand, rebuild `plan/`, update the tracker + (including Immich). +3. Spike in Phase 1 (both inform everything after): + - the `Module` trait and panel framework in the UI; + - the catalog benchmark at 500k photos. diff --git a/PLAN_phase_0.md b/PLAN_phase_0.md new file mode 100644 index 0000000000..65336df142 --- /dev/null +++ b/PLAN_phase_0.md @@ -0,0 +1,262 @@ +# Phase 0: Fork, brand configuration and foundations + +Part of [PLAN.md](PLAN.md). **Estimate:** 12–22 agent-hours. **Licence:** MIT (decided 2026-10-10, PLAN.md §4). +**Unblocks:** every later phase. + +**Goal:** the LightCraft code base, running under a product name that lives in **one config file** and can be changed +at any time. It also gets a parity tracker that covers Lightroom Classic and Immich, and an upstream-merge routine. + +--- + +## 0.1 Fork + +1. Clone `../lightcraft` into this folder with full history: + - `git clone ../lightcraft .` + - rename `origin` to `upstream` + - add the new origin. +2. Tag the fork point `fork-base` so `git log fork-base..upstream/main` always shows what upstream did since. +3. Write `docs/upstream-merge.md`. The routine: + 1. `git fetch upstream` + 2. merge into a `merge/upstream-YYYYMMDD` branch + 3. run `cargo xtask brand check` and `cargo xtask ci` + 4. fix, commit, merge. + - Weekly at first. + - Upstream renames are resolved by the brand tooling in 0.2, never by hand-editing names. + +**Done when:** `cargo xtask ci` is green on the untouched fork. + +--- + +## 0.2 The name lives in one config file (`brand.toml`) + +**Requirement:** the product name (and everything derived from it) is defined **once** in `brand.toml` at the +workspace root. Changing that file and rebuilding renames the product everywhere: + +- window title, menus and About; +- CLI help; +- logs and settings folders; +- installers; +- MCP server name; +- docs that are generated. + +**No source file may contain the product name.** + +### 0.2.1 The config file + +`brand.toml` (workspace root, the only place a name is written): + +```toml +# Changing anything in [product] is safe at any time: rebuild and repackage. +[product] +display_name = "NoNameYet" # window title, menus, About, dialogs, docs +short_name = "NoNameYet" # macOS menu bar, taskbar, notifications +tagline = "Photo library and raw development" +vendor = "NoNameYet contributors" +homepage = "https://example.invalid" +repository = "https://example.invalid/repo" +binary = "nonameyet" # desktop executable name in packages +cli_binary = "nonameyet-cli" +env_prefix = "NONAMEYET" # NONAMEYET_LOG, NONAMEYET_GPU, … +mcp_server = "nonameyet" # MCP server id shown to agents +icon_svg = "brand/icon.svg" # source for every generated icon +logo_svg = "brand/logo.svg" # identity plate default, About box + +# Identifiers stored in users' files and OS registrations. Changing these is allowed, but the old +# values MUST be appended to [legacy] in the same commit, so existing installs keep working. +[identity] +app_id = "org.example.NoNameYet" # reverse-DNS: bundle id, Flatpak id, MIME/desktop ids +settings_dir = "NoNameYet" # ~/.config/, ~/Library/Application Support/, %APPDATA%\ +library_default = "NoNameYet Library" # default catalog folder name under Pictures +catalog_ext = "nnycat" +preset_ext = "nnypreset" +url_scheme = "nonameyet" # nonameyet:// deep links, OAuth redirects + +# Never derived from the product name: these stay valid across renames forever. +[stable] +xmp_namespace_uri = "https://ns.example.invalid/develop/1.0/" +xmp_namespace_prefix = "nnyd" +catalog_magic = "PHOTO-CATALOG" # file-format magic; neutral on purpose + +# Previous identities, read on startup for migration (settings, catalogs, presets, env vars). +[legacy] +settings_dirs = ["LightCraft"] +env_prefixes = ["LIGHTCRAFT"] +preset_exts = ["lcpreset"] +catalog_exts = [] +app_ids = [] +``` + +Three groups, because names fall into three kinds: + +- **[product]** is the user-visible brand, freely changeable. +- **[identity]** is OS and file identity. It is changeable, but it needs migration, which the app does automatically + from **[legacy]**. +- **[stable]** holds format identifiers that must never follow the name. A rename must never orphan users' XMP sidecars. + +### 0.2.2 How code gets the name + +- **New crate `crates/brand` (L0, no dependencies).** + - Its `build.rs` reads `../../brand.toml` (or `$BRAND_FILE`, for test builds) and generates `pub const`s: + `DISPLAY_NAME`, `BINARY`, `APP_ID`, `ENV_PREFIX` and the rest. + - It also provides helpers: + - `brand::env("LOG")` reads `NONAMEYET_LOG`, falling back to every legacy prefix; + - `brand::settings_dir()`; + - `brand::legacy_settings_dirs()`. + - `cargo:rerun-if-changed=brand.toml` means editing the file triggers a rebuild. +- **Code changes:** + - Replace every hard-coded name in `crates/` and `apps/` (292 × "LightCraft" in 115 files, 25 `LIGHTCRAFT_*` + environment variables, preset and library names) with `brand::` constants. + - Replace user-visible format strings like `"{} Library"` with `brand::LIBRARY_DEFAULT`. +- **Localisation:** + - Catalogs use a `{app}` placeholder instead of the name; + - the i18n loader substitutes `brand::DISPLAY_NAME` at load time. + - Update every `docs/localization-*.md` table. +- **Native macOS menu bar:** take the application menu title from `brand::SHORT_NAME`. +- **Packaging becomes templates rendered by `cargo xtask package` from `brand.toml`:** + - `packaging/linux/{app_id}.desktop.in`, `{app_id}.metainfo.xml.in`, `{app_id}.mime.xml.in`; + - Flatpak manifest, `nfpm.yaml.in`; + - `macos/Info.plist.in`; + - `windows/app.wxs.in`. + - The current files hard-code `ai.storyteller.lightcraft.*` and `lightcraft.wxs`. +- **Icons:** `packaging/icons.sh` renders every icon size from `brand.icon_svg`. +- **Binaries:** + - Cargo `[[bin]] name`s cannot read a config file, so the binaries keep **neutral internal names** (`app`, `app-cli`). + - `cargo xtask run`, `cargo xtask package` and `cargo xtask install` copy and rename them to `brand.binary` / + `brand.cli_binary`. + - Shell completions and man pages are generated with the branded name. +- **Crate names:** + - Packages are named by function with a neutral internal prefix (`dac-raw`, `dac-catalog`, …; the prefix is an + internal codename never shown to users and can be changed with `cargo xtask rename-crates `). + - Renaming the crates is a separate one-time mechanical commit, done right after the fork, so upstream merges map + cleanly. See `docs/upstream-merge.md`: the xtask also rewrites `lightcraft_*`/`lightcraft-*` paths in incoming + upstream changes. + +### 0.2.3 Migration on rename + +On first start under a new `[identity]`, the app checks every `[legacy]` entry in order: + +- if a legacy settings folder exists and the new one does not, it **copies** the folder (never moves it) and writes a + `migrated-from` marker; +- it opens the legacy default library if no new one exists; +- it reads legacy preset extensions; +- it honours legacy env var prefixes, with a one-time deprecation log line. + +LightCraft itself is listed in `[legacy]`, so existing LightCraft users can switch with their settings and libraries. + +### 0.2.4 Enforcement + +- **`cargo xtask brand check`** (part of `cargo xtask ci`) fails if any of these appears outside `brand.toml`, + `[legacy]` handling, `ATTRIBUTION.md`, `docs/upstream-merge.md` or `CHANGELOG` history: + - the current `display_name`, `binary` or `env_prefix`; + - any legacy name (`LightCraft`, `lightcraft`, `LIGHTCRAFT_`, `ArtCraft`, `storyteller`). +- **A CI job builds with a throw-away brand** (`BRAND_FILE=xtask/test-brand.toml`, display name "Zzyzx Test") and + checks two things: + - The headless UI snapshots (LightCraft already captures every widget through the control channel) contain + "Zzyzx Test" and no other product name. + - Settings, logs and the default library go to Zzyzx paths. +- **Docs:** README and docs are written with the name in a `{{app}}` template where it matters. `cargo xtask docs` + renders them; prose elsewhere says "the app". + +**Done when:** +- Editing `display_name` in `brand.toml` and running `cargo xtask run` shows the new name in the title, menus, About, + logs path, CLI `--help`, MCP `serverInfo` and installer metadata, with **zero** source edits. +- The brand-check job is green. + +--- + +## 0.3 Remove upstream branding + +- Delete `docs/brand/` (ArtCraft trademarks, not open licensed), the README hero and badges, Discord links and the + "Crafting Apps" sections. +- Remove the `contributors/` and `assets/ATTRIBUTION.md` entries that only concern ArtCraft branding. +- Add our own placeholder `brand/icon.svg` and `brand/logo.svg` (original work) with attribution entries. +- Keep the upstream copyright notices in `NOTICE`/`LICENSE-*`; MIT and Apache require it. + +--- + +## 0.4 Apply the licence: MIT (PLAN.md §4) + +1. **`LICENSE`:** + - MIT text, with the copyright lines "the LightCraft contributors" and "the PhotoCraft contributors" for inherited + code, and "the project contributors" for new code; + - no product name. +2. **Remove `LICENSE-APACHE`** from the root and set `license = "MIT"` in `[workspace.package]`. +3. **Apache-2.0-only crates keep their licence:** + - `crates/segment` (ported Hugging Face SAM 3 code) and `crates/fetch` keep `license = "Apache-2.0"`, a local + copy of `LICENSE-APACHE` in each crate folder, and their `NOTICE` entries; + - Phase 1.7 writes the new `net` crate fresh under MIT instead of extending `fetch`. +4. **`NOTICE`:** keep the upstream attributions, the Hugging Face notice and third-party data attributions. +5. **Clean-room rules:** keep LightCraft's `AGENTS.md`/`CLAUDE.md` non-negotiables word for word and add: + - darktable and Ansel may be used **as running applications, manuals and prose design notes only**; + - their source trees in `../darktable` and `../ansel` are off-limits to agents, as are GPL data tables + (`noiseprofiles.json`, `wb_presets.json`, `colormatrices.c`, basecurves); + - camera matrices are never harvested from Adobe-converted DNGs (check the `Software` tag); camera-native DNGs are + fine; + - a "Sources" line in every PR that adds an algorithm (paper, prose spec, or "own design"). +6. **`cargo deny`** in CI, so a GPL dependency can't arrive silently: + - licences allowed: MIT, MIT-0, Apache-2.0 (incl. LLVM exception), BSD-2/3-Clause, ISC, Zlib, Unicode-3.0, CC0-1.0; + - everything else, including GPL, LGPL, AGPL and MPL, is denied. +7. **`assets/ATTRIBUTION.md` policy (unchanged):** CC-BY and CC-BY-SA are allowed only as separate data or asset + files, with attribution (for example the lensfun DB and GeoNames). + +--- + +## 0.5 Rebuild `plan/` and extend the tracker + +LightCraft's tracker ids point to a local `plan/` folder that wasn't published. + +1. Write `plan/` from scratch, **in our own words**: + - `lightroom-classic/` (feature catalog, menus, Classic shortcuts, per-module behaviour notes); + - `architecture.md` (PLAN.md §5); + - `STATUS.md`; + - `execution-plan.md` (these phase files). +2. Decide whether to keep `plan/` gitignored. Recommendation: **commit it**. The ignore rule only existed to keep + Adobe-observation notes local, so keep that one subfolder (`plan/observations/`) ignored. +3. Extend `docs/parity.md`: + - reopen the 🚫 Classic rows (KEYC-MODULES, the seven LRC-WEB rows, LRC-MAP-REVGEO); + - add rows for every PLAN.md §2 feature that has no row yet; + - fix the duplicated "Top gaps" list. +4. Add a new tracker section **"IMM. Immich integration"** with the rows below. They are worked through in Phases 1, + 3 and 4. `cargo xtask parity` counts them like any other row. + +| Id | Feature | Tier | Phase | +|---|---|---|---| +| IMM-CONNECT | Connect to one or more Immich servers (URL + API key), version check, secure key storage | P1 | 1 | +| IMM-LINK | Link catalog photos to Immich assets by checksum; "in Immich" badge and filter | P1 | 1 | +| IMM-IMPORT | Immich as an import source (browse albums/timeline, download originals or add as linked) | P1 | 1 | +| IMM-EXTLIB | Shared-originals mode: Immich external library and catalog over the same folders, no duplicate uploads | P1 | 1 | +| IMM-SHARELINK | Create Immich shared links for published albums (from Web/Slideshow/Publish) | P2 | 3 | +| IMM-PUBLISH | Immich publish service: collections → albums, renders and/or originals, re-publish, stacks | P1 | 4 | +| IMM-SYNC | Two-way metadata sync (rating, favourite, title/description, tags ↔ keywords, albums ↔ collections, GPS, time, archive) | P1 | 4 | +| IMM-PEOPLE | Import Immich people and face regions into People; push names back | P2 | 4 | +| IMM-SEARCH | Immich smart (CLIP) and metadata search from the Library filter bar | P2 | 4 | +| IMM-MCP | Immich commands available via CLI, control channel and MCP | P2 | 4 | + +5. Write `plan/immich.md`, the research note: + - Immich concepts (assets, checksums, albums, tags, people, stacks, external libraries, shared links, API keys + and permissions); + - the API endpoints we need, with the Immich release they were checked against; + - the minimum supported Immich version; + - how Immich's ratings and favourites behave. + - **Licence note:** the Immich server is AGPL-3.0. We only talk to it over HTTP and write our own client from its + public API documentation. We don't vendor its code or its generated SDK. +6. Add `xtask/immich/compose.yml`, a pinned Immich release for local and CI integration tests, plus + `cargo xtask immich up|down|seed`. The seed step loads a CC0 fixture set and creates an API key. + +--- + +## 0.6 Shared infrastructure + +- `craft-fonts` as the `CRAFT_FONTS_DIR` build input (CJK glyphs), and the raw corpus via `cargo xtask corpus`. +- Read and keep the never-crash standard (LightCraft's `AGENTS.md` already includes its substance; `craftrules` is + not needed at build time). + +--- + +## Exit gate + +- [ ] `cargo xtask ci` green under the configurable brand; brand-check job green with the throw-away brand. +- [ ] Renaming the product = editing `brand.toml` only (demonstrated in a PR that renames twice and back). +- [ ] Legacy LightCraft settings and library are picked up on first start. +- [ ] `plan/` exists; `docs/parity.md` contains Classic rows and IMM rows; `cargo xtask parity` prints the new totals. +- [ ] `cargo xtask immich up` starts a test server; licence policy enforced by `cargo deny`. diff --git a/PLAN_phase_1.md b/PLAN_phase_1.md new file mode 100644 index 0000000000..39608dffee --- /dev/null +++ b/PLAN_phase_1.md @@ -0,0 +1,251 @@ +# Phase 1: Classic shell, scalable catalog and Immich link + +Part of [PLAN.md](PLAN.md). **Estimate:** 50–85 agent-hours. **Depends on:** Phase 0. +**Unblocks:** Phases 2, 3 and 4. Those can run in parallel after this phase. + +**Goal:** the app *is* Lightroom Classic in structure: +- modules, Classic panels and keys; +- a catalog that holds 500k+ photos; +- true 1:1 zoom; +- network groundwork, so the catalog can be linked to an Immich server. + +The product name is never written in code; use `brand::` constants (Phase 0.2). + +--- + +## 1.1 Split the engine crate first (≈ 6–10 h) + +`crates/engine` is 45k lines and mixes import, export, catalog import, a SQLite reader, faces, denoise, segmentation, +presets and devices. Split it before new features land in it: + +| New crate | Takes | +|---|---| +| `engine-core` | command registry (`CommandSpec`), session, jobs, journal, undo | +| `engine-library` | import, devices, folders, collections, keywords, metadata, XMP, `.lrcat`/Luminar import | +| `engine-develop` | develop commands, presets, profiles, versions, sync, merge | +| `engine-export` | export, watermarks, naming templates, DNG writing | +| `engine` | thin facade that re-exports the above, so the UI, CLI, MCP and upstream merges keep compiling | + +- Update `xtask/src/layers.rs` with the new crates. +- **Done when:** behaviour is identical (all tests pass), and no file moves change command ids. + +--- + +## 1.2 Module system and panel framework (≈ 12–20 h) + +Today `ui-egui` has a `ViewMode` and a `RightPanel` enum (the cloud Lightroom layout). + +- **A `Module` trait:** + ```rust + trait Module { + fn id(&self) -> ModuleId; // Library, Develop, Map, Book, Slideshow, Print, Web + fn left_panels(&self) -> &[PanelId]; + fn right_panels(&self) -> &[PanelId]; + fn toolbar(&mut self, ui: &mut Ui, cx: &mut Cx); + fn center(&mut self, ui: &mut Ui, cx: &mut Cx); + fn keymap(&self) -> &Keymap; // module-local keys layered over global keys + } + ``` +- **Top bar:** + - identity plate on the left (text or image from `brand.logo_svg` by default, user-customisable); + - module picker on the right, with hide/show modules from its context menu; + - an activity/progress area. +- **Panel framework:** + - left, right, top and bottom (filmstrip) panel groups; + - collapsible panel headers; + - **solo mode** (opening one panel closes the others); + - auto hide and show per edge, with a manual override; + - Tab (side panels), ⇧Tab (all), F5–F8 (each edge), T (toolbar); + - panel order and visibility saved per module. +- **Screen modes:** normal, full screen with menu bar, full screen; **lights out** (dim/off, L). +- **Secondary window:** + - Grid, Loupe (Normal / Live / Locked), Compare, Survey, Slideshow; + - its own filmstrip and filter; + - the KEYC-SECONDWINDOW keys. +- **Re-home existing views:** + - Library: grid, loupe, compare, survey, people. + - Develop: detail view, all editing panels, reference view. + - Map, Book, Slideshow, Print and Web get placeholder modules ("coming in Phase 3"), so the picker is complete now. +- Every module, panel and screen mode is a command (`module.switch`, `panel.toggle`, …), reachable from MCP, the + control channel and the menus. + +**Done when:** switching modules keeps the selection and filmstrip; the panel state persists across restarts; +headless UI snapshots exist for each module. + +--- + +## 1.3 Classic keymap layer (≈ 3–5 h) + +- Add a keymap set called **"Classic"**, the default. LightCraft's current keys become a selectable alternative set. + - Module keys: + - G grid, E loupe, C compare, N survey, D develop; + - Ctrl+Alt+1…7 switch module; + - ⌘⌥↑ returns to the previous module. + - Rating and flag keys: + - `[` and `]` rating down and up; + - P/X/U flags and the backtick flag toggle; + - ⇧+key to set and advance (or Caps Lock auto-advance). + - Library and Develop keys: + - B target collection; + - Ctrl+Alt+0–9 keyword sets; + - ⇧⌘C and ⇧⌘V copy/paste metadata; + - R crop, Q remove, ⇧T masking, K brush, M linear, ⇧M radial. + - Help: F1 opens help; ⌘/ shows the shortcut overlay for the current module. +- Shortcut editor in Preferences (it reads the command registry, detects conflicts, and imports/exports a keymap + file). +- Tracker rows: all KEYC-* rows to ✅. + +--- + +## 1.4 Library module: Classic panels (≈ 10–16 h) + +| Panel / feature | Work | +|---|---| +| Navigator | Fit/Fill/1:1/custom zoom presets, click-to-pan, synced with the loupe | +| Catalog panel | All Photographs, **Quick Collection** (B, ⌘B show, ⌥⌘B clear, ⌘⇧B save as collection), Previous Import, Missing Photographs, Added by Previous Export | +| Folders | Volume headers with free space; add/move/rename/remove folders on disk (journaled, undoable); synchronise folder (new, missing, metadata changes); update location; show parent; show in file manager | +| Collections | Collection sets (nesting), **target collection**, smart collection rule editor parity (nested any/all groups, every metadata field), collection export/import | +| Quick Develop | Relative ± buttons for WB, exposure, contrast, highlights, shadows, whites, blacks, clarity, vibrance; presets; crop ratio; treatment | +| Keywording | Keyword tags as text, suggestions (co-occurrence), **keyword sets** (built-in and user), keyword shortcuts | +| Keyword List | Hierarchy, synonyms, include/exclude on export, person keywords, import/export of keyword text files, counts and filters | +| Metadata | Panel presets (Default, EXIF, IPTC, IPTC Extension, Location, Large Caption, Minimal); **metadata presets**; edit many; copy/paste metadata; edit capture time (shift, set, use file date) | +| Painter tool | Spray keywords, labels, flags, ratings, metadata preset, develop settings, rotation, target collection | +| Grid cells | Compact/expanded cell styles, badges (keywords, collections, edited, virtual copy, metadata conflict, **Immich linked**), index numbers | + +--- + +## 1.5 Catalog v4: scale, backup, multiple catalogs (≈ 12–20 h) + +Today the catalog is an op log plus a full JSON snapshot, held entirely in RAM (BTreeMaps of `Arc`). It works up +to about 85k photos. + +1. **Benchmark first.** `cargo xtask bench-catalog --photos 250000,1000000` measures open time, peak RSS, filter + latency, snapshot time and import throughput on the current design. Record the numbers in `docs/catalog.md`. +2. **New storage behind the same `catalog` API:** + - a pure-Rust embedded store (candidate `redb`, ACID with MVCC; decide from the benchmark); + - tables: photos, folders, collections, keywords, develop settings/history, previews index, **remote identities** + (1.7); + - secondary indexes for the filter bar's columns; + - photo records loaded lazily; the grid pages through ids; + - keep the op log as the undo journal and change feed (useful for sync in Phase 4). +3. **Migration:** v3 (LightCraft JSON) → v4 runs automatically, keeps a backup, and is tested on the 85k fixture. +4. **Catalog file:** one catalog = one folder with a `*.{brand.catalog_ext}` entry point. + - File → New/Open/Open Recent Catalog; + - a catalog chooser at startup (Alt held, or a preference). +5. **Backup:** schedule (on exit: daily/weekly/monthly/never), backup folder, integrity test, optimise (compaction plus + index rebuild). +6. **Export as Catalog / Import from Another Catalog:** subset with or without originals and previews; conflict rules + (new, changed: replace settings / metadata / keep), with a preview of changes. +7. **Metadata vs XMP:** a "changed on disk" / "changed in catalog" badge; Read Metadata from File / Save to File; + conflict dialog. + +**Done when:** 500k photos open in under 2 s, filter in under 100 ms, use under 2 GB RSS; 1M photos still usable; +the crash and fuzz tests are carried over. + +--- + +## 1.6 True 1:1 zoom and previews (≈ 6–10 h) + +- Generalise `ui-egui/src/region.rs` (it renders the on-screen window at zoom scale, but only for the loupe and + Before/After) to a **tiled region renderer**: + - used by loupe, compare, survey, reference view, soft proof and overlays; + - zoom levels Fit, Fill, 1:4, 1:3, 1:2, 1:1, 2:1, 3:1, 4:1, 8:1, 11:1; + - tiles cached per settings hash; + - the GPU path where available. +- Preview store: standard previews at a size set per catalog, 1:1 previews built on demand or at import, auto-discard + of 1:1 previews (day/week/month/never), and Library → Previews → Build/Discard commands. + +**Done when:** 1:1 pixels equal the full-resolution export pixels (test on corpus raws); panning at 1:1 on 45 MP +stays above 30 fps. + +--- + +## 1.7 Network groundwork (≈ 4–6 h) + +Immich in 1.8 and Phase 4, publish services, maps and model downloads all need this. + +- New L0 **`net` crate**, written fresh under **MIT**. `crates/fetch` is Apache-2.0 only (PLAN.md §4.1), so it is not + extended. It uses the same approach as `fetch`: rustls with the RustCrypto provider, pure Rust. It provides: + - methods GET/POST/PUT/PATCH/DELETE; + - JSON bodies (serde); + - **streaming multipart upload** with progress; + - streaming download (keeping the existing resume and SHA-256 logic); + - connect and stall timeouts, cancellation, redirects, gzip; + - optional HTTP proxy; + - `User-Agent` built from `brand::`; + - custom CA / self-signed certificates per connection (common on home Immich servers), with trust-on-first-use plus + fingerprint confirmation. + - `fetch` stays as it is for model downloads, or later becomes a thin Apache-2.0 wrapper over `net`. +- **`credentials` module:** secrets stored in the OS keychain where reachable in pure Rust: + - Linux Secret Service over D-Bus via `zbus`; + - macOS and Windows behind an isolated platform crate. + - Fallback: a file encrypted with a key derived from a user passphrase. + - Never write secrets into the catalog, settings, logs, MCP output or crash reports; add a test that greps the logs. +- **Connections settings pane:** Preferences → Connections lists accounts for Immich now, and publish services, map + tiles and geocoding later. +- **Catalog `remote_identity` table:** (photo_id, service, account_id, remote_id, remote_checksum, remote_updated_at, + last_synced_at, sync_state). Indexed both ways. This is where Immich links live. +- **Checksums at import:** + - compute **SHA-1** of each original, which is what Immich stores for its assets; + - compute it with the existing content hash in the same read pass; + - a background job back-fills SHA-1 for existing catalogs. + +--- + +## 1.8 Immich: connect, link, import (≈ 8–12 h) + +New crate **`immich`** (L3, depends on `net`, `catalog`): a typed client for the endpoints listed in `plan/immich.md`, +written by us from the public API docs. A version check refuses servers older than the minimum version, with a clear +message. + +1. **IMM-CONNECT:** + - Preferences → Connections → Add Immich server: URL, API key (with a link to the server's API-key page), Test + button; + - shows server version, user and the key's permissions; + - more than one server/account allowed; + - commands `immich.connect`, `immich.disconnect`, `immich.status`. +2. **IMM-LINK:** + - a background job lists the server's assets (paged, incremental by `updatedAt`); + - matches them to catalog photos by **SHA-1 checksum**; the fallback is original filename + capture time + file + size, marked "probable" so the user can confirm; + - writes `remote_identity` rows; + - results: + - grid badge "in Immich"; + - Library filter "Immich: linked / not linked / probable"; + - Metadata panel field with an "Open in Immich" link to the asset's web URL; + - a smart-collection criterion. +3. **IMM-IMPORT:** + - the Import dialog gets an **Immich** source: browse the timeline, albums, people and favourites as thumbnails + loaded from the server; + - choose **Copy** (download originals into a dated destination folder, then import normally) or **Link only** + (catalog entry with remote preview; the original is downloaded on first Develop); + - Immich rating, favourite, description, tags, albums and GPS are taken into catalog metadata on import (mapping as + in Phase 4 IMM-SYNC; one-way at this stage); + - duplicates are skipped by checksum. +4. **IMM-EXTLIB** (shared originals, the recommended setup for self-hosters): + - when Immich indexes the same folders as an *external library*, the link uses the checksum, never an upload; + - a setup helper shows which catalog folders are covered by which Immich external library (path mapping table for + container paths such as `/mnt/photos` ↔ `/home/me/Photos`); + - writes XMP sidecars so Immich picks up ratings, descriptions and keywords on its next scan. Phase 4 adds direct + API sync. +5. **Tests:** + - unit tests against recorded HTTP fixtures; + - integration tests against `cargo xtask immich up`, run as a nightly CI job rather than on every PR, because it + needs Docker; + - error paths: offline server, bad key, TLS mismatch and HTTP 5xx. None may crash; each must give a clear error and + a retry option. + +--- + +## Exit gate + +- [ ] Engine split; layering check green; command ids unchanged. +- [ ] All seven modules in the picker (Library and Develop complete, others placeholders); panel framework, screen + modes and secondary window done; Classic keymap default; shortcut editor. +- [ ] Library Classic panels ✅ in tracker (Navigator, Catalog, Folders, Collections, Quick Develop, Keywording, + Keyword List, Metadata, Painter). +- [ ] Catalog v4: 500k under 2 s open, under 100 ms filter; backup and optimise; multiple catalogs; export/import + catalog. +- [ ] 1:1 zoom pixel-equal to export. +- [ ] `net` and `credentials` in place; IMM-CONNECT, IMM-LINK, IMM-IMPORT and IMM-EXTLIB ✅ against the pinned Immich + test server. diff --git a/PLAN_phase_2.md b/PLAN_phase_2.md new file mode 100644 index 0000000000..85167b2b69 --- /dev/null +++ b/PLAN_phase_2.md @@ -0,0 +1,231 @@ +# Phase 2: Image quality and camera coverage + +Part of [PLAN.md](PLAN.md). **Estimate:** 110–180 agent-hours, partly data collection. The project is MIT, so +all camera data is measured or reverse-engineered by us (PLAN.md §4). **Depends on:** Phase 1 (engine split and the 1:1 region renderer). +**Runs in parallel with:** Phases 3 and 4. + +**Goal:** a photographer opening their own raws sees **correct colour**, **correct lens geometry** and +**Lightroom-grade detail**, on nearly every camera they own. This is the gap that decides whether people switch. + +Clean-room rules hold throughout (PLAN.md §4.2): +- No Adobe matrices, DCP, LCP, presets or profiles. +- No darktable, Ansel, rawspeed, LibRaw or lensfun source or GPL data tables. +- Each data source is recorded in `docs/sources.md` with its licence and how it was obtained. + +--- + +## 2.1 `camdb` crate: per-camera data (≈ 15–30 h) + +**Contents per camera model** (keyed by make, model and the EXIF unique model id): +- colour matrices for two illuminants; +- forward matrices when known; +- white-balance presets; +- noise profile (Poisson-Gaussian a/b per ISO per channel); +- black and white levels; +- default crop and masked areas; +- CFA layout; +- aliases (marketing names, regional variants). + +**Format:** a compact binary table generated at build time from human-editable TOML in `data/cameras/`, lazily +loaded. One file per maker. + +**Sources, in priority order:** +1. **Data the file carries itself:** + - DNG ColorMatrix/ForwardMatrix at runtime; + - Olympus and Pentax maker-note matrices; + - **camera-native DNGs** (Leica, Pentax, Ricoh, Hasselblad, phones; checked via the `Software` tag, never from + Adobe-converted DNGs) can seed `camdb` entries. +2. **Our own chart calibration** (2.2). This is the main source of "measured" entries. +3. **Measured by our tools from raw files:** + - **WB presets** read from each maker's own maker notes (many bodies store multipliers for every preset), via + `xtask camdb-harvest` over the CC0 corpus; + - **black and white levels, crops, CFA layout** from the files and our decoders; + - **noise profiles**: + - `app-cli noise-profile` fits a Poisson-Gaussian model (a, b per channel) from an ISO series of a defocused + flat target; + - the same model can also be estimated automatically from flat regions of ordinary corpus raws, as a fallback. +4. **LightCraft's per-file embedded-JPEG fit**, which already exists. It is the fallback when nothing above has the + model, and is marked "estimated" in the Info panel. + +Entries record provenance (`source = "chart" | "native-dng" | "maker-note" | "estimated"`) and the contributor. + +**Pipeline use:** +- the input transform chooses the matrix by illuminant (interpolating by CCT between the two); +- WB presets fill the white-balance menu; +- noise profiles feed 2.6. + +**Done when:** every corpus camera resolves to a `camdb` entry or an explicit "estimated"; no camera falls back to +the neutral matrix silently. + +--- + +## 2.2 Own camera calibration tool (≈ 8–12 h) + +- `app-cli calibrate` takes a chart shot (ColorChecker 24 in its 2000 and 2014 versions, ColorChecker SG, IT8.7/2), + either auto-detected or with corners picked by the user. +- It fits a 3×3 matrix (least squares on ΔE2000) and an optional 2.5D hue/sat LUT (thin-plate spline, the method + darktable manual describes; implemented from that description, not from its code). +- Output is a TOML `camdb` entry or a user camera profile. +- Reference chart values come from published CIE/manufacturer data. CIE observer and illuminant tables are public + data. +- A UI wizard in Develop → Profile → Calibrate Camera… gives users their own profiles. +- **Community data pipeline.** This is on the critical path, because there are no GPL tables to fall back on: + - a documented kit: which chart, lighting, ISO series, flat field and lens grid; + - `app-cli contribute` packages the shots plus EXIF and a CC0 licence statement; + - an upload target (Git LFS repo or object store); + - a CI job re-fits submitted data and opens a PR with the new `camdb`/`lensdb` entries. +- **Priority:** the 50 most-used bodies, from public usage statistics, get a chart shot even if the maintainers have + to buy or rent time on them. + +--- + +## 2.3 Camera-matching profiles (≈ 6–10 h) + +- For each supported maker, generate "Camera Standard / Portrait / Landscape / Neutral / Vivid"-style **looks** by + fitting our pipeline to the camera's own JPEGs: tone curve plus a 3D LUT in our profile format. +- Use LightCraft's existing fitter (`docs/camera-preview-colour.md`) on many shots per body, not per file. +- Store them as our own profiles in `data/profiles//`, and list them in the profile browser under "Camera + Matching". + +--- + +## 2.4 Raw decoders: coverage (≈ 25–60 h) + +| Item | Today | Work | +|---|---|---| +| Canon CR3: all CRX variants, sRAW/mRAW, dual-pixel | lossless and C-RAW verified on M50/R100/R8 only | every CRX variant and subsampled RAW; verify on ≥ 20 bodies | +| Olympus/OM compressed ORF | preview only | decoder | +| Samsung compressed SRW | preview only | decoder | +| Nikon lossy-after-split NEF | preview only | decoder; also NEFs labelled compressed but stored uncompressed | +| Long tail | none | 3FR/FFF (Hasselblad), IIQ (Phase One), MOS (Leaf), ERF (Epson), KDC/DCR (Kodak), MRW (Minolta), NRW, SRF/SR2, X3F if feasible | +| HEIC/HEIF, AVIF import | HEIC behind a feature flag | default-on HEIC decode (pure-Rust HEVC, shared `heif` crate), AVIF decode | + +- **Method: clean-room only.** Use LightCraft's black-box analysis (as for compressed NEF and RW2) and prose format + descriptions. Never LibRaw, rawspeed or dcraw source. Each decoder documents its analysis in the module docs, as + `vendor/rw2.rs` does. +- **Risk:** LightCraft rates this "high, 40–80 h". The budget covers the common formats first; the long tail falls back + to embedded previews until done. +- **Corpus:** + - one CC0 sample per model from raw.pixls.us in `cargo xtask corpus`; + - `crates/raw/tests/corpus.rs` checks per model: sensor decode (not preview), plausible levels, colour sanity + against the camera JPEG (median ΔE threshold); + - a coverage report in `docs/cameras.md` is generated by xtask. + +--- + +## 2.5 `lensdb` crate: lens corrections (≈ 10–18 h) + +- **lensfun database** (CC-BY-SA 3.0, ~1,500 lenses), used as **data only**. lensfun's LGPL library code is never read; + the correction models are implemented from their published mathematical descriptions. + - Shipped as a **separate data file**, not compiled into the binary, so the MIT code stays separate from the + CC-BY-SA data. It is converted at packaging time into a compact, lazily loaded table (Ansel's notes measured about + 100 ms just to parse lensfun's XML). + - It can also be downloaded or updated at runtime from upstream. + - Attribution and the CC-BY-SA terms go in `ATTRIBUTION.md`; edits we make to that data stay CC-BY-SA in + `data/lenses/` and are offered back upstream. + - Our **own** measured profiles (below) are CC0 and kept in a separate file. +- **Lookup:** EXIF lens id, lens model string, focal length and aperture, with crop-factor handling and mount + filtering. Users can pick manually from make/model menus (the Lens Corrections → Profile UI). +- **Models:** + - distortion: poly3, poly5, PTLens; + - TCA: linear, poly3; + - vignetting: pa model. + - Applied in the existing geometry stage with a single resample. + - Amount sliders for distortion and vignetting. +- **Our own profiles:** `app-cli lens-calibrate` with distortion from straight-line or grid shots, vignetting from flat + fields and TCA from edges, writing `data/lenses/` entries. Users can save custom profiles. +- **Done when:** a profile is found for ≥ 80% of lens EXIFs in the corpus; straight lines stay straight within 0.5 px + on test charts. + +--- + +## 2.6 Detail: noise reduction, sharpening, Enhance (≈ 12–25 h) + +- **Profiled classical NR:** + - use the `camdb` noise profiles (a variance-stabilising transform, then wavelet/non-local-means denoise in the + stabilised domain); + - keep the Luminance/Detail/Contrast and Color/Detail/Smoothness controls as they are; + - run colour NR at half resolution on both CPU and GPU (an open LightCraft M5 item). +- **AI Denoise:** + - LightCraft has Bayer-only inference with **opt-in GPL weights** that the user downloads separately; they are never + bundled with the MIT app. The goal is our own CC0/MIT weights. + - Follow the **design described in Ansel's prose note** `doc/rawdenoiseai.md` (not its code): a small U-Net + conditioned on a per-pixel sigma map from the noise profile, deterministic, no external runtime. + - Extend it to X-Trans and linear DNG. + - Output, as Lightroom does: a new DNG stacked with the original, plus Amount. + - Weights: train our own on CC0 / own pairs (preferred), or choose a permissively licensed model. That is an owner + decision shared with Phase 5. +- **Raw Details:** better demosaic with reduced false colour and artifacts; offer the demosaic choice (AHD, PPG, and + later RCD/AMaZE-class) as an "Enhance" output. +- **Super Resolution (2×):** classical edge-directed upscaling first; an ML model later (Phase 5). +- Sharpening keeps its masking preview (Alt-drag) at true 1:1, which Phase 1.6 makes possible. + +--- + +## 2.7 Remove tool: content-aware (≈ 6–10 h) + +- Port PhotoCraft: + - `algo/src/inpaint.rs`: multi-scale Wexler EM with PatchMatch NNF and `best_offset`; + - `algo/src/content_aware.rs`: restricted sampling area, rotation/scale/mirror adaptation, Poisson colour + adaptation. +- Put them in a new L2 **`inpaint`** crate and copy-rename them as LightCraft did with `heif`. +- Make it resolution independent: + - store strokes in normalised coordinates; + - synthesise at preview scale for interaction and at full scale for export; + - cache results per stroke hash. +- **Spot pin editing:** drag the source, change the size, switch Remove/Heal/Clone, feather and opacity. +- **Detect (dust spots):** + - a "Visualize Spots" threshold already exists; + - add automatic spot detection as a sensor-dust finder: same position across photos from one body, low-contrast + blobs; + - add sync of spots across a selection. + +--- + +## 2.8 Render fidelity suite (≈ 8–14 h) + +- **References:** renders made by the maintainer's own Lightroom Classic copy, from CC0 raws, with settings sweeps. + - They are stored **locally only** (never committed) in `plan/observations/fidelity/`. + - The reference pixels themselves are never shipped. +- **Metrics:** ΔE2000 (mean, p95), SSIM, histogram distance, and highlight-clipping location per sweep step. +- **Tuning targets, in order:** + 1. default rendering; + 2. exposure, highlights, shadows, whites, blacks; + 3. texture, clarity, dehaze; + 4. NR and sharpening; + 5. vignette and grain. +- **Decide tone-curve placement.** LightCraft applies curves after display encoding; compare against reference + behaviour and move the stage if needed, behind a process-version bump so old edits render unchanged. +- **CI:** a small public subset compared against *our own* golden renders, which guards against regressions. + +--- + +## 2.9 Soft proofing with real ICC (≈ 6–10 h) + +- Port PhotoCraft's **`cms`**: pure-Rust ICC v2/v4 parse and write, LUT profiles including CMYK↔Lab, rendering + intents, black point compensation, gamut check. + - Replace or complement `moxcms` for output transforms. + - Keep one CMS path, so the preview equals the export. +- **Soft proof:** + - choose any installed or added printer/paper ICC; + - Perceptual or Relative intent; + - **Simulate Paper & Ink** (paper white plus black point); + - monitor and destination **gamut warnings**; + - "Create Proof Copy" (a virtual copy). + - Before/after shows proof against the original. +- **Display profile:** read the OS monitor profile (ICC from the platform, via an isolated crate if FFI is needed) and + render through it. +- **Done when:** proofing through a known profile matches a reference transform within ΔE 1. Print (Phase 3) uses the + same code. + +--- + +## Exit gate + +- [ ] ≥ 95% of corpus camera models decode from sensor data; coverage report generated. +- [ ] Median ΔE2000 ≤ 2 against camera JPEGs (camera-matching profile) for supported bodies; no silent neutral-matrix + fallback. +- [ ] Lens profile found for ≥ 80% of corpus lens EXIFs. +- [ ] Content-aware Remove ✅, spot editing ✅, dust detection ✅. +- [ ] Fidelity suite runs; default rendering mean ΔE2000 ≤ 3 against the local references. +- [ ] Soft proofing with printer ICC and Simulate Paper & Ink ✅. diff --git a/PLAN_phase_3.md b/PLAN_phase_3.md new file mode 100644 index 0000000000..cd12435bfb --- /dev/null +++ b/PLAN_phase_3.md @@ -0,0 +1,189 @@ +# Phase 3: Output modules (Print, Map, Slideshow, Book, Web) + +Part of [PLAN.md](PLAN.md). **Estimate:** 72–124 agent-hours. **Depends on:** Phase 1 (module system). +Print also needs Phase 2.9 (`cms`); until then it uses the existing output-space transform. +**Runs in parallel with:** Phases 2 and 4. + +**Goal:** every Lightroom Classic output module works end to end, sharing one layout and text engine and one PDF +writer. + +Functional references: the darktable application's map, print, slideshow and tethering views, its web-gallery and +photo-book exports, and its user manual. Use them as **running applications and documentation only**; their source +is never read (MIT clean-room, PLAN.md §4.2). + +--- + +## 3.1 Shared foundations (≈ 15–25 h) + +| Crate | Layer | Contents | +|---|---|---| +| `text` | L1 | **Port of PhotoCraft `text`**: font database, parley shaping (complex scripts), skrifa, CJK/vertical, craft-fonts loading. Replaces LightCraft's ab_glyph watermark renderer, and the export watermarks use it too | +| `pdf` | L1 | **New** PDF 1.7 writer: multi-page, TrueType/OpenType **subsetting and embedding**, images (JPEG passthrough, Flate 8/16-bit), ICC-based colour spaces and **OutputIntent**, page boxes (media/bleed/trim), vector paths for guides and crop marks, metadata. PhotoCraft's single-page `print_cmds.rs` writer is a starting point for crop and registration marks only | +| `layout` | L3 | Page model shared by Print, Book, Slideshow and Web: page size, margins, bleed; **cells** (photo cell with fit/fill, zoom, pan and rotate; text cell; graphic cell); grids and packages; guides; snapping; **templates** (serde, user-saveable, built-ins we design); token text (`{Title}`, `{Caption}`, `{Filename}`, `{Date}`, `{Exposure}`, …, shared with the export naming templates) | +| `ui` widgets | L5 | Page canvas with zoom, rulers, guides, cell handles and drag-and-drop from the filmstrip; template browser with live previews; text style panel | + +- A **"saved creation"** catalog object type (Saved Print / Book / Slideshow / Web Gallery) is stored as a special + collection with the layout document attached, so it appears in the Collections panel exactly as in Classic. +- All of it is reachable as commands (`print.*`, `book.*`, …) for MCP and CLI. `app-cli print --template … + --collection …` renders headless. + +--- + +## 3.2 Print module (≈ 14–22 h) + +- **Layout styles:** + - Single Image / Contact Sheet (grid: rows, columns, spacing, cell size, keep square); + - Picture Package (fixed cell sizes, auto layout, new page); + - Custom Package (free cells, anchor, lock to photo aspect ratio). +- **Image settings:** zoom to fill, rotate to fit, repeat one photo per page, stroke border, inner stroke. +- **Guides:** rulers, page bleed, margins and gutters, image cells, dimensions. +- **Page:** + - page background colour; + - identity plate (with rotation, opacity, render on every image); + - watermark (shared with export); + - page options (page numbers, page info, crop marks); + - photo info tokens; + - font size. +- **Print job:** + - to printer, JPEG file or **PDF file**; + - draft mode (uses previews); + - print resolution; + - print sharpening (Low/Standard/High × Matte/Glossy); + - 16-bit output; + - colour management: printer-managed or a chosen ICC profile with Perceptual/Relative intent and BPC (`cms`), plus + a Print Adjustment brightness/contrast compensation. +- **OS printing:** + - Linux and macOS: **IPP to CUPS** in pure Rust. Send the rendered PDF or raster; query printer media sizes and + margins for the page-setup dialog. + - Windows: the Win32 print spooler in an isolated `platform-print` crate (the only `unsafe` here, documented in + AGENTS.md as `sysmem` is). PDF/JPEG output always works. +- Page Setup, Print, Print One; templates (built-ins and user); saved prints. + +**Done when:** +- A 2×2 contact sheet, a picture package and a custom layout print to PDF with embedded fonts and the correct ICC + OutputIntent. +- A CUPS test printer (`cups-pdf` in CI) receives the job. +- Measured colour through a profile is within ΔE 1 of the soft proof. + +--- + +## 3.3 Map module (≈ 12–20 h) + +- **New crate `geo`** (L3): + - Web-Mercator tiles: fetch through `net`, disk cache with size limit and expiry; + - **configurable tile servers**: OpenStreetMap default, respecting its tile usage policy (User-Agent from `brand::`, + attribution shown, no bulk prefetch), plus user-added XYZ servers, satellite and terrain; + - clustering (grid-based, zoom-dependent); + - GPX/KML/GeoJSON track parsing (GPX already exists); + - saved locations (centre, radius, private flag). +- **Map view (egui):** + - smooth zoom/pan, style picker, search box (geocoding); + - pins and clusters with hover previews; + - multi-select; + - **drag photos from the filmstrip onto the map to geotag**, and drag pins to move them. +- **Tracklogs:** + - load, show and choose tracks; + - time-zone offset; + - **Auto-tag selected photos**; set the offset by matching one photo to a known position. +- **Saved Locations panel:** create from the map, radius circle, **private** flag (GPS stripped on export of photos + inside it), photo counts. +- **Location filter bar:** visible on map, tagged, untagged, by saved location. +- **Reverse geocoding** (fills Sublocation/City/State/Country/ISO code): + - opt-in, with a choice of provider: an online Nominatim-compatible endpoint with rate limits, or an **offline + GeoNames** cities dataset (CC-BY 4.0), downloaded on request and attributed; + - never sends anything without consent. +- If Immich is connected, an option shows Immich-only assets (linked but not in the catalog) as ghost pins. Off by + default. + +--- + +## 3.4 Slideshow module (≈ 10–16 h) + +- **Options:** zoom to fill, stroke border, cast shadow (opacity, offset, radius, angle). +- **Layout:** guides, margins (linked or independent), aspect preview (screen, 16:9, 4:3). +- **Overlays:** identity plate, rating stars, watermark, text overlays with tokens (positioned and anchored to the + photo), shadow on text. +- **Backdrop:** colour wash with angle, background image with opacity, background colour. +- **Titles:** intro and ending screens with colour and identity plate. +- **Playback:** + - manual or automatic; slide and fade durations; + - colour fade; random order; repeat; + - **pan and zoom** (Ken Burns, amount); + - quality (draft or full). +- **Music:** + - several tracks; + - **fit slide durations to the music**; + - volume and balance. + - Decode with `symphonia` (pure Rust: MP3, AAC, FLAC, Vorbis, WAV). Output with `cpal`; on Linux this links the + system ALSA library, so accept that and document it, or add a pure-Rust PipeWire/Pulse backend later. +- **Export:** + - PDF slideshow; + - JPEG sequence; + - **video**: AV1 in MP4/WebM with pure-Rust `rav1e` encode and Opus/FLAC audio. + - H.264 MP4 depends on the Phase 5 video decision, where an OS encoder is an option. +- Templates and saved slideshows; preview in the content area; full-screen play on the main or secondary display. + +--- + +## 3.5 Book module (≈ 12–20 h) + +- **Book settings:** + - book types **PDF** and **JPEG** (Blurb ordering is a proprietary service and out of scope); + - sizes (small square, standard landscape/portrait, large landscape, letter, A4, custom); + - cover type (hardcover, softcover, none); + - paper type as a note; + - JPEG quality, colour profile, file resolution, sharpening. +- **Auto Layout:** presets (one photo per page, left blank, with text, fill), "Auto Layout" and "Clear Layout". +- **Page:** page templates by photo count (1–4+, with or without text); favourite templates; add page or blank; page + numbers (position, display, apply to all). +- **Guides:** page bleed, text safe area, photo cells, filler text. +- **Cells:** padding (linked or per side), zoom and pan inside the cell, swap photos by dragging. +- **Text:** + - photo text (tokens or custom, offset); + - page text; + - **Type panel**: font, style, size, opacity, colour, tracking, baseline, leading, kerning, columns, gutter, + alignment; + - text style presets. + - Uses the `text` crate. +- **Background:** apply to all pages, graphic or photo with opacity, colour. +- **Views:** multi-page, spread, single page, zoomed page. +- **Export:** a PDF with embedded fonts and ICC (one file, cover plus pages, spreads as single pages) or a JPEG per + page. +- Saved books. + +--- + +## 3.6 Web module (≈ 8–14 h) + +- **Gallery templates** we write ourselves: grid, square, track and a single-image viewer. They are static + HTML/CSS/minimal JS with no external CDN, responsive, with keyboard navigation and accessible alt text from the + captions. +- **Panels:** + - Site Info: title, collection title and description, contact, web or mail link; + - Colour Palette; + - Appearance: grid size, cell numbers, photo borders, image page size; + - Image Info: title and caption tokens; + - Output Settings: large image size, quality, metadata (all / copyright only), watermark, sharpening. +- **Preview:** live in-app preview of the rendered HTML. +- **Output:** export to a folder, or **upload** via **SFTP** (pure-Rust `russh`/`russh-sftp`); plain FTP is optional + and off by default. Upload server presets with credentials in the keychain (Phase 1.7). +- **IMM-SHARELINK:** as an alternative output, "Share via Immich": + - upload the gallery's photos to an Immich album (Phase 4 IMM-PUBLISH); + - create an **Immich shared link** with expiry, password, allow-download and show-metadata options; + - copy the URL. + - The same action is offered in Slideshow (share the selection) and in the Publish Services context menu. +- Saved web galleries. + +--- + +## Exit gate + +- [ ] `text`, `pdf` and `layout` crates done, with golden PDF tests (rasterised compare) and font-embedding checks. +- [ ] Print: all three layout styles, colour-managed PDF/JPEG/printer output; CUPS CI job green. +- [ ] Map: tiles, pins/clusters, drag-to-geotag, tracklogs, saved locations with privacy, location filter, opt-in + reverse geocoding. +- [ ] Slideshow: templates, overlays, music sync, PDF/JPEG/AV1 video export. +- [ ] Book: auto layout, templates, text, PDF/JPEG export. +- [ ] Web: templates, live preview, folder and SFTP output; Immich shared link (IMM-SHARELINK ✅). +- [ ] Saved creations appear in Collections; every module scriptable via MCP. +- [ ] All LRC-PRINT/MAP/SS/BOOK/WEB tracker rows ✅. diff --git a/PLAN_phase_4.md b/PLAN_phase_4.md new file mode 100644 index 0000000000..e94845c5fa --- /dev/null +++ b/PLAN_phase_4.md @@ -0,0 +1,217 @@ +# Phase 4: Workflow power features and full Immich integration + +Part of [PLAN.md](PLAN.md). **Estimate:** 60–105 agent-hours (including about 20–35 h of Immich work). +**Depends on:** Phase 1 (catalog v4, `net`, `credentials`, the `immich` crate and links). +**Runs in parallel with:** Phases 2 and 3. + +**Goal:** +- the workflow features power users rely on: tethering, publish services, plugins, round trips, actions, people and + catalog migration; +- **two-way integration with Immich**, so the desktop catalog and a self-hosted Immich server stay one library. + +--- + +## 4.1 Tethered capture (≈ 10–16 h) + +1. **Studio capture first** (the design described in Ansel's prose note `doc/studio-capture.md`): watch a folder written by any vendor tool or the camera's own app; + auto-import with: + - a develop preset; + - a metadata preset and keywords; + - a session name and naming template; + - a target collection. + The newest shot shows in the loupe automatically. +2. **Native tethering**, new crate `tether`: + - PTP over USB with `nusb` (pure Rust), plus PTP/IP over Wi-Fi; + - vendor extensions for Canon, Nikon, Sony and Fujifilm, in that order; + - capture, download-on-capture, delete-from-card option. +3. **Tether bar** (as in Classic): camera name, shutter, aperture, ISO and WB readouts and settings; capture button; + develop settings "same as previous"; **live view** where the camera supports it. +4. Platform notes: + - Linux needs a udev rule (shipped in packages). + - macOS: release the camera from `ptpcamerad`. + - Windows: WinUSB driver notes. + - Unsupported cameras fall back to studio capture with a clear message. + +**Done when:** studio capture works with any camera; native capture is verified on at least one Canon, Nikon and Sony +body; CI uses a simulated PTP device. + +--- + +## 4.2 Publish services framework (≈ 8–12 h) + +- **Model:** + - a *publish service* (type plus account plus export settings) contains **published collections** and sets; + - each photo has a state: *new to publish*, *modified to re-publish*, *published*, *deleted to remove*; + - remote ids are stored in `remote_identity` (Phase 1.7); + - the modified state comes from the develop/metadata change feed (the catalog op log). +- **UI:** + - Publish Services panel in Library; + - the Publish button; + - the grid split into New / Modified / Published sections; + - "Mark as Up-to-date"; + - remote comments and likes where the service supports them. + - This closes LRC-LIB-COMMENTS for services that have them. +- **Built-in services:** + - **Hard Drive** (export to a folder kept in sync); + - **Immich** (4.6); + - **SFTP** (reuses Phase 3.6). +- Other services (Flickr, SmugMug, Piwigo, Nextcloud, PhotoPrism, WebDAV) come as **plugins** (4.3). + +--- + +## 4.3 Plugin SDK (≈ 10–16 h) + +- **Sandbox:** port PhotoCraft's `plugins` crate (`wasmi`, no host imports by default, fuel and memory limits). +- **Host API, versioned and capability-gated:** + - catalog query (read); + - metadata read/write in a plugin-owned namespace, plus standard fields with permission; + - **export post-process hooks**; + - **publish service provider interface** (the same trait the built-in services implement); + - metadata/keyword providers; + - menu commands that register as engine commands; + - simple dialogs from a declarative UI description. +- **Permissions:** + - network per host; + - filesystem roots; + - granted on install and revocable in the Plugin Manager. +- **Plugin Manager:** install, enable, disable, update, view logs. +- **SDK:** Rust crate plus template, docs and two example plugins (a WebDAV publisher and a metadata reverse-lookup). +- Lightroom's Lua plugins are not supported, and no promise is made to support them. + +--- + +## 4.4 Edit In and the PhotoCraft round trip (≈ 5–8 h) + +- External editor presets (app, file format, colour space, bit depth, resolution, compression, stack with original, + naming). +- **PhotoCraft integration:** + - "Edit in PhotoCraft" sends TIFF or **layered PSD** using PhotoCraft's `psd` writer (ported). "Open as Layers" + builds a layered PSD from the selection. + - When the file is saved, it is re-imported and stacked with the original; the edit-in round trip keeps metadata. + - If PhotoCraft runs with `--control`, the two apps can talk directly over the control channel: open, and notify on + save. +- PSD/PSB **import** uses the PhotoCraft `psd` reader (flattened composite plus layer metadata). + +--- + +## 4.5 Actions, people, migration (≈ 10–18 h) + +- **Actions:** + - record a sequence of engine commands (built on PhotoCraft's `actions_cmds` design and our journal); + - parameterise it, save it, assign a shortcut, run it on a selection; + - also exposed through MCP and the CLI (`app-cli run-action`). +- **People:** + - face clusters with separators and confidence; + - merge and split; + - small-face detection on large images (tiled detection beyond 640 px); + - **write face regions to XMP** (MWG Regions) and read them back; + - person keywords. +- **`.lrcat` migration v2:** + - replay develop history and snapshots; + - a profile mapping table (Adobe profile names → our camera-matching/creative profiles from Phase 2.3); + - masks (brush, linear, radial, range) and spot/heal; + - a per-photo **fidelity report** listing what could not be mapped; + - publish-service collections imported as plain collections. + - Mapping is derived from the published XMP `crs:` field descriptions and from our own measurements: apply known + values in Lightroom, export, compare (the local fidelity references of Phase 2.8). darktable's importer is + **not** read (MIT clean-room). + +--- + +## 4.6 Immich: full two-way integration (≈ 20–35 h) + +Builds on Phase 1.8: connection, link by checksum, import, shared originals. Every Immich action is a command +(`immich.*`), so it works from the UI, CLI, control channel and MCP (**IMM-MCP**). + +### 4.6.1 IMM-PUBLISH: Immich as a publish service + +- An **"Immich" publish service** per connected account. Published collections map 1:1 to **Immich albums** (created + if missing, renamed if the collection is renamed). Collection sets map to album name prefixes. +- **What is sent**, per service: + 1. **Rendered** JPEG/AVIF/JXL using the export settings, so Immich shows the edited look; or + 2. **Original** (plus XMP sidecar); or + 3. **Both, stacked in Immich**, with the render on top and the original underneath, using Immich's stack feature. +- **Upload:** + - streaming multipart upload with progress and resume-on-failure (via `net`); + - a stable device asset id (catalog photo id plus virtual-copy id); + - **checksum pre-check before upload**, so Immich never stores a duplicate; already-present assets are just linked + and added to the album. +- **Re-publish:** edits mark photos *modified*; re-publishing replaces the rendered asset in place (keeping its id, + albums and favourites where the API allows), otherwise uploads a new asset, moves album membership and trashes the + old one. +- **Removal:** removing from a published collection removes the photo from the album. Deleting the Immich asset is a + separate, explicit option (default **off**); assets go to the Immich trash, never a hard delete. +- **Shared-originals mode** (IMM-EXTLIB): for originals already in an Immich external library, publish only changes + album membership and metadata; nothing is uploaded except renders, if chosen. + +### 4.6.2 IMM-SYNC: two-way metadata sync + +- **Per-field opt-in mapping**, with defaults: + +| Catalog | Immich | Default | +|---|---|---| +| Star rating 0–5 | asset rating | two-way | +| Pick flag | favourite | two-way (configurable: favourite ↔ pick, or favourite ↔ 5★, or off) | +| Reject flag | archived | off (configurable) | +| Title / Caption | description | two-way (caption ↔ description; title optional) | +| Keywords (hierarchical) | tags (hierarchical, `A/B/C`) | two-way; export-excluded keywords never sent | +| Collections | albums | two-way for linked collections only | +| GPS, capture date/time | asset location and date | two-way, with a conflict prompt | +| People names / face regions | people / faces | see IMM-PEOPLE | +| Deleted photo | trashed asset | **never automatic**; a queue for the user to confirm | + +- **Change detection:** + - local changes come from the catalog op log since `last_synced_at`; + - remote changes come from incremental queries (`updatedAfter` or the server's sync stream, depending on the pinned + Immich API version in `plan/immich.md`). +- **Conflicts** (both sides changed since the last sync): + - a per-field policy: catalog wins, Immich wins, or newest wins (the default); + - a Sync Conflicts view that shows both values for anything unresolved. +- **Scheduling:** manual, on publish, or a background interval. It runs offline-safe: queued and retried with + backoff, and it never blocks the UI. +- Activity log entries for every sync run; a dry-run mode shows what would change. + +### 4.6.3 IMM-PEOPLE + +- Import Immich **people** (names, birthdates, hidden flag) and **face regions** (bounding boxes) for linked assets + into the People view. They are marked "from Immich" and can be confirmed or corrected. +- Push names assigned in the app back to Immich people (opt-in); merges map to Immich person merges. +- This gives good face recognition **before Phase 5**, by reusing Immich's own machine learning. + +### 4.6.4 IMM-SEARCH + +- The Library filter bar and the Text filter get an **"Immich smart search"** mode: a natural-language query (Immich's + CLIP search) returns asset ids, which are mapped to linked catalog photos. The results show as a temporary + collection that can be saved as a collection. +- Also: metadata search (OCR text, objects, places) when the server supports it. +- This stands in for local AI search (FILT-SEARCH-AI) until Phase 5, and can coexist with it later. + +### 4.6.5 Hardening and tests + +- **Version policy:** support the pinned minimum Immich release and the latest release. A nightly CI job runs + integration tests against both through `cargo xtask immich up --version …`. +- **Scale:** sync of 100k assets completes, resumes after interruption and stays under 5% CPU when idle. +- **Failure:** + - server down, key revoked, permission missing, TLS change: each gives a clear error, nothing is lost, and work is + queued; + - never crash, as the never-crash standard requires; fuzz the JSON decoding of server responses. +- **Privacy:** a "private" saved location (Phase 3.3) strips GPS from renders sent to Immich too. Uploads respect the + export metadata policy. + +--- + +## Exit gate + +- [ ] Studio capture and native tethering (Canon/Nikon/Sony verified) ✅. +- [ ] Publish framework with Hard Drive, SFTP and Immich services; plugin SDK with two example plugins. +- [ ] Edit-in round trip with PhotoCraft (layered PSD) ✅; actions record and replay ✅. +- [ ] People clusters and XMP face regions ✅; `.lrcat` v2 migration with fidelity report. +- [ ] IMM-PUBLISH, IMM-SYNC, IMM-PEOPLE, IMM-SEARCH and IMM-MCP ✅ against the minimum and latest Immich releases. +- [ ] Scripted end-to-end session through MCP, headless in CI: + 1. simulated tethered shoot; + 2. import preset; + 3. cull; + 4. develop; + 5. publish to Hard Drive, SFTP and Immich (album plus stacked original); + 6. edit the rating in Immich and see it sync back; + 7. print a contact sheet to PDF. diff --git a/README.md b/README.md index 0152518f48..1810a887b6 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,19 @@

- - - - ArtCraft - - +

- -

LightCraft

- -

Your photos. Your pixels. Your machine.

+

Your photos. Your pixels. Your machine.

Photo library and raw development; an open-source, clean-room reimplementation of Adobe Lightroom, rebuilt in pure Rust.
Native on macOS, Windows and Linux. In the browser via WebAssembly. Drivable end to end by AI agents over MCP.

-

- Pure Rust - macOS, Windows, Linux and Web - MCP server included - License: MIT OR Apache-2.0 - Status: young and moving fast -

- -

- Join the ArtCraft community on Discord -

- -

- LightCraft on getartcraft.com · - ArtCraft · - All Crafting Apps -

- -
- -

- LightCraft's Edit view with Ansel Adams' The Tetons and the Snake River in the loupe, the Light and Effects panels open on the right, and the four showcase photos in the filmstrip -
- Ansel Adams, "The Tetons and the Snake River" (1942). Public domain, U.S. National Archives. Developed in LightCraft. -

- > [!NOTE] -> **ArtCraft is a community of artists from all walks of life.** Digital, generative, music, -> games — if you make things, you're one of us. **[Come say hi on Discord](https://discord.gg/artcraft).** +> The product name, binary names, settings folder and environment-variable prefix are set in one place, +> [`brand.toml`](brand.toml). This README calls the product "the app"; ``, ``, ``, `` +> and `` stand for `display_name`, `binary`, `cli_binary`, `mcp_server` and `settings_dir`, and +> `` for `env_prefix`, from that file.

Editing · @@ -59,15 +27,14 @@ Status · Quick start · Roadmap · - Downloads · - Crafting Apps + Downloads


## Edit like you mean it -LightCraft is a complete darkroom in a single native app. Every adjustment is **non-destructive**, so your originals +The app is a complete darkroom in a single native app. Every adjustment is **non-destructive**, so your originals are never touched. Every slider renders through a **scene-referred, wide-gamut, 32-bit float pipeline**: highlights roll off like film, shadows open up without halos, and colour stays clean from capture to export. @@ -125,7 +92,7 @@ Split-tone shadows, midtones and highlights independently with drag-anywhere col ## Before & after Hold \\ to peek at the original, press Y for side by side, or Shift+Y for a -split view. Every image below is a real screenshot of LightCraft, captured automatically by an agent through the +split view. Every image below is a real screenshot of the app, captured automatically by an agent through the [control channel](#built-for-agents). @@ -152,7 +119,7 @@ plus an overall Amount.

Masking panel with a linear Sky mask and a radial Sun glow mask; the radial gradient is drawn as a red overlay around the sun on a lake scene
- A radial "Sun glow" mask (Temp +40, Exposure +0.50) layered over a linear "Sky" mask. Photo from LightCraft's procedurally generated demo library. + A radial "Sun glow" mask (Temp +40, Exposure +0.50) layered over a linear "Sky" mask. Photo from the app's procedurally generated demo library.


@@ -218,12 +185,12 @@ so they stay smooth whether you have forty photos or forty thousand. ## Built for agents -Every menu item, slider, brush stroke, crop handle and keystroke in LightCraft is a **command** with a stable id and +Every menu item, slider, brush stroke, crop handle and keystroke in the app is a **command** with a stable id and JSON parameters. The UI, the keyboard, the CLI, a JSON-lines control channel and an **MCP server** all dispatch through the same entry point. An agent can cull a shoot, develop it, mask a sky and export it, and *see* the result. ```sh -lightcraft --control 7980 ~/Pictures/trip + --control 7980 ~/Pictures/trip ``` ```jsonc {"method": "engine.execute", "params": {"command": "photo.flag", "params": {"flag": "pick"}}} @@ -236,18 +203,18 @@ lightcraft --control 7980 ~/Pictures/trip - **Command registry.** `engine.commands` lists the available commands; `develop.controls` lists every slider's range, default and current value. -- **MCP server.** `lightcraft-cli mcp` exposes the command registry to Claude (or any MCP client), alongside +- **MCP server.** ` mcp` exposes the command registry to Claude (or any MCP client), alongside helpers for import, query, develop, mask, render (returned as an image) and export. It runs headless, or attached to the running app with screenshots, clicks and gestures. See [docs/mcp.md](docs/mcp.md). ```sh cargo build --release -p dac-cli - claude mcp add lightcraft -- "$PWD/target/release/lightcraft-cli" mcp ~/Pictures/shoot # headless - claude mcp add lightcraft-app -- "$PWD/target/release/lightcraft-cli" mcp --connect 127.0.0.1:7980 # live app + claude mcp add -- "$PWD/target/release/app-cli" mcp ~/Pictures/shoot # headless + claude mcp add -app -- "$PWD/target/release/app-cli" mcp --connect 127.0.0.1:7980 # live app ``` -- **Scriptable CLI:** `lightcraft-cli run --import in.dng develop.set control=light.exposure value=0.7 app.export +- **Scriptable CLI:** ` run --import in.dng develop.set control=light.exposure value=0.7 app.export path=out.jpg longEdge=2048` runs any chain of commands (headless, on a saved library, or against the running app) - and prints one JSON result per command; `lightcraft-cli render in.dng -o out.jpg --set light.exposure=0.7 --preset …`. + and prints one JSON result per command; ` render in.dng -o out.jpg --set light.exposure=0.7 --preset …`. - **Undo for everything**, including agent actions: a slider drag (or a scripted burst of updates) is one undo step. - **Every widget is addressable** (`ui.widgets`) and clickable by name, so agents operate the real UI, not a side door. @@ -282,7 +249,7 @@ lightcraft --control 7980 ~/Pictures/trip ## Feature status -LightCraft is young and moving fast. **Where we honestly stand** (details in the [roadmap](ROADMAP.md#where-we-stand)): +The app is young and moving fast. **Where we honestly stand** (details in the [roadmap](ROADMAP.md#where-we-stand)): - **By feature count we're at ~79%** of Lightroom (core features 98%), tracked row by row in [docs/parity.md](docs/parity.md). @@ -326,16 +293,22 @@ LightCraft is young and moving fast. **Where we honestly stand** (details in the ## Quick start ```sh -git clone https://github.com/storytold/lightcraft && cd lightcraft -cargo run --release -p dac-app # opens your library (~/Pictures/LightCraft Library; a new one starts with demo photos) -cargo run --release -p dac-app -- ~/Pictures/trip # import your photos (folders are scanned, duplicates skipped) -cargo run --release -p dac-app -- --memory # a throwaway in-memory demo session (writes nothing) -cargo run --release -p dac-app -- --control 7980 # with the automation channel +git clone https://example.invalid/repo && cd repo +cargo xtask brand check # the product name lives only in brand.toml +cargo xtask run # build and open your library (~/Pictures/ Library; a new one starts with demo photos) +cargo xtask run -- ~/Pictures/trip # import your photos (folders are scanned, duplicates skipped) +cargo xtask run -- --memory # a throwaway in-memory demo session (writes nothing) +cargo xtask run -- --control 7980 # with the automation channel cargo xtask web --serve # the same app in the browser: http://127.0.0.1:8080/ cargo run --release -p dac-cli -- render photo.jpg -o out.jpg --set light.exposure=0.5 +cargo xtask package # installers and archives under the brand binary names +cargo xtask install # install the app and CLI for the current user cargo xtask ci # fmt, clippy, tests, layering, wasm checks ``` +Inside `target/` the binaries are always called `app` and `app-cli`; `cargo xtask run`, `package` and `install` +give them the brand names from `brand.toml`. `cargo run -p dac-app` / `-p dac-cli` also work for development. + CI defaults to line-table debug information and one build job per 1.5 GB of RAM available when it starts (at most one per CPU; 4 if memory can't be read), so an 8 GB machine with 6 GB free builds with 4, and a busy machine with little free @@ -351,53 +324,53 @@ git clone https://github.com/storytold/craft-fonts ../craft-fonts CRAFT_FONTS_DIR=../craft-fonts cargo run --release -p dac-app ``` -Without it LightCraft builds and runs the same, but Chinese and Japanese text have no glyphs. Fonts are never committed to this +Without it the app builds and runs the same, but Chinese and Japanese text have no glyphs. Fonts are never committed to this repo; see [craftrules `standards/fonts.md`](https://github.com/storytold/craftrules/blob/main/standards/fonts.md). **Interface language:** **Edit → Language** (English, 简体中文, 繁體中文(台灣), 日本語, Português (Brasil), Deutsch) or **Settings → General → Language**; the choice applies immediately and persists. See [docs/localization.md](docs/localization.md). -**Logs:** the desktop app writes its log to standard error and to `logs/lightcraft.log` in its settings folder -(Linux `$XDG_CONFIG_HOME/lightcraft/logs/`, by default `~/.config/lightcraft/logs/`; macOS -`~/Library/Application Support/LightCraft/logs/`; Windows `%APPDATA%\LightCraft\logs\`), never in the library. A +**Logs:** the desktop app writes its log to standard error and to `logs/.log` in its settings folder +(Linux `$XDG_CONFIG_HOME//logs/`, by default `~/.config//logs/`; macOS +`~/Library/Application Support//logs/`; Windows `%APPDATA%\\logs\`), never in the library. A launch from a desktop menu or the Dock has no terminal, so attach this file to a bug report (**Help ▸ Open Log Folder** shows it in the file manager). Each start moves the -previous log to `lightcraft.1.log` and that one to `lightcraft.2.log`, so the log of a run that crashed survives the +previous log to `.1.log` and that one to `.2.log`, so the log of a run that crashed survives the next start; the file stops growing at 16 MiB, `--version` and `--help` write none, and runs with -`LIGHTCRAFT_NO_PREFS` log to standard error only. By default LightCraft's own crates log at `info` and everything else -at `warn`. `LIGHTCRAFT_LOG=info` or `debug` works as before (that level for LightCraft's own crates, warnings and +`_NO_PREFS` log to standard error only. By default the app's own crates log at `info` and everything else +at `warn`. `_LOG=info` or `debug` works as before (that level for the app's own crates, warnings and errors from the rest; any other value: warnings and errors only) and wins over `RUST_LOG`, which otherwise replaces the default with env_logger-style directives such as `RUST_LOG=debug` or `RUST_LOG=warn,dac_pipeline=trace` (a -directive ending in `*` covers every target starting with it, as in `lightcraft*=debug`). Panics are recorded there -too, and still in `lightcraft-panics.log` in the temp folder. The logger is `apps/app/src/logging.rs`. +directive ending in `*` covers every target starting with it, as in `dac*=debug`). Panics are recorded there +too, and still in `-panics.log` in the temp folder. The logger is `apps/app/src/logging.rs`. The web build needs the `wasm32-unknown-unknown` target and the matching `wasm-bindgen` CLI (`cargo xtask web` prints the exact install command); see [docs/web.md](docs/web.md). -**Nix** builds the desktop app and `lightcraft-cli` (the Nix build always includes the craft-fonts input, so Japanese +**Nix** builds the desktop app and `` (the Nix build always includes the craft-fonts input, so Japanese text has glyphs): ```sh -nix run github:storytold/lightcraft # the desktop app -nix build github:storytold/lightcraft # → ./result/bin/{lightcraft,lightcraft-cli} -nix develop github:storytold/lightcraft # rust toolchain + native deps + fonts +nix run # the desktop app +nix build # → ./result/bin/{,} +nix develop # rust toolchain + native deps + fonts ``` In a flake configuration (NixOS, home-manager, nix-darwin): ```nix # flake.nix -inputs.lightcraft.url = "github:storytold/lightcraft"; -# optional: build against your own nixpkgs instead of the one LightCraft pins -# inputs.lightcraft.inputs.nixpkgs.follows = "nixpkgs"; +inputs.app.url = ""; +# optional: build against your own nixpkgs instead of the one the app pins +# inputs.app.inputs.nixpkgs.follows = "nixpkgs"; # then, in a NixOS or home-manager module (where `inputs` is in scope): -nixpkgs.overlays = [ inputs.lightcraft.overlays.default ]; # makes `pkgs.lightcraft` available -environment.systemPackages = [ pkgs.lightcraft ]; # home-manager: home.packages = [ pkgs.lightcraft ]; +nixpkgs.overlays = [ inputs.app.overlays.default ]; # makes `pkgs.` available +environment.systemPackages = [ pkgs. ]; # home-manager: home.packages = [ pkgs. ]; ``` `nix build` installs the same desktop file, hicolor icons and AppStream metadata as the .deb/.rpm, and runs -`cargo test --workspace` as its check phase (skip it with `pkgs.lightcraft.overrideAttrs { doCheck = false; }`). +`cargo test --workspace` as its check phase (skip it with `pkgs..overrideAttrs { doCheck = false; }`). **Keyboard:** G grid · D detail · E edit · C crop · M masking · Shift+P presets · \\ original · Y before/after · Z zoom · @@ -407,8 +380,8 @@ environment.systemPackages = [ pkgs.lightcraft ]; # home-manager: home An engine-first Cargo workspace of small, tested crates with enforced layering (`cargo xtask layers`): `geom`, `color`, `raster`, `tiff` → `raw`, `codecs`, `meta`, `develop` → `pipeline` → `catalog` → `engine` → `ui-egui`. The -egui frontend is one swappable crate; nothing below it knows a UI exists. `mcp` and the apps (`lightcraft`, -`lightcraft-cli`) sit on top of `engine`. +egui frontend is one swappable crate; nothing below it knows a UI exists. `mcp` and the apps (`app`, +``) sit on top of `engine`. ## Contributing @@ -426,23 +399,21 @@ Humans and agents follow the same rules, so read [AGENTS.md](AGENTS.md) first. T `unsafe`, checked indexing on anything derived from input, and a regression test with every crash fix. Details in [AGENTS.md](AGENTS.md#never-crash-outranks-feature-work). -Questions, ideas or a bug you'd like to talk through first? Bring them to [Discord](https://discord.gg/artcraft). -
## Downloads -**New to LightCraft?** Download it from the [LightCraft page on getartcraft.com](https://getartcraft.com/apps/app). That's the easiest way to install it. - -**Want a specific build or format?** On GitHub, the [latest release](https://github.com/storytold/lightcraft/releases/latest) has every build listed below, and [all releases](https://github.com/storytold/lightcraft/releases) has earlier versions and their notes. `` in the file names is the version number, and `SHA256SUMS.txt` lists a checksum for every file. +Release builds are listed on the project's releases page. `` in the file names is the version number, +``/`` are the brand binary names, and `SHA256SUMS.txt` lists a checksum for every file. Build them yourself +with `cargo xtask package`. ### Windows | Build | Installer | Portable | |---|---|---| -| x64 (64-bit Intel/AMD) | `lightcraft--windows-x64.msi` | `lightcraft--windows-x64-portable.zip` | -| arm64 (Snapdragon and other ARM PCs) | `lightcraft--windows-arm64.msi` | `lightcraft--windows-arm64-portable.zip` | -| x86 (32-bit) | `lightcraft--windows-x86.msi` | `lightcraft--windows-x86-portable.zip` | +| x64 (64-bit Intel/AMD) | `--windows-x64.msi` | `--windows-x64-portable.zip` | +| arm64 (Snapdragon and other ARM PCs) | `--windows-arm64.msi` | `--windows-arm64-portable.zip` | +| x86 (32-bit) | `--windows-x86.msi` | `--windows-x86-portable.zip` | Installers and executables are code-signed. @@ -450,102 +421,51 @@ Installers and executables are code-signed. | Build | File | Notes | |---|---|---| -| App, universal (Apple silicon + Intel) | `lightcraft--macos-universal.dmg` | Signed and notarized | -| Command-line tool, universal | `lightcraft-cli--macos-universal.zip` | Signed and notarized | +| App, universal (Apple silicon + Intel) | `--macos-universal.dmg` | Signed and notarized | +| Command-line tool, universal | `--macos-universal.zip` | Signed and notarized | ### Linux | Format | x86_64 | aarch64 (ARM64) | Notes | |---|---|---|---| -| AppImage | `lightcraft--linux-x86_64.AppImage` | `lightcraft--linux-aarch64.AppImage` | Runs anywhere; updates itself with [AppImageUpdate](https://github.com/AppImageCommunity/AppImageUpdate) (`.zsync` files) | -| Flatpak | `lightcraft--linux-x86_64.flatpak` | `lightcraft--linux-aarch64.flatpak` | Sandboxed; `flatpak install --user ` | -| Debian/Ubuntu | `lightcraft--linux-x86_64.deb` | `lightcraft--linux-aarch64.deb` | | -| Fedora/RHEL/openSUSE | `lightcraft--linux-x86_64.rpm` | `lightcraft--linux-aarch64.rpm` | | -| Tarball | `lightcraft--linux-x86_64.tar.gz` | `lightcraft--linux-aarch64.tar.gz` | Unpack anywhere | +| AppImage | `--linux-x86_64.AppImage` | `--linux-aarch64.AppImage` | Runs anywhere; updates itself with [AppImageUpdate](https://github.com/AppImageCommunity/AppImageUpdate) (`.zsync` files) | +| Flatpak | `--linux-x86_64.flatpak` | `--linux-aarch64.flatpak` | Sandboxed; `flatpak install --user ` | +| Debian/Ubuntu | `--linux-x86_64.deb` | `--linux-aarch64.deb` | | +| Fedora/RHEL/openSUSE | `--linux-x86_64.rpm` | `--linux-aarch64.rpm` | | +| Tarball | `--linux-x86_64.tar.gz` | `--linux-aarch64.tar.gz` | Unpack anywhere | ### FreeBSD | Build | File | |---|---| -| x86_64 | `lightcraft--freebsd-x86_64.tar.gz` | +| x86_64 | `--freebsd-x86_64.tar.gz` | ### Web (WebAssembly) | Build | File | Notes | |---|---|---| -| Static site | `lightcraft-web-.zip` | Runs in a modern browser; host it on any static server | - -
- -## The Crafting Apps - -LightCraft is one of the **Crafting Apps**: free, open-source creative tools from the -[ArtCraft](https://getartcraft.com/) team, each written from scratch in Rust and each able to -stand on its own. - -| | App | What it's for | Code | Learn more | -|:-:|---|---|---|---| -| | **PhotoCraft** | Image editing: layers, masks, type and real PSD files | [GitHub](https://github.com/storytold/photocraft) | [Website](https://getartcraft.com/apps/photocraft) | -| | **VectorCraft** | Vector illustration | [GitHub](https://github.com/storytold/vectorcraft) | [Website](https://getartcraft.com/apps/vectorcraft) | -| | **FilmCraft** | Video editing, color and sound | [GitHub](https://github.com/storytold/filmcraft) | [Website](https://getartcraft.com/apps/filmcraft) | -| | **LightCraft** | **Photo library and raw development · you are here** | [GitHub](https://github.com/storytold/lightcraft) | [Website](https://getartcraft.com/apps/app) | -| | **PdfCraft** | Reading, organizing and protecting PDFs | [GitHub](https://github.com/storytold/pdfcraft) | [Website](https://getartcraft.com/apps/pdfcraft) | -| | **EffectCraft** | Motion graphics and visual effects | [GitHub](https://github.com/storytold/effectcraft) | [Website](https://getartcraft.com/apps/effectcraft) | -| | **DesignCraft** | Page layout and publishing | [GitHub](https://github.com/storytold/designcraft) | [Website](https://getartcraft.com/apps/designcraft) | - -And [**ArtCraft**](https://getartcraft.com/) itself, our AI image and video studio for artists who want real control. - -
- -

- Join the ArtCraft community on Discord -

- -

Come make things with us

- -

- Our Discord is where artists of every kind hang out: people who paint, shoot, draw, cut film, - set type, and people still figuring out what they like to make. Share what you're working on, - ask for help, tell us what's broken, or tell us what you wish these tools could do. - Whatever your medium and however long you've been at it, you're welcome here. -

- -

- discord.gg/artcraft · - getartcraft.com · - The Crafting Apps · - LightCraft -

+| Static site | `-web-.zip` | Runs in a modern browser; host it on any static server |
## License and credits -LightCraft is dual-licensed under [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE), at your option. -Copyright (c) 2026 ArtCraft Team and the LightCraft contributors. Required notices are in [NOTICE](NOTICE). +The app is licensed under the [MIT License](LICENSE), except `crates/segment` and `crates/fetch`, which are +Apache-2.0 only. It is a fork of an upstream open-source project; the upstream copyright notices and required +third-party notices are in [LICENSE](LICENSE) and [NOTICE](NOTICE). Bundled fonts, icons, images and other assets keep their own open licenses; each one is listed with its author, source and license in [assets/ATTRIBUTION.md](assets/ATTRIBUTION.md). Showcase photographs are public-domain works, used via Wikimedia Commons: Ansel Adams, *The Tetons and the Snake River* (1942, U.S. National Archives); Dorothea Lange, *Migrant Mother* (1936, Library of Congress); Bill Anders / NASA, -*Earthrise* (1968); NASA, *The Blue Marble* (1972). The demo library is procedurally generated by LightCraft. UI font: +*Earthrise* (1968); NASA, *The Blue Marble* (1972). The demo library is procedurally generated by the app. UI font: Inter (SIL OFL 1.1). Builds made with [craft-fonts](https://github.com/storytold/craft-fonts) (all official releases) also embed its Chinese and Japanese fonts (Noto Sans CJK SC, BIZ UDPGothic, BIZ UDMincho, Shippori Mincho; SIL OFL 1.1), listed in its [ATTRIBUTION.md](https://github.com/storytold/craft-fonts/blob/main/ATTRIBUTION.md). All icons are original. -The ArtCraft name, wordmark and logos in [`docs/brand/`](docs/brand/) are trademarks of the -ArtCraft Team and are not covered by this license. They may be used only unmodified, and only as -part of this repository and LightCraft, under [`docs/brand/LICENSE-brand.txt`](docs/brand/LICENSE-brand.txt). Forks and modified versions must remove them. -Adobe, Photoshop, Illustrator, Premiere Pro, Lightroom, Acrobat, After Effects and InDesign are trademarks or registered trademarks of Adobe Inc. in the United States and/or other countries. LightCraft is an independent, open-source project and is not affiliated with, sponsored by or endorsed by Adobe Inc.; these names are used only to describe the workflows it is compatible with. +Adobe, Photoshop, Illustrator, Premiere Pro, Lightroom, Acrobat, After Effects and InDesign are trademarks or registered trademarks of Adobe Inc. in the United States and/or other countries. The app is an independent, open-source project and is not affiliated with, sponsored by or endorsed by Adobe Inc.; these names are used only to describe the workflows it is compatible with. -

- ArtCraft
- Made by the ArtCraft team and community. -

-## Star history - -[![Star History Chart](https://api.star-history.com/svg?repos=storytold/lightcraft&type=Date&legend=top-left)](https://www.star-history.com/?repos=storytold%2Flightcraft&type=date&legend=top-left) diff --git a/ROADMAP.md b/ROADMAP.md index 32f6a89bc6..5c22c218d0 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,4 +1,4 @@ -# LightCraft roadmap +# Roadmap Milestones toward full Adobe Lightroom parity (cloud Lightroom first, then every Lightroom Classic module), with wall-clock estimates for continuous (24/7) agent-driven development with 4–6 parallel agents. Estimates are calibrated on the sibling @@ -197,13 +197,13 @@ own chart-based calibration (M11.4). Adobe matrices are never used. File → Import Lightroom Catalog… reads `.lrcat` plus committed WAL pages directly through a pure-Rust SQLite reader. Originals stay in place; ratings, flags, labels, XMP metadata, hierarchical keywords, -collections/sets, virtual copies and supported develop settings migrate into LightCraft. Existing edits +collections/sets, virtual copies and supported develop settings migrate into the app. Existing edits are preserved by default, reimport identities are persistent, and source settings/history/snapshots are archived before catalog mutation. Missing originals remain available for relinking. Rendering is approximate: unsupported Adobe profiles/AI/process settings are reported and archived; history/snapshots remain source data, and smart collections import current membership. The Lightroom -database is read-only; LightCraft owns subsequent edits. See `docs/lightroom-catalog-import.md`. +database is read-only; the app owns subsequent edits. See `docs/lightroom-catalog-import.md`. ## Log - 2026-09-30: roadmap created; M0 in progress; research docs (Lightroom reference, Rust imaging ecosystem) complete. diff --git a/apps/app/Cargo.toml b/apps/app/Cargo.toml index 6152c0ec96..ee5410e313 100644 --- a/apps/app/Cargo.toml +++ b/apps/app/Cargo.toml @@ -22,6 +22,7 @@ rawnind-model = ["denoise", "dac-engine/rawnind-model"] heif = ["dac-codecs/heif"] [dependencies] +dac-brand = { workspace = true } dac-engine = { workspace = true, features = ["sam"] } dac-sysmem = { workspace = true } dac-ui-egui = { workspace = true } @@ -33,7 +34,8 @@ serde_json = { workspace = true } log = { workspace = true } [build-dependencies] -# Icon + VERSIONINFO for lightcraft.exe; build.rs only uses it when targeting Windows. +# Icon + VERSIONINFO for the desktop executable; build.rs only uses it when targeting Windows. +dac-brand = { workspace = true } winresource = "0.1" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/apps/app/build.rs b/apps/app/build.rs index 4947091d64..7a37ad2dde 100644 --- a/apps/app/build.rs +++ b/apps/app/build.rs @@ -1,28 +1,33 @@ -//! Windows only: embed the app icon and version info (VERSIONINFO) into `lightcraft.exe`, so +//! Windows only: embed the app icon and version info (VERSIONINFO) into the desktop executable, so //! Explorer, the taskbar, the Start menu and Alt-Tab show the lynx. //! //! On every other target this does nothing. A missing resource compiler is a warning, so a -//! cross-compile from macOS or Linux still links, unless `LIGHTCRAFT_REQUIRE_WINRES=1` turns it +//! cross-compile from macOS or Linux still links, unless `_REQUIRE_WINRES=1` turns it //! into an error (for release builds). fn main() { println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=../../assets/app-icon/lightcraft.ico"); - println!("cargo:rerun-if-env-changed=LIGHTCRAFT_REQUIRE_WINRES"); + println!("cargo:rerun-if-changed=../../assets/app-icon/app.ico"); + let require = dac_brand::env_var("REQUIRE_WINRES"); + println!("cargo:rerun-if-env-changed={require}"); + for prefix in dac_brand::LEGACY_ENV_PREFIXES { + println!("cargo:rerun-if-env-changed={prefix}_REQUIRE_WINRES"); + } if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("windows") { return; } let mut res = winresource::WindowsResource::new(); - res.set_icon("../../assets/app-icon/lightcraft.ico") - .set("ProductName", "LightCraft") - .set("FileDescription", "LightCraft photo library and raw developer") - .set("LegalCopyright", "Copyright (c) the LightCraft authors. MIT OR Apache-2.0.") - .set("OriginalFilename", "lightcraft.exe") - .set("InternalName", "lightcraft"); + res.set_icon("../../assets/app-icon/app.ico") + .set("ProductName", dac_brand::DISPLAY_NAME) + .set("FileDescription", &format!("{}: {}", dac_brand::DISPLAY_NAME, dac_brand::TAGLINE)) + .set("CompanyName", dac_brand::VENDOR) + .set("LegalCopyright", &format!("Copyright (c) {}. MIT OR Apache-2.0.", dac_brand::VENDOR)) + .set("OriginalFilename", &format!("{}.exe", dac_brand::BINARY)) + .set("InternalName", dac_brand::BINARY); if let Err(e) = res.compile() { - if std::env::var_os("LIGHTCRAFT_REQUIRE_WINRES").is_some() { + if dac_brand::env_is_set("REQUIRE_WINRES") { panic!("embedding Windows resources failed: {e}"); } - println!("cargo:warning=lightcraft.exe built without icon/version resources: {e}"); + println!("cargo:warning={}.exe built without icon/version resources: {e}", dac_brand::BINARY); } } diff --git a/apps/app/src/control_server.rs b/apps/app/src/control_server.rs index 64b62ca01b..50b4d1bbfa 100644 --- a/apps/app/src/control_server.rs +++ b/apps/app/src/control_server.rs @@ -1,5 +1,5 @@ //! Loopback JSON-lines control server: one request per line, one reply per line. -//! This is the transport the MCP server (`lightcraft-cli mcp --connect`) wraps. +//! This is the transport the MCP server (` mcp --connect`) wraps. //! //! The server only ever reads requests: a line that is not a JSON object with a string `method` //! (an HTTP request line from a browser's cross-origin `fetch`, a stray `nc`, binary junk) gets diff --git a/apps/app/src/logging.rs b/apps/app/src/logging.rs index ac47eb695b..ced89227b0 100644 --- a/apps/app/src/logging.rs +++ b/apps/app/src/logging.rs @@ -2,25 +2,25 @@ //! //! It replaces the stderr-only `StderrLog` that `main.rs` used to install. A launch from a //! desktop menu or the Dock has no terminal, so the file is what a bug report can attach: -//! `/logs/lightcraft.log`, next to `ui.json` (`config_dir` in `main.rs`; Linux -//! `$XDG_CONFIG_HOME/lightcraft/logs`, by default `~/.config/lightcraft/logs`). Never in the -//! library folder. Each start moves the previous log to `lightcraft.1.log` (and that one to `.2`), -//! so the log of a run that crashed survives the next launch. Runs with `LIGHTCRAFT_NO_PREFS` +//! `/logs/.log`, next to `ui.json` (`config_dir` in `main.rs`; Linux +//! `$XDG_CONFIG_HOME//logs`, by default `~/.config//logs`). Never in the +//! library folder. Each start moves the previous log to `.1.log` (and that one to `.2`), +//! so the log of a run that crashed survives the next launch. Runs with `_NO_PREFS` //! (tests, scripts) log to standard error only, so they don't rotate away the user's own logs. //! -//! Levels ([`filter_spec`]): `info` for LightCraft's own crates, `warn` for everything else (wgpu -//! and naga are chatty). `LIGHTCRAFT_LOG` keeps the meaning it had with the old logger: `info` or -//! `debug` lowers LightCraft's own crates to that level, any other value means warnings and errors +//! Levels ([`filter_spec`]): `info` for the app's own crates, `warn` for everything else (wgpu +//! and naga are chatty). `_LOG` keeps the meaning it had with the old logger: `info` or +//! `debug` lowers the app's own crates to that level, any other value means warnings and errors //! only. Without it, `RUST_LOG` replaces the default with env_logger-style directives: `debug`, //! `warn,dac_pipeline=trace`, `wgpu_core=info`. A directive ending in `*` matches every -//! target that starts with it (`lightcraft*=debug`). +//! target that starts with it (`dac*=debug`). //! //! Records logged before the settings folder is known are kept (up to [`MAX_PENDING`]) and //! written once the file is attached. Writing never panics: a file that can't be created or //! written leaves standard error as the only sink. Panics that escape everything are added to the //! file by [`AppLogger::record_panic`] (the default hook already printed them on standard error). //! -//! This is the desktop app's logger only; `lightcraft-cli` doesn't share a process with it. +//! This is the desktop app's logger only; the command-line tool doesn't share a process with it. use std::fs::File; use std::io::Write; @@ -31,27 +31,29 @@ use std::time::SystemTime; use log::LevelFilter; /// The current log file's name inside the log folder. -pub const LOG_FILE: &str = "lightcraft.log"; -/// How many previous logs are kept (`lightcraft.1.log` … `lightcraft..log`). +pub fn log_file() -> String { + format!("{}.log", dac_brand::BINARY) +} +/// How many previous logs are kept (`.1.log` … `..log`). pub const KEEP: usize = 2; /// The log file stops growing past this size (a runaway warning can't fill the disk). pub const MAX_FILE_BYTES: u64 = 16 * 1024 * 1024; /// Records kept in memory until the log file is attached. pub const MAX_PENDING: usize = 512; -/// The built-in filter when neither `LIGHTCRAFT_LOG` nor `RUST_LOG` says otherwise. -pub const DEFAULT_FILTER: &str = "warn,lightcraft*=info"; +/// The built-in filter when neither `_LOG` nor `RUST_LOG` says otherwise. +pub const DEFAULT_FILTER: &str = "warn,dac*=info,app=info"; -/// The filter directives for this run from `LIGHTCRAFT_LOG` and `RUST_LOG` (blank = unset). +/// The filter directives for this run from `_LOG` and `RUST_LOG` (blank = unset). /// -/// `LIGHTCRAFT_LOG` wins when set and means what it did for the old stderr logger: `info` or -/// `debug` for LightCraft's own crates (warnings and errors from everything else), any other value +/// `_LOG` wins when set and means what it did for the old stderr logger: `info` or +/// `debug` for the app's own crates (warnings and errors from everything else), any other value /// warnings and errors only. Else `RUST_LOG` as env_logger directives, else [`DEFAULT_FILTER`]. -pub fn filter_spec(lightcraft_log: Option<&str>, rust_log: Option<&str>) -> String { +pub fn filter_spec(app_log: Option<&str>, rust_log: Option<&str>) -> String { let set = |v: Option<&str>| v.map(str::trim).filter(|v| !v.is_empty()).map(str::to_owned); - if let Some(level) = set(lightcraft_log) { + if let Some(level) = set(app_log) { return match level.as_str() { - "debug" => "warn,lightcraft*=debug".to_owned(), - "info" => "warn,lightcraft*=info".to_owned(), + "debug" => "warn,dac*=debug,app=debug".to_owned(), + "info" => "warn,dac*=info,app=info".to_owned(), _ => "warn".to_owned(), }; } @@ -137,8 +139,12 @@ fn civil_from_days(days: u64) -> (u64, u64, u64) { (y, m, d) } +fn numbered_name(n: usize) -> String { + format!("{}.{n}.log", dac_brand::BINARY) +} + fn numbered(dir: &Path, n: usize) -> PathBuf { - if n == 0 { dir.join(LOG_FILE) } else { dir.join(format!("lightcraft.{n}.log")) } + if n == 0 { dir.join(log_file()) } else { dir.join(numbered_name(n)) } } /// Shift the previous logs up one (`.log` → `.1.log` → … → `..log`, the oldest dropped) @@ -266,7 +272,7 @@ impl AppLogger { } } - /// No log file for this run (`LIGHTCRAFT_NO_PREFS`): log to standard error only. + /// No log file for this run (`_NO_PREFS`): log to standard error only. pub fn no_file(&self) { self.sink.lock().unwrap_or_else(PoisonError::into_inner).no_file(); } @@ -275,7 +281,7 @@ impl AppLogger { /// error), whatever the filter. Skipped when the sink is busy: the panic may have happened on /// this very thread while it held the lock, and waiting would hang the app. pub fn record_panic(&self, thread: &str, report: &str) { - let line = format_line(×tamp(SystemTime::now()), log::Level::Error, thread, "lightcraft", report); + let line = format_line(×tamp(SystemTime::now()), log::Level::Error, thread, "app", report); let mut sink = match self.sink.try_lock() { Ok(sink) => sink, Err(TryLockError::Poisoned(p)) => p.into_inner(), @@ -312,8 +318,7 @@ impl log::Log for AppLogger { /// first. Call [`AppLogger::attach_dir`] (or [`AppLogger::no_file`]) once the arguments are parsed. pub fn install() -> Option<&'static AppLogger> { static LOGGER: OnceLock = OnceLock::new(); - let var = |name| std::env::var(name).ok(); - let filter = Filter::parse(&filter_spec(var("LIGHTCRAFT_LOG").as_deref(), var("RUST_LOG").as_deref())); + let filter = Filter::parse(&filter_spec(dac_brand::env("LOG").as_deref(), std::env::var("RUST_LOG").ok().as_deref())); let max = filter.max(); let logger = LOGGER.get_or_init(|| AppLogger::new(filter, true)); log::set_logger(logger).ok()?; @@ -322,7 +327,7 @@ pub fn install() -> Option<&'static AppLogger> { } /// Chain a panic hook after the current one (the engine guard's: standard error plus -/// `lightcraft-panics.log` in the temp folder) that also puts the panic in the log file. +/// `-panics.log` in the temp folder) that also puts the panic in the log file. pub fn record_panics(logger: &'static AppLogger) { let previous = std::panic::take_hook(); std::panic::set_hook(Box::new(move |info| { @@ -342,7 +347,7 @@ mod tests { fn temp_dir(tag: &str) -> PathBuf { static N: AtomicUsize = AtomicUsize::new(0); - let d = std::env::temp_dir().join(format!("lightcraft-logging-{tag}-{}-{}", std::process::id(), N.fetch_add(1, Ordering::Relaxed))); + let d = std::env::temp_dir().join(format!("app-logging-{tag}-{}-{}", std::process::id(), N.fetch_add(1, Ordering::Relaxed))); let _ = std::fs::remove_dir_all(&d); d } @@ -357,21 +362,21 @@ mod tests { } /// The logger this replaced (`StderrLog`): warnings and errors from every target, `info` and - /// `debug` only from LightCraft's own crates, and only when `LIGHTCRAFT_LOG` asked for them. - fn old_stderr_log_enabled(lightcraft_log: &str, level: log::Level, target: &str) -> bool { - let max = match lightcraft_log { + /// `debug` only from the app's own crates, and only when `_LOG` asked for them. + fn old_stderr_log_enabled(app_log: &str, level: log::Level, target: &str) -> bool { + let max = match app_log { "debug" => LevelFilter::Debug, "info" => LevelFilter::Info, _ => LevelFilter::Warn, }; - level <= max && (level <= log::Level::Warn || target.starts_with("lightcraft")) + level <= max && (level <= log::Level::Warn || (target.starts_with("dac") || target == "app" || target.starts_with("app::"))) } #[test] - fn the_default_filter_shows_lightcraft_info_and_other_crates_warnings() { + fn the_default_filter_shows_own_info_and_other_crates_warnings() { let f = Filter::parse(DEFAULT_FILTER); - assert_eq!(f.level_for("lightcraft"), LevelFilter::Info); - assert_eq!(f.level_for("lightcraft::control_server"), LevelFilter::Info); + assert_eq!(f.level_for("app"), LevelFilter::Info); + assert_eq!(f.level_for("app::control_server"), LevelFilter::Info); assert_eq!(f.level_for("dac_engine::guard"), LevelFilter::Info); assert_eq!(f.level_for("dac_ui_egui::render"), LevelFilter::Info); assert_eq!(f.level_for("wgpu_core::device"), LevelFilter::Warn); @@ -382,16 +387,16 @@ mod tests { assert_eq!(filter_spec(Some(""), Some(" ")), DEFAULT_FILTER); } - /// `LIGHTCRAFT_LOG` keeps working exactly as it did with the old stderr-only logger. + /// `_LOG` keeps working exactly as it did with the old stderr-only logger. #[test] - fn lightcraft_log_keeps_its_meaning() { - let targets = ["dac-app", "lightcraft::control_server", "dac_engine::segment", "dac_gpu", "wgpu_core::device", "naga", "eframe"]; + fn app_log_keeps_its_meaning() { + let targets = ["dac-app", "app::control_server", "dac_engine::segment", "dac_gpu", "wgpu_core::device", "naga", "eframe"]; let levels = [log::Level::Error, log::Level::Warn, log::Level::Info, log::Level::Debug, log::Level::Trace]; for value in ["info", "debug", "warn", "error", "verbose", "INFO"] { let f = Filter::parse(&filter_spec(Some(value), None)); for target in targets { for level in levels { - assert_eq!(level <= f.level_for(target), old_stderr_log_enabled(value, level, target), "LIGHTCRAFT_LOG={value} {level} {target}"); + assert_eq!(level <= f.level_for(target), old_stderr_log_enabled(value, level, target), "LOG={value} {level} {target}"); } } } @@ -400,7 +405,7 @@ mod tests { } #[test] - fn rust_log_replaces_the_default_and_lightcraft_log_wins_over_it() { + fn rust_log_replaces_the_default_and_app_log_wins_over_it() { assert_eq!(filter_spec(None, Some("warn,wgpu_core=info")), "warn,wgpu_core=info"); let f = Filter::parse(&filter_spec(None, Some("debug"))); assert_eq!(f.level_for("eframe"), LevelFilter::Debug); @@ -421,14 +426,14 @@ mod tests { // A module name is matched at `::` boundaries, not as a bare prefix. assert_eq!(f.level_for("wgpu_core_extra"), LevelFilter::Info); // A trailing `*` is a prefix. - assert_eq!(Filter::parse("lightcraft*=debug").level_for("dac_raw::cr2"), LevelFilter::Debug); - assert_eq!(Filter::parse("lightcraft*=debug").level_for("eframe"), LevelFilter::Error); + assert_eq!(Filter::parse("dac*=debug").level_for("dac_raw::cr2"), LevelFilter::Debug); + assert_eq!(Filter::parse("dac*=debug").level_for("eframe"), LevelFilter::Error); // A bare target name sets that target to the most verbose level, as env_logger does. assert_eq!(Filter::parse("naga").level_for("naga::front"), LevelFilter::Trace); assert_eq!(Filter::parse("naga").level_for("eframe"), LevelFilter::Error); // Levels are case-insensitive and surrounding blanks are ignored. - assert_eq!(Filter::parse(" WARN , lightcraft = Debug ").level_for("lightcraft"), LevelFilter::Debug); - assert_eq!(Filter::parse(" WARN , lightcraft = Debug ").level_for("eframe"), LevelFilter::Warn); + assert_eq!(Filter::parse(" WARN , app = Debug ").level_for("app"), LevelFilter::Debug); + assert_eq!(Filter::parse(" WARN , app = Debug ").level_for("eframe"), LevelFilter::Warn); } #[test] @@ -441,30 +446,30 @@ mod tests { "=", "==", "=debug", - "lightcraft=", + "app=", "nonsense=loud", "🦀=info", "*", "*=", "=*", "a=b=c", - "warn,,lightcraft=DEBUG", + "warn,,app=DEBUG", "\0", "é::ü=trace", &long, &many, ] { let f = Filter::parse(spec); - for target in ["", "lightcraft", "🦀", "a::b", "*"] { + for target in ["", "app", "🦀", "a::b", "*"] { let _ = f.level_for(target); } let _ = f.max(); let _ = filter_spec(Some(spec), Some(spec)); } - assert_eq!(Filter::parse("warn,,lightcraft=DEBUG").level_for("lightcraft"), LevelFilter::Debug); + assert_eq!(Filter::parse("warn,,app=DEBUG").level_for("app"), LevelFilter::Debug); // An unknown level is skipped: that target keeps the default. assert_eq!(Filter::parse("nonsense=loud").level_for("nonsense"), LevelFilter::Error); - assert_eq!(Filter::parse("lightcraft=").level_for("lightcraft"), LevelFilter::Error); + assert_eq!(Filter::parse("app=").level_for("app"), LevelFilter::Error); assert_eq!(Filter::parse("=debug").max(), LevelFilter::Error); assert_eq!(Filter::parse("🦀=info").level_for("🦀::claw"), LevelFilter::Info); } @@ -487,8 +492,8 @@ mod tests { #[test] fn a_line_carries_time_level_thread_target_and_message() { assert_eq!( - format_line("2026-10-08T07:59:17.728Z", log::Level::Info, "main", "lightcraft", "library /photos: 12 photos"), - "2026-10-08T07:59:17.728Z INFO [main] lightcraft: library /photos: 12 photos\n" + format_line("2026-10-08T07:59:17.728Z", log::Level::Info, "main", "app", "library /photos: 12 photos"), + "2026-10-08T07:59:17.728Z INFO [main] app: library /photos: 12 photos\n" ); // A multi-line message keeps its lines; the record still ends in one newline. assert!(format_line("t", log::Level::Error, "w", "x", "a\nb\n").ends_with("x: a\nb\n")); @@ -499,14 +504,14 @@ mod tests { let dir = temp_dir("rotate"); for run in 1..=4 { let (path, _file) = rotate(&dir).expect("rotate"); - assert_eq!(path, dir.join(LOG_FILE)); + assert_eq!(path, dir.join(log_file())); assert_eq!(read(&path), ""); std::fs::write(&path, format!("run {run}")).expect("write"); } - assert_eq!(read(&dir.join(LOG_FILE)), "run 4"); - assert_eq!(read(&dir.join("lightcraft.1.log")), "run 3"); - assert_eq!(read(&dir.join("lightcraft.2.log")), "run 2"); - assert!(!dir.join("lightcraft.3.log").exists(), "only {KEEP} old logs are kept"); + assert_eq!(read(&dir.join(log_file())), "run 4"); + assert_eq!(read(&dir.join(numbered_name(1))), "run 3"); + assert_eq!(read(&dir.join(numbered_name(2))), "run 2"); + assert!(!dir.join(numbered_name(3)).exists(), "only {KEEP} old logs are kept"); let _ = std::fs::remove_dir_all(&dir); } @@ -592,24 +597,24 @@ mod tests { use log::Log; let dir = temp_dir("logger"); let logger = AppLogger::new(Filter::parse(DEFAULT_FILTER), false); - record(&logger, log::Level::Info, "lightcraft", "before the settings directory"); + record(&logger, log::Level::Info, "app", "before the settings directory"); record(&logger, log::Level::Info, "wgpu_core::device", "too chatty"); let path = logger.attach_dir(&dir).expect("attach"); - assert_eq!(path, dir.join(LOG_FILE)); + assert_eq!(path, dir.join(log_file())); record(&logger, log::Level::Warn, "wgpu_hal::vulkan", "a real warning"); record(&logger, log::Level::Error, "dac_engine::guard", "`develop.reset` failed unexpectedly: boom"); - record(&logger, log::Level::Debug, "lightcraft", "below info"); + record(&logger, log::Level::Debug, "app", "below info"); let text = read(&path); let lines: Vec<&str> = text.lines().collect(); assert_eq!(lines.len(), 3, "{text}"); - assert!(lines[0].contains(" INFO [") && lines[0].ends_with("lightcraft: before the settings directory"), "{text}"); + assert!(lines[0].contains(" INFO [") && lines[0].ends_with("app: before the settings directory"), "{text}"); assert!(lines[1].ends_with("wgpu_hal::vulkan: a real warning"), "{text}"); assert!(lines[2].contains(" ERROR [") && lines[2].ends_with("dac_engine::guard: `develop.reset` failed unexpectedly: boom"), "{text}"); assert!(logger.enabled(&log::Metadata::builder().level(log::Level::Info).target("dac_ui_egui").build())); assert!(!logger.enabled(&log::Metadata::builder().level(log::Level::Info).target("naga").build())); // Attaching again rotates: the first log becomes `.1`. logger.attach_dir(&dir).expect("attach again"); - assert_eq!(read(&dir.join("lightcraft.1.log")), text); + assert_eq!(read(&dir.join(numbered_name(1))), text); let _ = std::fs::remove_dir_all(&dir); } @@ -623,7 +628,7 @@ mod tests { let l = std::sync::Arc::clone(&logger); std::thread::spawn(move || { for i in 0..100 { - record(&l, log::Level::Info, "lightcraft", &format!("thread {t} record {i}")); + record(&l, log::Level::Info, "app", &format!("thread {t} record {i}")); } }) }) @@ -633,7 +638,7 @@ mod tests { } let text = read(&path); assert_eq!(text.lines().count(), 800); - assert!(text.lines().all(|l| l.contains(" lightcraft: thread ")), "{text}"); + assert!(text.lines().all(|l| l.contains(" app: thread ")), "{text}"); let _ = std::fs::remove_dir_all(&dir); } @@ -643,7 +648,7 @@ mod tests { std::fs::create_dir_all(dir.parent().expect("parent")).expect("tmp"); std::fs::write(&dir, "not a directory").expect("block"); let logger = AppLogger::new(Filter::parse("info"), false); - record(&logger, log::Level::Info, "lightcraft", "early"); + record(&logger, log::Level::Info, "app", "early"); assert!(logger.attach_dir(&dir).is_err()); record(&logger, log::Level::Error, "x", "still fine"); // Nothing waits in memory for a file that won't come. @@ -663,8 +668,8 @@ mod tests { .join(); assert!(logger.sink.is_poisoned()); let path = logger.attach_dir(&dir).expect("attach"); - record(&logger, log::Level::Warn, "lightcraft", "after the poison"); - assert!(read(&path).contains("lightcraft: after the poison")); + record(&logger, log::Level::Warn, "app", "after the poison"); + assert!(read(&path).contains("app: after the poison")); let _ = std::fs::remove_dir_all(&dir); } @@ -681,7 +686,7 @@ mod tests { logger.record_panic("main", "while the sink is held"); } let text = read(&path); - assert!(text.contains(" ERROR [render] lightcraft: panicked at crates/x/src/lib.rs:3:5:\nboom\n"), "{text}"); + assert!(text.contains(" ERROR [render] app: panicked at crates/x/src/lib.rs:3:5:\nboom\n"), "{text}"); assert!(!text.contains("while the sink is held"), "{text}"); let _ = std::fs::remove_dir_all(&dir); } diff --git a/apps/app/src/main.rs b/apps/app/src/main.rs index f9cfadf91a..86b6e8d234 100644 --- a/apps/app/src/main.rs +++ b/apps/app/src/main.rs @@ -1,23 +1,23 @@ -//! LightCraft desktop app. +//! The desktop app. //! -//! Usage: `lightcraft [--library DIR | --memory] [--no-demo] [--control ] [files or folders…]` +//! Usage: ` [--library DIR | --memory] [--no-demo] [--control ] [files or folders…]` //! //! The library (catalog, presets, thumbnail cache) lives in `--library DIR`, else -//! `$LIGHTCRAFT_LIBRARY`, else the library last opened with Settings → Open Library…, else -//! `~/Pictures/LightCraft Library`; a new library starts with the +//! `$_LIBRARY`, else the library last opened with Settings → Open Library…, else +//! `~/Pictures/` (`dac_brand::LIBRARY_DEFAULT`); a new library starts with the //! procedural demo photos unless `--no-demo` or files are given. Files and folders on the command //! line are imported (duplicates are skipped). `--memory` runs an in-memory session that writes //! nothing (demo photos unless files are given; used by the README showcase scripts). A library //! that can't be opened is never replaced silently: the window says why and asks what to do //! (`dac_ui_egui::panels::library_problem`). //! -//! `--control ` (or `LIGHTCRAFT_CONTROL_PORT`) starts a localhost JSON-lines control server: +//! `--control ` (or `_CONTROL_PORT`) starts a localhost JSON-lines control server: //! `{"id":1,"method":"ui.inspect","params":{}}` → `{"id":1,"ok":true,"result":…}`. //! See `dac_ui_egui::control` for the methods. //! //! On Windows, release builds are GUI-subsystem programs: launching the app opens no console //! window (issue #7). Their `--help` / `--version` output and diagnostics then have no console to -//! go to; use `lightcraft-cli` (a console program) from a terminal, or a debug build. +//! go to; use the command-line tool (a console program) from a terminal, or a debug build. #![cfg_attr(all(target_os = "windows", not(debug_assertions)), windows_subsystem = "windows")] #![forbid(unsafe_code)] #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] @@ -35,15 +35,15 @@ use dac_ui_egui::{DacApp, Services, UiState}; use dialog_filter::FileDialogExt as _; /// Reverse-DNS app id: Wayland app id, `.desktop` file and hicolor icon name. -const APP_ID: &str = "ai.storyteller.lightcraft"; +const APP_ID: &str = dac_brand::APP_ID; /// The window, taskbar and Dock icon (assets/app-icon/, regenerated by packaging/icons.sh). macOS /// gets the version with Apple's transparent margin so it sits right among the other Dock icons. fn app_icon() -> egui::IconData { #[cfg(target_os = "macos")] - let png: &[u8] = include_bytes!("../../../assets/app-icon/lightcraft-macos-512.png"); + let png: &[u8] = include_bytes!("../../../assets/app-icon/app-macos-512.png"); #[cfg(not(target_os = "macos"))] - let png: &[u8] = include_bytes!("../../../assets/app-icon/hicolor/256x256/apps/ai.storyteller.lightcraft.png"); + let png: &[u8] = include_bytes!("../../../assets/app-icon/hicolor/256x256/apps/app.png"); eframe::icon_data::from_png_bytes(png).unwrap_or_default() } @@ -81,8 +81,8 @@ impl eframe::App for App { } } -/// The window's renderer (egui-wgpu): eframe's defaults, with LightCraft's backend choice — DX12 -/// alone on Windows unless `LIGHTCRAFT_GPU_BACKEND` / `WGPU_BACKEND` say otherwise (issue #136: +/// The window's renderer (egui-wgpu): eframe's defaults, with the app's backend choice — DX12 +/// alone on Windows unless `_GPU_BACKEND` / `WGPU_BACKEND` say otherwise (issue #136: /// with Vulkan in the set, wgpu loads the Vulkan driver even when it then picks DX12) — and DX12 /// shaders compiled with FXC, never a stray `dxcompiler.dll` (issue #471). fn window_wgpu_options() -> eframe::egui_wgpu::WgpuConfiguration { @@ -95,9 +95,9 @@ fn window_wgpu_options() -> eframe::egui_wgpu::WgpuConfiguration { } /// Written while the GPU compute device is created, removed once that returned -/// (`dac_gpu::backend::set_init_marker`). Not with `LIGHTCRAFT_NO_PREFS` (tests, scripts). +/// (`dac_gpu::backend::set_init_marker`). Not with `_NO_PREFS` (tests, scripts). fn gpu_marker_path() -> Option { - if std::env::var_os("LIGHTCRAFT_NO_PREFS").is_some() { + if dac_brand::env_is_set("NO_PREFS") { return None; } config_dir().map(|d| d.join("gpu-init.marker")) @@ -126,10 +126,11 @@ fn gpu_crash_check_at(marker: Option, in_memory: bool) -> Op } fn gpu_crash_notice(what: &str) -> String { + let (app, var) = (dac_brand::DISPLAY_NAME, dac_brand::env_var("GPU_BACKEND")); format!( - "LightCraft closed unexpectedly while starting the GPU last time ({what}), so GPU rendering is now off and photos render on the CPU. \ - To try the GPU again, turn on Settings ▸ Performance ▸ Use the GPU for rendering; to try another graphics backend, start LightCraft with \ - LIGHTCRAFT_GPU_BACKEND=dx12, vulkan or off (see docs/gpu-pipeline.md → Troubleshooting)." + "{app} closed unexpectedly while starting the GPU last time ({what}), so GPU rendering is now off and photos render on the CPU. \ + To try the GPU again, turn on Settings ▸ Performance ▸ Use the GPU for rendering; to try another graphics backend, start {app} with \ + {var}=dx12, vulkan or off (see docs/gpu-pipeline.md → Troubleshooting)." ) } @@ -138,9 +139,9 @@ fn config_dir() -> Option { } /// `/ui.json`, the saved UI state and app settings — `None` when nothing is read or -/// written: `LIGHTCRAFT_NO_PREFS` (tests, scripts) or no home folder. +/// written: `_NO_PREFS` (tests, scripts) or no home folder. fn prefs_path() -> Option { - if std::env::var_os("LIGHTCRAFT_NO_PREFS").is_some() { + if dac_brand::env_is_set("NO_PREFS") { return None; } config_dir().map(|d| d.join("ui.json")) @@ -222,7 +223,7 @@ fn write_atomic(path: &std::path::Path, bytes: &[u8]) -> std::io::Result<()> { /// library it opened is saved then). #[derive(Default)] struct PrefsWriter { - /// Where to write; `None` writes nothing (`--memory`, `LIGHTCRAFT_NO_PREFS`, no home folder). + /// Where to write; `None` writes nothing (`--memory`, `_NO_PREFS`, no home folder). path: Option, written: Vec, library: String, @@ -270,7 +271,7 @@ impl PrefsWriter { Err(e) => { if !self.failing { log::warn!("{e}"); - app.notices.push(format!("{e}. LightCraft keeps trying.")); + app.notices.push(format!("{e}. {} keeps trying.", dac_brand::DISPLAY_NAME)); } self.failing = true; // don't retry every frame @@ -467,7 +468,7 @@ fn services(ctx: egui::Context, log_file: Option<&std::path::Path>) -> Services save_preset_file: Some(Box::new(|name: &str| { rfd::FileDialog::new() .set_title(dac_ui_egui::i18n::tr("Export Presets")) - .add_filter_nocase(dac_ui_egui::i18n::tr("LightCraft Preset"), &["lcpreset"]) + .add_filter_nocase(dac_ui_egui::i18n::tr("{app} Preset"), &[dac_brand::PRESET_EXT]) .set_file_name(name) .save_file() .map(|p| p.to_string_lossy().to_string()) @@ -520,7 +521,7 @@ fn open_library_session(in_memory: bool, dir: Option, seed_d } let unopened = || Session::new().with_fs().with_default_denoise_models().with_system_clock(); let Some(dir) = dir else { - log::warn!("no library location (set --library or LIGHTCRAFT_LIBRARY)"); + log::warn!("no library location (set --library or {})", dac_brand::env_var("LIBRARY")); return (unopened(), Some(LibraryProblem::new("", "There is no home folder to keep the library in. Choose a folder for it."))); }; let t0 = std::time::Instant::now(); @@ -544,30 +545,38 @@ fn open_library_session(in_memory: bool, dir: Option, seed_d } } +/// `--help` text; `{bin}`, `{app}`, `{P}` and `{lib}` are filled by [`help`]. const HELP: &str = "\ -lightcraft — photo library + raw developer +{bin} — photo library + raw developer -USAGE: lightcraft [OPTIONS] [FILES/FOLDERS…] (files and folders are imported) +USAGE: {bin} [OPTIONS] [FILES/FOLDERS…] (files and folders are imported) OPTIONS: - --library DIR open (or create) this library (default: ~/Pictures/LightCraft Library; env LIGHTCRAFT_LIBRARY) + --library DIR open (or create) this library (default: ~/Pictures/{lib}; env {P}_LIBRARY) --no-demo don't seed a new library with the procedural demo photos --memory throwaway in-memory session (alias --demo); nothing is saved - --control PORT serve the JSON-lines control channel on 127.0.0.1:PORT (env LIGHTCRAFT_CONTROL_PORT; + --control PORT serve the JSON-lines control channel on 127.0.0.1:PORT (env {P}_CONTROL_PORT; see docs/control-protocol.md) --version, --help ENVIRONMENT: - LIGHTCRAFT_GPU_BACKEND=dx12|vulkan|metal|auto|off graphics backend (default: DX12 on Windows, Metal on macOS, - Vulkan on Linux; off = render on the CPU); else WGPU_BACKEND. LIGHTCRAFT_GPU=0: CPU rendering. - LIGHTCRAFT_SAM3_DIR=DIR the SAM 3 model for Object / Describe masks (default: /models/sam3; - optional: LightCraft offers to download it when first needed) - LIGHTCRAFT_SAM3_MIRRORS=URL,… where to download the SAM 3 model from (base URLs, tried in order) - LIGHTCRAFT_LOG=info|debug more log detail from LightCraft itself (default: info from LightCraft, warnings + {P}_GPU_BACKEND=dx12|vulkan|metal|auto|off graphics backend (default: DX12 on Windows, Metal on macOS, + Vulkan on Linux; off = render on the CPU); else WGPU_BACKEND. {P}_GPU=0: CPU rendering. + {P}_SAM3_DIR=DIR the SAM 3 model for Object / Describe masks (default: /models/sam3; + optional: {app} offers to download it when first needed) + {P}_SAM3_MIRRORS=URL,… where to download the SAM 3 model from (base URLs, tried in order) + {P}_LOG=info|debug more log detail from {app} itself (default: info from {app}, warnings from other crates); else RUST_LOG=. Records go to stderr and to - /logs/lightcraft.log (previous runs: lightcraft.1.log, lightcraft.2.log) + /logs/{bin}.log (previous runs: {bin}.1.log, {bin}.2.log) "; +fn help() -> String { + HELP.replace("{bin}", dac_brand::BINARY) + .replace("{lib}", dac_brand::LIBRARY_DEFAULT) + .replace("{P}", dac_brand::ENV_PREFIX) + .replace("{app}", dac_brand::DISPLAY_NAME) +} + /// The launch arguments' files and folders to import (absolute), and a notice for each one that /// is not imported (see [`dac_engine::import::launch_path`]; issue #374). fn launch_imports(args: &[String]) -> (Vec, Vec) { @@ -594,9 +603,9 @@ fn launch_imports_in(args: &[String], cwd: Option<&std::path::Path>, home: Optio } /// Where the log files live: `logs` in the settings folder, next to `ui.json` (see `logging`). -/// None with `LIGHTCRAFT_NO_PREFS` (tests, scripts), so those runs don't rotate away the user's logs. +/// None with `_NO_PREFS` (tests, scripts), so those runs don't rotate away the user's logs. fn log_dir() -> Option { - if std::env::var_os("LIGHTCRAFT_NO_PREFS").is_some() { + if dac_brand::env_is_set("NO_PREFS") { return None; } config_dir().map(|d| d.join("logs")) @@ -616,12 +625,12 @@ fn control_port_from(what: &str, value: Option) -> Option { fn main() -> eframe::Result { // First, so every start-up record is kept for the log file (`logging`). let logger = logging::install(); - dac_engine::guard::install_hook(std::env::temp_dir().join("lightcraft-panics.log")); + dac_engine::guard::install_hook(std::env::temp_dir().join(format!("{}-panics.log", dac_brand::BINARY))); if let Some(logger) = logger { logging::record_panics(logger); } alloc_release::install(); - let mut control_port = control_port_from("LIGHTCRAFT_CONTROL_PORT", std::env::var("LIGHTCRAFT_CONTROL_PORT").ok().filter(|v| !v.is_empty())); + let mut control_port = control_port_from(&dac_brand::env_var("CONTROL_PORT"), dac_brand::env("CONTROL_PORT").filter(|v| !v.is_empty())); let mut files = Vec::new(); let mut seed_demo = true; let mut in_memory = false; @@ -634,15 +643,15 @@ fn main() -> eframe::Result { "--no-demo" => seed_demo = false, "--memory" | "--demo" => in_memory = true, "--version" => { - println!("lightcraft {}", env!("CARGO_PKG_VERSION")); + println!("{} {}", dac_brand::BINARY, env!("CARGO_PKG_VERSION")); return Ok(()); } "-h" | "--help" => { - print!("{HELP}"); + print!("{}", help()); return Ok(()); } o if o.starts_with("--") => { - eprintln!("lightcraft: unknown option `{o}`\n\n{HELP}"); + eprintln!("{}: unknown option `{o}`\n\n{}", dac_brand::BINARY, help()); std::process::exit(2); } _ => files.push(a), @@ -656,7 +665,7 @@ fn main() -> eframe::Result { match log_dir().filter(|_| !in_memory) { Some(dir) => match logger.attach_dir(&dir) { Ok(path) => { - log::info!("LightCraft {}, log file {}", env!("CARGO_PKG_VERSION"), path.display()); + log::info!("{} {}, log file {}", dac_brand::DISPLAY_NAME, env!("CARGO_PKG_VERSION"), path.display()); log_file = Some(path); } // The file sink has given up by now, so this goes to standard error only. @@ -665,6 +674,14 @@ fn main() -> eframe::Result { None => logger.no_file(), } } + // first start under this name: copy the settings folder of a previous name (never moved) + if !in_memory && !dac_brand::env_is_set("NO_PREFS") { + match dac_brand::migrate_legacy_settings() { + Ok(Some(from)) => log::info!("settings copied from {}", from.display()), + Ok(None) => {} + Err(e) => log::warn!("could not copy the previous settings folder: {e}"), + } + } // what the arguments name, resolved now: an empty or relative argument never becomes a drive // root, and a whole drive or home folder is not walked (issue #374) let (files, launch_notices) = launch_imports(&files); @@ -675,11 +692,7 @@ fn main() -> eframe::Result { } // --library, else the library last opened from Settings, else the default location let library_dir = library_dir.or_else(|| { - prefs - .as_ref() - .map(|u| u.settings.library_path.clone()) - .filter(|p| !p.is_empty() && std::env::var_os("LIGHTCRAFT_LIBRARY").is_none()) - .map(Into::into) + prefs.as_ref().map(|u| u.settings.library_path.clone()).filter(|p| !p.is_empty() && !dac_brand::env_is_set("LIBRARY")).map(Into::into) }); let library_dir = library_dir.or_else(dac_engine::library::default_dir); // GPU compute: off if the preference says so, or if the last launch died creating the device @@ -689,7 +702,7 @@ fn main() -> eframe::Result { dac_engine::gpu::set_enabled(gpu_on); let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() - .with_title("LightCraft") + .with_title(dac_brand::DISPLAY_NAME) .with_inner_size([1600.0, 1000.0]) .with_min_inner_size([900.0, 560.0]) .with_drag_and_drop(true) @@ -697,7 +710,7 @@ fn main() -> eframe::Result { .with_titlebar_shown(false) .with_title_shown(false) .with_icon(app_icon()) - // Wayland matches the window to packaging/linux/ai.storyteller.lightcraft.desktop by this id + // Wayland matches the window to the packaged `.desktop` file by this id .with_app_id(APP_ID), wgpu_options: window_wgpu_options(), ..Default::default() @@ -705,15 +718,15 @@ fn main() -> eframe::Result { // the app's copy: `log_file` is still named in the message of a start that fails let app_log_file = log_file.clone(); let started = eframe::run_native( - "LightCraft", + dac_brand::DISPLAY_NAME, options, Box::new(move |cc| { let (mut session, problem) = open_session(in_memory, library_dir, seed_demo && files.is_empty()); - // AI masks: the SAM 3 checkpoint (facebook/sam3) in /models/sam3, or LIGHTCRAFT_SAM3_DIR + // AI masks: the SAM 3 checkpoint (facebook/sam3) in /models/sam3, or _SAM3_DIR // (never required: without it, AI masks offer to download it; see docs/ai-masks.md) session.segmenter.dir = - std::env::var_os("LIGHTCRAFT_SAM3_DIR").map(std::path::PathBuf::from).or_else(|| config_dir().map(|d| d.join("models").join("sam3"))); - // the user's own download locations, one base URL per line (LIGHTCRAFT_SAM3_MIRRORS too) + dac_brand::env_os("SAM3_DIR").map(std::path::PathBuf::from).or_else(|| config_dir().map(|d| d.join("models").join("sam3"))); + // the user's own download locations, one base URL per line (_SAM3_MIRRORS too) session.segmenter.mirrors_file = config_dir().map(|d| d.join("models").join("sam3-mirrors.txt")); let mut app = DacApp::new(session, services(cc.egui_ctx.clone(), app_log_file.as_deref())); if let Some(ui) = prefs { @@ -754,9 +767,9 @@ fn main() -> eframe::Result { app.ui.view = dac_ui_egui::state::ViewMode::PhotoGrid; } // native menu bar generated from the command registry (macOS; elsewhere the menus are - // drawn in the window's top bar). LIGHTCRAFT_NO_NATIVE_MENU=1 keeps the in-window menus. + // drawn in the window's top bar). _NO_NATIVE_MENU=1 keeps the in-window menus. #[cfg(target_os = "macos")] - let menu = (std::env::var_os("LIGHTCRAFT_NO_NATIVE_MENU").is_none()).then(|| native_menu::NativeMenu::install(&mut app, &cc.egui_ctx)); + let menu = (!dac_brand::env_is_set("NO_NATIVE_MENU")).then(|| native_menu::NativeMenu::install(&mut app, &cc.egui_ctx)); Ok(Box::new(App( app, writer, @@ -775,8 +788,8 @@ fn main() -> eframe::Result { /// message box naming the log file, instead of exiting without a trace — the release builds have /// no console on Windows, and an app started from Finder shows no standard error (issue #260). fn startup_failed(error: &str, log_file: Option<&std::path::Path>) { - log::error!("LightCraft could not open its window: {error}"); - if std::env::var_os("LIGHTCRAFT_NO_PREFS").is_some() { + log::error!("{} could not open its window: {error}", dac_brand::DISPLAY_NAME); + if dac_brand::env_is_set("NO_PREFS") { return; // tests and scripts: no dialog to click away } let (title, text) = dac_ui_egui::i18n::startup_failed_message(error, log_file.map(|p| p.display().to_string()).as_deref()); @@ -929,7 +942,7 @@ mod tests { fn window_backends_follow_the_platform_default() { let eframe::egui_wgpu::WgpuSetup::CreateNew(n) = window_wgpu_options().wgpu_setup else { panic!("expected CreateNew") }; let b = n.instance_descriptor.backends; - if std::env::var_os("LIGHTCRAFT_GPU_BACKEND").is_none() && std::env::var_os("WGPU_BACKEND").is_none() { + if !dac_brand::env_is_set("GPU_BACKEND") && std::env::var_os("WGPU_BACKEND").is_none() { if cfg!(windows) { assert_eq!(b, eframe::wgpu::Backends::DX12); } else if cfg!(target_os = "macos") { @@ -984,7 +997,7 @@ mod tests { assert_eq!(control_port_from("--control", Some("nope".into())), None); assert_eq!(control_port_from("--control", Some(String::new())), None); assert_eq!(control_port_from("--control", Some("70000".into())), None); - assert_eq!(control_port_from("LIGHTCRAFT_CONTROL_PORT", None), None); + assert_eq!(control_port_from("CONTROL_PORT", None), None); } #[test] diff --git a/apps/app/src/native_menu.rs b/apps/app/src/native_menu.rs index 999bc059cd..85b9c1d374 100644 --- a/apps/app/src/native_menu.rs +++ b/apps/app/src/native_menu.rs @@ -227,10 +227,10 @@ impl NativeMenu { self.items.clear(); // the application menu - let app_menu = Submenu::new("LightCraft", true); - let about = MenuItem::with_id("app.about", dac_ui_egui::i18n::tr("About LightCraft"), true, None); + let app_menu = Submenu::new(dac_brand::SHORT_NAME, true); + let about = MenuItem::with_id("app.about", dac_brand::fill(&dac_ui_egui::i18n::tr("About {app}")), true, None); let settings = MenuItem::with_id(SETTINGS, dac_ui_egui::i18n::tr("Settings…"), true, accelerator(SETTINGS_KEY)); - let quit = MenuItem::with_id(QUIT, dac_ui_egui::i18n::tr("Quit LightCraft"), true, accelerator("Cmd+Q")); + let quit = MenuItem::with_id(QUIT, dac_brand::fill(&dac_ui_egui::i18n::tr("Quit {app}")), true, accelerator("Cmd+Q")); let _ = app_menu.append_items(&[ &about, &PredefinedMenuItem::separator(), @@ -238,7 +238,7 @@ impl NativeMenu { &PredefinedMenuItem::separator(), &PredefinedMenuItem::services(Some(dac_ui_egui::i18n::tr("Services"))), &PredefinedMenuItem::separator(), - &PredefinedMenuItem::hide(Some(dac_ui_egui::i18n::tr("Hide LightCraft"))), + &PredefinedMenuItem::hide(Some(dac_brand::fill(&dac_ui_egui::i18n::tr("Hide {app}")))), &PredefinedMenuItem::hide_others(Some(dac_ui_egui::i18n::tr("Hide Others"))), &PredefinedMenuItem::show_all(Some(dac_ui_egui::i18n::tr("Show All"))), &PredefinedMenuItem::separator(), @@ -457,7 +457,7 @@ mod tests { set_language(Locale::ZhHant); assert_eq!(label_text("File"), "檔案"); assert_eq!(label_text("Settings…"), "設定…"); - assert_eq!(label_text("Quit LightCraft"), "結束 LightCraft"); + assert_eq!(dac_brand::fill(&label_text("Quit {app}")), dac_brand::fill("結束 {app}")); set_language(Locale::En); } diff --git a/apps/cli/Cargo.toml b/apps/cli/Cargo.toml index f5834b79a2..db82bbc354 100644 --- a/apps/cli/Cargo.toml +++ b/apps/cli/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true publish = false -description = "LightCraft command-line tool: headless render, command listing and the MCP server" +description = "Command-line tool: headless render, command listing and the MCP server" [[bin]] name = "app-cli" @@ -14,9 +14,11 @@ path = "src/main.rs" workspace = true [dependencies] +dac-brand = { workspace = true } dac-engine = { workspace = true } dac-sysmem = { workspace = true } dac-mcp = { workspace = true } +log = { workspace = true } dac-ui-egui = { workspace = true } dac-codecs = { workspace = true } dac-raster = { workspace = true } diff --git a/apps/cli/src/main.rs b/apps/cli/src/main.rs index 0cb3b6995a..4878613c37 100644 --- a/apps/cli/src/main.rs +++ b/apps/cli/src/main.rs @@ -1,15 +1,15 @@ -//! `lightcraft-cli`: headless LightCraft. +//! The command-line tool (`dac_brand::CLI_BINARY`): the app, headless. //! //! ```text -//! lightcraft-cli run [--demo | --library DIR | --connect [ADDR]] [--import PATH]… CMD [key=value…]… -//! lightcraft-cli mcp [--connect [ADDR]] [--demo] [--compact] [FILES/FOLDERS…] -//! lightcraft-cli render -o [--set control=value]… [--settings FILE.json] [--preset ID] [--size N] [--quality Q] -//! lightcraft-cli snapshot [--library DIR | --demo] [--script FILE.jsonl] [-o OUT.png] [--size WxH] [--scale S] [FILES…] -//! lightcraft-cli merge hdr|panorama|hdr-panorama [OPTIONS] FILES… -//! lightcraft-cli synth-merge hdr|panorama -o DIR -//! lightcraft-cli commands [--json] -//! lightcraft-cli controls [--json] -//! lightcraft-cli calibrate [--max N] [--out DIR] FOLDERS/FILES… +//! run [--demo | --library DIR | --connect [ADDR]] [--import PATH]… CMD [key=value…]… +//! mcp [--connect [ADDR]] [--demo] [--compact] [FILES/FOLDERS…] +//! render -o [--set control=value]… [--settings FILE.json] [--preset ID] [--size N] [--quality Q] +//! snapshot [--library DIR | --demo] [--script FILE.jsonl] [-o OUT.png] [--size WxH] [--scale S] [FILES…] +//! merge hdr|panorama|hdr-panorama [OPTIONS] FILES… +//! synth-merge hdr|panorama -o DIR +//! commands [--json] +//! controls [--json] +//! calibrate [--max N] [--out DIR] FOLDERS/FILES… //! ``` #![forbid(unsafe_code)] #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] @@ -24,33 +24,34 @@ use dac_engine::Session; use dac_mcp::{Backend, DEFAULT_ADDR, Headless, Remote, Server, expand_paths}; use serde_json::{Value, json}; +/// `--help` text; `{cli}`, `{bin}`, `{app}` and `{P}` are filled by [`usage`]. const USAGE: &str = "\ -lightcraft-cli — headless LightCraft (photo library + raw developer) +{cli} — headless {app} (photo library + raw developer) USAGE: - lightcraft-cli run [OPTIONS] COMMAND [key=value | '{json}']… [COMMAND …]… + {cli} run [OPTIONS] COMMAND [key=value | '{json}']… [COMMAND …]… Run one or more commands (ids from `commands`, or control-protocol methods such as engine.commands / ui.inspect / ui.screenshot) and print one JSON line per command: {\"command\", \"ok\", \"result\" | \"error\", \"ms\"}. A word without `=` starts the next command; values are JSON when they parse (1, true, [1,2], {…}), else strings. Exit status is non-zero when a command fails. Example: - lightcraft-cli run --import ~/Photos/a.jpg develop.set control=light.exposure value=0.7 \\ + {cli} run --import ~/Photos/a.jpg develop.set control=light.exposure value=0.7 \\ develop.auto app.export path=/tmp/a.jpg longEdge=1600 Options: --demo headless, the procedural demo library - --library DIR headless, open (or create) a LightCraft library; edits are saved + --library DIR headless, open (or create) a {app} library; edits are saved --import PATH headless, import a file or folder first (repeatable) - --connect [ADDR] drive the running app (`lightcraft --control 7980`; default 127.0.0.1:7980) + --connect [ADDR] drive the running app (`{bin} --control 7980`; default 127.0.0.1:7980) --script FILE|- also run JSON lines {\"command\": id, \"params\": {…}} (or {\"method\": …}) --keep-going continue after a failed command - lightcraft-cli mcp [OPTIONS] [FILES/FOLDERS…] + {cli} mcp [OPTIONS] [FILES/FOLDERS…] MCP server (JSON-RPC 2.0 over stdio). Headless by default: an in-process session with the given files imported. Options: - --connect [ADDR] drive a running app instead (`lightcraft --control 7980`; default 127.0.0.1:7980) + --connect [ADDR] drive a running app instead (`{bin} --control 7980`; default 127.0.0.1:7980) --demo headless: start with the procedurally generated demo library - --library DIR headless: open (or create) a persistent LightCraft library; edits are saved + --library DIR headless: open (or create) a persistent {app} library; edits are saved --compact list only the helper tools (every command stays reachable via run_command) - lightcraft-cli render -o [OPTIONS] + {cli} render -o [OPTIONS] Develop one file and export it (.jpg, .png, .tif, .webp, .avif or .dng by extension) with the same encoder as the app's Export dialog. Options: --set CONTROL=VALUE set a develop slider, repeatable (e.g. --set light.exposure=0.5) @@ -62,11 +63,11 @@ USAGE: string), e.g. --opt colorSpace=displayP3 --opt bitDepth=16 --opt percent=50 --opt shortEdge=1080 --opt ppi=300 --opt format=original (copy + XMP sidecar) --opt metadata=none - lightcraft-cli snapshot [OPTIONS] [FILES/FOLDERS…] + {cli} snapshot [OPTIONS] [FILES/FOLDERS…] Run the full app UI headlessly (no window, no GPU: CPU-rasterized egui) and write PNGs. Options: --demo the procedural demo library (default unless --library or FILES) - --library DIR open (or create) a LightCraft library + --library DIR open (or create) a {app} library --script FILE JSON-lines control-protocol requests (docs/control-protocol.md), one per line: {\"method\": \"ui.set\", \"params\": {\"view\": \"detail\"}}. Replies go to stdout. `ui.screenshot` without a path writes -o (then @@ -76,26 +77,35 @@ USAGE: -o, --output OUT PNG path (a final screenshot is written here if the script took none) --size WxH window size in points (default 1600x1000) --scale S pixels per point (default 1) - lightcraft-cli merge hdr|panorama|hdr-panorama [OPTIONS] FILES… + {cli} merge hdr|panorama|hdr-panorama [OPTIONS] FILES… Photo Merge: writes -HDR.dng / -Pano.dng / -HDR-Pano.dng next to the first file and prints the result as JSON. Options: --deghost none|low|medium|high --no-align --bracket N (HDR panorama) --projection auto|spherical|cylindrical|perspective --boundary-warp 0..100 --auto-crop --fill-edges --no-auto-settings --preview OUT.png only render a ≤ 1024 px preview (nothing written next to the files) - lightcraft-cli synth-merge hdr|panorama -o DIR + {cli} synth-merge hdr|panorama -o DIR Write synthetic merge inputs (procedural scene; bracketed DNGs or overlapping PNG views). - lightcraft-cli commands [--json] list every command id with its parameters - lightcraft-cli controls [--json] list every develop control id with its range - lightcraft-cli calibrate [--max N] [--out DIR] FOLDERS/FILES… + {cli} commands [--json] list every command id with its parameters + {cli} controls [--json] list every develop control id with its range + {cli} calibrate [--max N] [--out DIR] FOLDERS/FILES… Fit a colour profile per camera model from raw files and their embedded camera JPEGs (Sony ARW, Nikon NEF, Fujifilm RAF): up to N files spread over the folders (default 300; 0 = all), pooled per - model, written as .json to DIR (default: the profiles folder LightCraft reads, - /camera-profiles, or $LIGHTCRAFT_CAMERA_PROFILES). Raws of a profiled model then + model, written as .json to DIR (default: the profiles folder {app} reads, + /camera-profiles, or ${P}_CAMERA_PROFILES). Raws of a profiled model then take their colour from the profile and only their tone from their own JPEG. - lightcraft-cli --version | --help + {cli} --version | --help "; +fn usage() -> String { + USAGE.replace("{cli}", CLI).replace("{bin}", dac_brand::BINARY).replace("{P}", dac_brand::ENV_PREFIX).replace("{app}", APP) +} + +/// The command name shown in messages and `--help`. +const CLI: &str = dac_brand::CLI_BINARY; +const APP: &str = dac_brand::DISPLAY_NAME; +const BIN: &str = dac_brand::BINARY; + #[cfg(feature = "dhat-heap")] #[global_allocator] static ALLOC: dhat::Alloc = dhat::Alloc; @@ -113,7 +123,7 @@ fn library_warnings(session: &mut Session, who: &str) { fn library_error(dir: &str, e: dac_engine::EngineError) -> String { match e { dac_engine::EngineError::LibraryInUse(why) => format!( - "{dir}: {why}\nTo work with the library while the app has it open, start the app with `--control PORT` and use `lightcraft-cli mcp --connect 127.0.0.1:PORT`." + "{dir}: {why}\nTo work with the library while the app has it open, start the app with `--control PORT` and use `{CLI} mcp --connect 127.0.0.1:PORT`." ), e => format!("{dir}: {e}"), } @@ -121,10 +131,10 @@ fn library_error(dir: &str, e: dac_engine::EngineError) -> String { fn main() -> ExitCode { // `--features dhat-heap`: count allocations; the profile is written when `_heap` drops - // (LIGHTCRAFT_DHAT_FILE, default dhat-heap.json). + // (_DHAT_FILE, default dhat-heap.json). #[cfg(feature = "dhat-heap")] let _heap = { - let file = std::env::var("LIGHTCRAFT_DHAT_FILE").unwrap_or_else(|_| "dhat-heap.json".into()); + let file = dac_brand::env("DHAT_FILE").unwrap_or_else(|| "dhat-heap.json".into()); dac_engine::memory::set_heap_stats(|| { let s = dhat::HeapStats::get(); dac_engine::memory::HeapUsage { current: s.curr_bytes as u64, peak: s.max_bytes as u64 } @@ -132,9 +142,17 @@ fn main() -> ExitCode { dhat::Profiler::builder().file_name(file).build() }; alloc_release::install(); - // Warnings (a GPU render redone on the CPU, an unknown backend name) on stderr; LIGHTCRAFT_LOG + // Warnings (a GPU render redone on the CPU, an unknown backend name) on stderr; _LOG // or RUST_LOG picks another level (#168). dac_engine::logging::install("dac-cli"); + // first start under this name: copy the settings folder of a previous name (never moved) + if !dac_brand::env_is_set("NO_PREFS") { + match dac_brand::migrate_legacy_settings() { + Ok(Some(from)) => log::info!("settings copied from {}", from.display()), + Ok(None) => {} + Err(e) => log::warn!("could not copy the previous settings folder: {e}"), + } + } let args: Vec = std::env::args().skip(1).collect(); let r = match args.first().map(String::as_str) { Some("run") => run(&args[1..]), @@ -147,19 +165,19 @@ fn main() -> ExitCode { Some("controls") => controls(&args[1..]), Some("calibrate") => calibrate(&args[1..]), Some("--version" | "-V" | "version") => { - println!("lightcraft-cli {}", env!("CARGO_PKG_VERSION")); + println!("{CLI} {}", env!("CARGO_PKG_VERSION")); Ok(()) } Some("--help" | "-h" | "help") | None => { - print!("{USAGE}"); + print!("{}", usage()); Ok(()) } - Some(other) => Err(format!("unknown subcommand `{other}`\n\n{USAGE}")), + Some(other) => Err(format!("unknown subcommand `{other}`\n\n{}", usage())), }; match r { Ok(()) => ExitCode::SUCCESS, Err(e) => { - eprintln!("lightcraft-cli: {e}"); + eprintln!("{CLI}: {e}"); ExitCode::FAILURE } } @@ -310,11 +328,11 @@ fn mcp(args: &[String]) -> Result<(), String> { } match Remote::connect(&addr) { Ok(r) => { - eprintln!("lightcraft-cli mcp: connected to LightCraft at {addr}"); + eprintln!("{CLI} mcp: connected to {APP} at {addr}"); Box::new(r) } Err(e) => { - eprintln!("lightcraft-cli mcp: LightCraft is not reachable at {addr} yet ({e}); will retry on each call"); + eprintln!("{CLI} mcp: {APP} is not reachable at {addr} yet ({e}); will retry on each call"); Box::new(Remote::lazy(&addr)) } } @@ -324,8 +342,8 @@ fn mcp(args: &[String]) -> Result<(), String> { Some(dir) => { let mut h = Headless::default(); let r = h.session.open_library(dir, demo).map_err(|e| library_error(dir, e))?; - eprintln!("lightcraft-cli mcp: opened library {dir} ({r:?})"); - library_warnings(&mut h.session, "lightcraft-cli mcp"); + eprintln!("{CLI} mcp: opened library {dir} ({r:?})"); + library_warnings(&mut h.session, &format!("{CLI} mcp")); h } None if demo => Headless::demo(), @@ -334,12 +352,12 @@ fn mcp(args: &[String]) -> Result<(), String> { if !files.is_empty() { let paths = expand_paths(&files); let r = h.session.execute("library.import", &json!({"paths": paths})).map_err(|e| e.to_string())?; - eprintln!("lightcraft-cli mcp: imported {} photo(s)", r["imported"].as_array().map_or(0, Vec::len)); + eprintln!("{CLI} mcp: imported {} photo(s)", r["imported"].as_array().map_or(0, Vec::len)); } Box::new(h) } }; - eprintln!("lightcraft-cli mcp: serving MCP on stdio ({})", backend.describe()); + eprintln!("{CLI} mcp: serving MCP on stdio ({})", backend.describe()); let mut server = Server::new(backend).with_command_tools(!compact); let stdin = std::io::stdin(); server.serve(BufReader::new(stdin), std::io::stdout()).map_err(|e| e.to_string()) @@ -453,7 +471,7 @@ fn synth_merge(args: &[String]) -> Result<(), String> { Ok(()) } -/// One step of `lightcraft-cli run`: a command id (or control-protocol method) and its params. +/// One step of ` run`: a command id (or control-protocol method) and its params. #[derive(Debug, PartialEq)] struct Step { id: String, @@ -543,42 +561,42 @@ fn run(args: &[String]) -> Result<(), String> { } } if steps.is_empty() { - return Err("run: no command given (see `lightcraft-cli commands`)".into()); + return Err(format!("run: no command given (see `{CLI} commands`)")); } - let mut backend: Box = - match connect { - Some(addr) => { - if demo || library.is_some() || !imports.is_empty() { - return Err("--demo, --library and --import apply to headless mode only".into()); - } - Box::new(Remote::connect(&addr).map_err(|e| { - format!("LightCraft is not reachable at {addr} ({e}); start it with `lightcraft --control {}`", connect_port(&addr)) - })?) + let mut backend: Box = match connect { + Some(addr) => { + if demo || library.is_some() || !imports.is_empty() { + return Err("--demo, --library and --import apply to headless mode only".into()); } - None => { - let mut h = match &library { - Some(dir) => { - let mut h = Headless::default(); - h.session.open_library(dir, demo).map_err(|e| library_error(dir, e))?; - library_warnings(&mut h.session, "dac-cli"); - h - } - None if demo => Headless::demo(), - None => Headless::default(), - }; - if !imports.is_empty() { - let paths = expand_paths(&imports); - let r = h.session.execute("library.import", &json!({"paths": paths})).map_err(|e| e.to_string())?; - // what follows acts on the imported photos (already-known files are reported as duplicates) - let mut ids: Vec = r["imported"].as_array().cloned().unwrap_or_default(); - ids.extend(r["duplicates"].as_array().into_iter().flatten().filter_map(|d| d.get("existing").filter(|v| v.is_u64()).cloned())); - if let Some(first) = ids.first().cloned() { - h.session.execute("library.select", &json!({"ids": ids, "active": first})).map_err(|e| e.to_string())?; - } + Box::new( + Remote::connect(&addr) + .map_err(|e| format!("{APP} is not reachable at {addr} ({e}); start it with `{BIN} --control {}`", connect_port(&addr)))?, + ) + } + None => { + let mut h = match &library { + Some(dir) => { + let mut h = Headless::default(); + h.session.open_library(dir, demo).map_err(|e| library_error(dir, e))?; + library_warnings(&mut h.session, "dac-cli"); + h + } + None if demo => Headless::demo(), + None => Headless::default(), + }; + if !imports.is_empty() { + let paths = expand_paths(&imports); + let r = h.session.execute("library.import", &json!({"paths": paths})).map_err(|e| e.to_string())?; + // what follows acts on the imported photos (already-known files are reported as duplicates) + let mut ids: Vec = r["imported"].as_array().cloned().unwrap_or_default(); + ids.extend(r["duplicates"].as_array().into_iter().flatten().filter_map(|d| d.get("existing").filter(|v| v.is_u64()).cloned())); + if let Some(first) = ids.first().cloned() { + h.session.execute("library.select", &json!({"ids": ids, "active": first})).map_err(|e| e.to_string())?; } - Box::new(h) } - }; + Box::new(h) + } + }; let mut out = std::io::stdout().lock(); let mut failed = 0; for s in &steps { @@ -690,9 +708,9 @@ fn render(args: &[String]) -> Result<(), String> { dac_engine::export::write_file(&output, &e.bytes)?; for (sc, bytes) in &sidecars { dac_engine::export::write_file(sc, bytes)?; - eprintln!("lightcraft-cli: wrote {sc}"); + eprintln!("{CLI}: wrote {sc}"); } - eprintln!("lightcraft-cli: wrote {output} ({}×{})", e.width, e.height); + eprintln!("{CLI}: wrote {output} ({}×{})", e.width, e.height); Ok(()) } @@ -743,7 +761,7 @@ fn snapshot(args: &[String]) -> Result<(), String> { let ti = Instant::now(); let r = session.execute("library.import", &json!({"paths": expand_paths(&files)})).map_err(|e| e.to_string())?; let n = r["imported"].as_array().map_or(0, Vec::len); - eprintln!("lightcraft-cli snapshot: imported {n} files in {:.0} ms", ti.elapsed().as_secs_f64() * 1e3); + eprintln!("{CLI} snapshot: imported {n} files in {:.0} ms", ti.elapsed().as_secs_f64() * 1e3); } let services = dac_ui_egui::Services { write_shared: Some(std::sync::Arc::new(dac_engine::export::write_file)), @@ -819,11 +837,7 @@ fn snapshot(args: &[String]) -> Result<(), String> { } writeln!(out, "{reply}").map_err(|e| e.to_string())?; if method == "ui.screenshot" { - eprintln!( - "lightcraft-cli snapshot: {} ({:.0} ms)", - reply["result"]["path"].as_str().unwrap_or("?"), - ts.elapsed().as_secs_f64() * 1000.0 - ); + eprintln!("{CLI} snapshot: {} ({:.0} ms)", reply["result"]["path"].as_str().unwrap_or("?"), ts.elapsed().as_secs_f64() * 1000.0); } if h.quit_requested() { break; @@ -835,18 +849,18 @@ fn snapshot(args: &[String]) -> Result<(), String> { if r["ok"] != true { return Err(format!("screenshot failed: {}", r["error"])); } - eprintln!("lightcraft-cli snapshot: wrote {path} ({}×{})", r["result"]["width"], r["result"]["height"]); + eprintln!("{CLI} snapshot: wrote {path} ({}×{})", r["result"]["width"], r["result"]["height"]); } // a background export started by the script finishes before we exit (its files would be cut off) if h.app.export.is_some() { - eprintln!("lightcraft-cli snapshot: waiting for the background export"); + eprintln!("{CLI} snapshot: waiting for the background export"); let te = std::time::Instant::now(); while h.app.export.is_some() && te.elapsed() < std::time::Duration::from_secs(3600) { h.step(); std::thread::sleep(std::time::Duration::from_millis(20)); } } - eprintln!("lightcraft-cli snapshot: done in {:.2} s ({} frames)", t0.elapsed().as_secs_f64(), h.frames()); + eprintln!("{CLI} snapshot: done in {:.2} s ({} frames)", t0.elapsed().as_secs_f64(), h.frames()); if failed > 0 { Err(format!("{failed} scripted request(s) failed")) } else { Ok(()) } } diff --git a/apps/cli/tests/cli.rs b/apps/cli/tests/cli.rs index 945b09c7e5..e5ff5f3036 100644 --- a/apps/cli/tests/cli.rs +++ b/apps/cli/tests/cli.rs @@ -1,4 +1,4 @@ -//! End-to-end tests of the `lightcraft-cli` binary: `mcp` over real stdio pipes, `render`, `commands`. +//! End-to-end tests of the command-line binary: `mcp` over real stdio pipes, `render`, `commands`. use std::io::{BufRead, BufReader, Write}; use std::process::{Command, Stdio}; @@ -8,7 +8,7 @@ use serde_json::{Value, json}; const BIN: &str = env!("CARGO_BIN_EXE_app-cli"); fn tmp(name: &str) -> std::path::PathBuf { - let d = std::env::temp_dir().join(format!("lightcraft-cli-test-{}", std::process::id())); + let d = std::env::temp_dir().join(format!("app-cli-test-{}", std::process::id())); std::fs::create_dir_all(&d).unwrap(); d.join(name) } @@ -267,8 +267,8 @@ fn snapshot_defaults_to_cpu_without_gpu_environment_overrides() { .unwrap(); let image = tmp("default-cpu.png"); let output = Command::new(BIN) - .env_remove("LIGHTCRAFT_GPU") - .env_remove("LIGHTCRAFT_GPU_BACKEND") + .env_remove(dac_brand::env_var("GPU")) + .env_remove(dac_brand::env_var("GPU_BACKEND")) .env_remove("WGPU_BACKEND") .args(["snapshot", "--demo", "--script", script.to_str().unwrap(), "-o", image.to_str().unwrap(), "--size", "480x320"]) .output() @@ -300,12 +300,13 @@ fn snapshot_starts_without_a_gpu() { ), ) .unwrap(); - for (var, value, reason) in [("LIGHTCRAFT_GPU", "0", "LIGHTCRAFT_GPU=0"), ("LIGHTCRAFT_GPU_BACKEND", "off", "LIGHTCRAFT_GPU_BACKEND=off")] { + for (var, value) in [(dac_brand::env_var("GPU"), "0"), (dac_brand::env_var("GPU_BACKEND"), "off")] { + let reason = format!("{var}={value}"); let out = tmp(&format!("nogpu-{var}.png")); let o = Command::new(BIN) - .env_remove("LIGHTCRAFT_GPU") - .env_remove("LIGHTCRAFT_GPU_BACKEND") - .env(var, value) + .env_remove(dac_brand::env_var("GPU")) + .env_remove(dac_brand::env_var("GPU_BACKEND")) + .env(&var, value) .args(["snapshot", "--demo", "--script", script.to_str().unwrap(), "-o", out.to_str().unwrap(), "--size", "480x320"]) .output() .unwrap(); @@ -315,7 +316,7 @@ fn snapshot_starts_without_a_gpu() { let gpu = &replies[1]["result"]; assert_eq!(gpu["available"], false, "{var}: {gpu}"); assert_eq!(gpu["adapter"], Value::Null, "{var}: no device was created: {gpu}"); - assert!(gpu["reason"].as_str().is_some_and(|r| r.contains(reason)), "{var}: {gpu}"); + assert!(gpu["reason"].as_str().is_some_and(|r| r.contains(&reason)), "{var}: {gpu}"); let d = dac_codecs::decode(&std::fs::read(&out).unwrap(), Default::default()).unwrap(); assert_eq!((d.width, d.height), (480, 320)); } @@ -387,7 +388,7 @@ fn devices_are_listed_and_imported_from() { let _ = std::fs::remove_dir_all(&base); std::fs::create_dir_all(base.join("CARD/DCIM/100TEST")).unwrap(); gradient_png(&base.join("CARD/DCIM/100TEST/IMG_0001.png")); - let o = Command::new(BIN).env("LIGHTCRAFT_DEVICE_ROOTS", &base).args(["run", "--demo", "library.devices"]).output().unwrap(); + let o = Command::new(BIN).env(dac_brand::env_var("DEVICE_ROOTS"), &base).args(["run", "--demo", "library.devices"]).output().unwrap(); assert!(o.status.success(), "{}", String::from_utf8_lossy(&o.stderr)); let line: Value = serde_json::from_slice(o.stdout.split(|b| *b == b'\n').next().unwrap()).unwrap(); let dev = &line["result"][0]; @@ -418,7 +419,7 @@ fn a_library_open_in_another_process_is_refused() { } let (ok, _, stderr) = run_cli(&["--library", lib_s, "library.info"], None); assert!(!ok); - assert!(stderr.contains("already open in lightcraft-cli") && stderr.contains(&format!("process {}", holder.id())), "{stderr}"); + assert!(stderr.contains("already open in ") && stderr.contains(&format!("process {}", holder.id())), "{stderr}"); assert!(stderr.contains("mcp --connect"), "{stderr}"); drop(holder.stdin.take()); // EOF: the server exits and lets go of the library @@ -449,10 +450,10 @@ fn warnings_are_logged_on_stderr() { let run = |level: &str| { let o = Command::new(BIN) .args(["render", input.to_str().unwrap(), "-o", out.to_str().unwrap()]) - .env("LIGHTCRAFT_GPU_BACKEND", "bogus") + .env(dac_brand::env_var("GPU_BACKEND"), "bogus") .env("RUST_LOG", level) - .env_remove("LIGHTCRAFT_LOG") - .env_remove("LIGHTCRAFT_GPU") + .env_remove(dac_brand::env_var("LOG")) + .env_remove(dac_brand::env_var("GPU")) .output() .unwrap(); let stderr = String::from_utf8_lossy(&o.stderr).into_owned(); @@ -460,7 +461,7 @@ fn warnings_are_logged_on_stderr() { stderr }; let warn = run("warn"); - assert!(warn.contains("LIGHTCRAFT_GPU_BACKEND=bogus names no known backend"), "{warn}"); + assert!(warn.contains(&format!("{}=bogus names no known backend", dac_brand::env_var("GPU_BACKEND"))), "{warn}"); let off = run("off"); assert!(!off.contains("names no known backend"), "{off}"); } @@ -481,8 +482,12 @@ fn snapshot_rejects_invalid_dimensions_before_creating_an_image() { #[test] fn snapshot_preserves_fractional_scale_rounding() { let image = tmp("fractional-scale-rounding.png"); - let output = - Command::new(BIN).env("LIGHTCRAFT_GPU", "0").args(["snapshot", "--size", "345x200", "--scale", "0.9", "-o"]).arg(&image).output().unwrap(); + let output = Command::new(BIN) + .env(dac_brand::env_var("GPU"), "0") + .args(["snapshot", "--size", "345x200", "--scale", "0.9", "-o"]) + .arg(&image) + .output() + .unwrap(); assert!(output.status.success(), "{}", String::from_utf8_lossy(&output.stderr)); let decoded = dac_codecs::decode(&std::fs::read(image).unwrap(), Default::default()).unwrap(); assert_eq!((decoded.width, decoded.height), (311, 180)); @@ -498,7 +503,7 @@ fn snapshot_leaves_desktop_gpu_preferences_untouched() { session.open_library(&library, true).unwrap(); drop(session); let config = dir.join("config"); - let app_config = config.join("lightcraft"); + let app_config = config.join(dac_brand::settings_dir_name(dac_brand::SETTINGS_DIR)); std::fs::create_dir_all(&app_config).unwrap(); let ui_path = app_config.join("ui.json"); let mut ui = dac_ui_egui::UiState::default(); @@ -514,9 +519,12 @@ fn snapshot_leaves_desktop_gpu_preferences_untouched() { for gpu_environment in [None, Some("1")] { let image = dir.join(format!("{}.png", gpu_environment.unwrap_or("default"))); let mut cmd = Command::new(BIN); - cmd.env("XDG_CONFIG_HOME", &config).env_remove("LIGHTCRAFT_GPU").env_remove("LIGHTCRAFT_GPU_BACKEND").env_remove("WGPU_BACKEND"); + cmd.env("XDG_CONFIG_HOME", &config) + .env_remove(dac_brand::env_var("GPU")) + .env_remove(dac_brand::env_var("GPU_BACKEND")) + .env_remove("WGPU_BACKEND"); if let Some(value) = gpu_environment { - cmd.env("LIGHTCRAFT_GPU", value); + cmd.env(dac_brand::env_var("GPU"), value); } let output = cmd .args(["snapshot", "--library"]) diff --git a/apps/web/Cargo.toml b/apps/web/Cargo.toml index c45c52573b..c6d297be7a 100644 --- a/apps/web/Cargo.toml +++ b/apps/web/Cargo.toml @@ -4,7 +4,7 @@ version.workspace = true edition.workspace = true license.workspace = true publish = false -description = "LightCraft in the browser: the egui UI compiled to WASM (build with `cargo xtask web`)" +description = "The app in the browser: the egui UI compiled to WASM (build with `cargo xtask web`)" [lints] workspace = true @@ -13,6 +13,7 @@ workspace = true crate-type = ["cdylib", "rlib"] [dependencies] +dac-brand = { workspace = true } dac-engine = { workspace = true } dac-ui-egui = { workspace = true } dac-codecs = { workspace = true } diff --git a/apps/web/index.html b/apps/web/index.html index 6fb74707da..a4388d0a94 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -3,30 +3,30 @@ - LightCraft + Loading… - + - -
Loading LightCraft…
-
+ +
Loading…
+
diff --git a/apps/web/src/backend.rs b/apps/web/src/backend.rs index e20f6dc9c9..2571f4e728 100644 --- a/apps/web/src/backend.rs +++ b/apps/web/src/backend.rs @@ -9,7 +9,7 @@ use wasm_bindgen::{JsCast, JsValue}; use wasm_bindgen_futures::JsFuture; use web_sys::{FileSystemDirectoryHandle, FileSystemFileHandle, FileSystemGetDirectoryOptions, FileSystemGetFileOptions, IdbDatabase}; -const IDB_NAME: &str = "lightcraft"; +const IDB_NAME: &str = crate::legacy::IDB_NAME; const IDB_STORE: &str = "files"; #[derive(Clone)] @@ -339,7 +339,7 @@ pub fn request_persistence(on_result: impl FnOnce(bool) + 'static) { Ok(p) => JsFuture::from(p).await.ok().is_some_and(|v| v.is_truthy()), Err(_) => false, }; - log::info!("lightcraft: persistent storage {}", if granted { "granted" } else { "not granted" }); + log::info!("app: persistent storage {}", if granted { "granted" } else { "not granted" }); on_result(granted); }); } diff --git a/apps/web/src/backup.rs b/apps/web/src/backup.rs index 00ec12a415..5f629ae7fa 100644 --- a/apps/web/src/backup.rs +++ b/apps/web/src/backup.rs @@ -34,11 +34,11 @@ const UTF8: u16 = 0x0800; /// 1980-01-01 00:00 in MS-DOS format (date, time). const DOS_DATE: u16 = (1 << 5) | 1; -/// The readme inside every backup. -pub const README: &str = "LightCraft library backup (browser version)\n\n\ +/// The readme inside every backup (`{app}` is filled with [`dac_brand::fill`]). +pub const README: &str = "{app} library backup (browser version)\n\n\ library/ the catalog (catalog.snap + catalog.log), presets, view state and preferences\n\ originals/ every imported photo, as originals//\n\n\ -Restore it in LightCraft for the web with File > Restore Library from Backup...\n\ +Restore it in {app} for the web with File > Restore Library from Backup...\n\ The photos in originals/ are the untouched files you imported; edits live in the catalog.\n"; /// Is `name` a safe library folder name (`library` or `library-`)? @@ -234,7 +234,7 @@ pub fn data_offset(entry: &ZipEntry, local: &[u8]) -> Result { /// Check an entry's bytes. pub fn verify(entry: &ZipEntry, data: &[u8]) -> Result<(), String> { if entry.method != 0 { - return Err(format!("{}: compressed entries are not supported (not a LightCraft backup?)", entry.name)); + return Err(format!("{}: compressed entries are not supported (not a {} backup?)", entry.name, dac_brand::DISPLAY_NAME)); } if data.len() as u64 != entry.size || crc32fast::hash(data) != entry.crc { return Err(format!("{}: damaged (checksum mismatch)", entry.name)); diff --git a/apps/web/src/bench.rs b/apps/web/src/bench.rs index 9f561d66c9..fd4af2563e 100644 --- a/apps/web/src/bench.rs +++ b/apps/web/src/bench.rs @@ -1,7 +1,7 @@ //! Scripted in-app measurement (`?bench`): open the first photo in Detail, then drive the Exposure //! control exactly like a slider drag (begin interaction → N `develop.set` → end) and time each //! step from the command to the moment the new loupe texture is ready. Results go to the log -//! (the browser console on the web) as one `lightcraft-bench {…json…}` line. +//! (the browser console on the web) as one `app-bench {…json…}` line. use dac_ui_egui::DacApp; use dac_ui_egui::render::Slot; diff --git a/apps/web/src/legacy.rs b/apps/web/src/legacy.rs new file mode 100644 index 0000000000..8a30a6bbfb --- /dev/null +++ b/apps/web/src/legacy.rs @@ -0,0 +1,7 @@ +//! Names the browser build stored under its previous product name. They name data already in +//! users' browsers, so they never follow the brand: changing them would orphan saved libraries. + +/// The IndexedDB database holding the library when OPFS is unavailable. +pub const IDB_NAME: &str = "lightcraft"; +/// The Web Locks name that keeps a library to one tab; shared with tabs still running an older build. +pub const TAB_LOCK: &str = "lightcraft-library"; diff --git a/apps/web/src/lib.rs b/apps/web/src/lib.rs index 04ec89b549..12c66e877c 100644 --- a/apps/web/src/lib.rs +++ b/apps/web/src/lib.rs @@ -1,4 +1,4 @@ -//! LightCraft in the browser: the same egui UI as the desktop app, compiled to WASM. +//! The app in the browser: the same egui UI as the desktop app, compiled to WASM. //! //! Build with `cargo xtask web` (→ `target/web/`), then serve that folder over HTTP (see //! `docs/web.md`). Differences from the desktop host: @@ -25,6 +25,8 @@ pub mod wire; #[cfg(target_arch = "wasm32")] mod backend; #[cfg(target_arch = "wasm32")] +mod legacy; +#[cfg(target_arch = "wasm32")] mod safety; #[cfg(target_arch = "wasm32")] mod web; diff --git a/apps/web/src/safety.rs b/apps/web/src/safety.rs index 137b525039..4e1208855d 100644 --- a/apps/web/src/safety.rs +++ b/apps/web/src/safety.rs @@ -49,11 +49,11 @@ pub fn confirm(text: &str) -> bool { /// Cover the page with a message (the app can't continue, or must not start). pub fn show_blocking(text: &str) { let Some(doc) = document() else { return }; - let el = match doc.get_element_by_id("lightcraft_blocking") { + let el = match doc.get_element_by_id("app_blocking") { Some(el) => el, None => { let Ok(el) = doc.create_element("div") else { return }; - el.set_id("lightcraft_blocking"); + el.set_id("app_blocking"); let _ = el.set_attribute( "style", "position:fixed;inset:0;z-index:10;display:flex;align-items:center;justify-content:center;padding:32px;\ @@ -66,7 +66,7 @@ pub fn show_blocking(text: &str) { } }; el.set_text_content(Some(text)); - if let Some(loading) = doc.get_element_by_id("lightcraft_loading") { + if let Some(loading) = doc.get_element_by_id("app_loading") { loading.remove(); } } @@ -81,16 +81,17 @@ pub fn install_panic_hook() { _ => "unknown error".into(), }; let at = info.location().map(|l| format!(" at {}:{}", l.file(), l.line())).unwrap_or_default(); - log::error!("LightCraft panicked{at}: {msg}"); + log::error!("{} panicked{at}: {msg}", dac_brand::DISPLAY_NAME); show_blocking(&format!( - "LightCraft stopped after an internal error:\n{msg}\n\nThe library saved in this browser is kept. Reload the page to continue.\n\ - If it happens again right away, a photo may be the cause: reload with ?workers=0 or report the error." + "{app} stopped after an internal error:\n{msg}\n\nThe library saved in this browser is kept. Reload the page to continue.\n\ + If it happens again right away, a photo may be the cause: reload with ?workers=0 or report the error.", + app = dac_brand::DISPLAY_NAME )); })); } /// The name of the lock that keeps a library to one tab. -const TAB_LOCK: &str = "lightcraft-library"; +const TAB_LOCK: &str = crate::legacy::TAB_LOCK; /// Hold the library lock for as long as this page lives (Web Locks API). `Some(true)`: ours; /// `Some(false)`: another tab of this site has it; `None`: the browser can't tell (no Web Locks, or @@ -163,7 +164,7 @@ pub async fn backup(files: Files, backend: Backend, names: HashMap Result Result`, wires the file picker and drag-and-drop, and turns exports +//! ``, wires the file picker and drag-and-drop, and turns exports //! into downloads. use std::cell::Cell; @@ -45,7 +45,7 @@ fn perf_now() -> f64 { } fn set_status(text: &str) { - if let Some(el) = window().and_then(|w| w.document()).and_then(|d| d.get_element_by_id("lightcraft_status")) { + if let Some(el) = window().and_then(|w| w.document()).and_then(|d| d.get_element_by_id("app_status")) { el.set_text_content(Some(text)); } } @@ -240,7 +240,7 @@ async fn flush(files: Files, backend: Backend, dir: String, flushing: Rc Boot { if let Some(b) = &backend { if opts.reset { // everything this site keeps in the browser, photos included: never without asking - let ok = safety::confirm( - "?reset deletes the LightCraft library stored in this browser, including every imported photo. \ + let ok = safety::confirm(&dac_brand::fill( + "?reset deletes the {app} library stored in this browser, including every imported photo. \ This can't be undone. Delete it?", - ); + )); if ok { match b.clear().await { - Ok(()) => log::info!("lightcraft: storage cleared (?reset)"), + Ok(()) => log::info!("app: storage cleared (?reset)"), Err(e) => log::error!("clearing storage: {e}"), } } else { - log::info!("lightcraft: ?reset declined; storage kept"); + log::info!("app: ?reset declined; storage kept"); } } // a restored backup lives in its own folder (see `backup`) @@ -323,10 +323,10 @@ async fn boot(opts: Options) -> Boot { } crate::backend::request_persistence(|granted| { if !granted { - notice( - "This browser may delete LightCraft's library when it runs short of space (persistent storage wasn't granted). \ + notice(&dac_brand::fill( + "This browser may delete {app}'s library when it runs short of space (persistent storage wasn't granted). \ Keep your original photos elsewhere and use File ▸ Back Up Library… now and then.", - ); + )); } }); // thumbnails stored without an index entry (index saved late, or lost): delete them @@ -350,7 +350,7 @@ async fn boot(opts: Options) -> Boot { } } log::info!( - "lightcraft: storage {} opened in {:.0} ms ({} thumbnails indexed, {:.1} MB)", + "app: storage {} opened in {:.0} ms ({} thumbnails indexed, {:.1} MB)", backend.as_ref().map_or("memory", |b| b.kind()), perf_now() - t0, index.len(), @@ -393,7 +393,7 @@ impl WebApp { let mut problem = None; match session.open_library_in(stores, true).cloned() { Ok(r) => log::info!( - "lightcraft: library {} in {:.0} ms ({} photos; snapshot seq {}, {} ops replayed)", + "app: library {} in {:.0} ms ({} photos; snapshot seq {}, {} ops replayed)", if r.created { "created" } else { "loaded" }, perf_now() - t, session.catalog.len(), @@ -415,10 +415,10 @@ impl WebApp { } } if backend.is_some() { - notice( - "LightCraft in the browser is experimental. Your library is kept in this browser's storage: keep your original photos \ + notice(&dac_brand::fill( + "{app} in the browser is experimental. Your library is kept in this browser's storage: keep your original photos \ elsewhere and back up with File ▸ Back Up Library….", - ); + )); } // previews are large (≤ 2560 px, f32): keep few in a 32-bit address space session.media.preview_capacity = 3; @@ -450,7 +450,7 @@ impl WebApp { if let Some(w) = &workers { app.renderer.set_offload(Box::new(w.clone())); } - log::info!("lightcraft: {n} render workers"); + log::info!("app: {n} render workers"); CTX.with(|c| *c.borrow_mut() = Some(cc.egui_ctx.clone())); let origin = dac_ui_egui::now_ms() - perf_now(); WebApp { @@ -632,9 +632,9 @@ impl eframe::App for WebApp { if let Some(b) = self.bench.as_mut() && let Some(report) = b.step(&mut self.app) { - log::info!("lightcraft-bench {report}"); + log::info!("app-bench {report}"); if let Some((alive, ready, remote, inline)) = self.workers.as_ref().map(Workers::stats) { - log::info!("lightcraft-workers {{\"alive\":{alive},\"ready\":{ready},\"remote_jobs\":{remote},\"inline_jobs\":{inline}}}"); + log::info!("app-workers {{\"alive\":{alive},\"ready\":{ready},\"remote_jobs\":{remote},\"inline_jobs\":{inline}}}"); } set_status(&format!("bench: {report}")); self.bench = None; @@ -652,7 +652,7 @@ impl eframe::App for WebApp { self.app.ui(ui); if !self.first_frame_logged && !self.app.widgets.is_empty() { self.first_frame_logged = true; - log::info!("lightcraft first UI frame at {:.0} ms after navigation start", perf_now()); + log::info!("app first UI frame at {:.0} ms after navigation start", perf_now()); } } } @@ -662,26 +662,33 @@ impl eframe::App for WebApp { pub fn start(chinese_font: Vec) { eframe::WebLogger::init(log::LevelFilter::Info).ok(); safety::install_panic_hook(); - log::info!("lightcraft: wasm instantiated at {:.0} ms", perf_now()); + log::info!("app: wasm instantiated at {:.0} ms", perf_now()); + // index.html is static: the page title and loading text come from the brand + if let Some(doc) = window().and_then(|w| w.document()) { + doc.set_title(dac_brand::DISPLAY_NAME); + if let Some(el) = doc.get_element_by_id("app_loading") { + el.set_text_content(Some(&format!("Loading {}…", dac_brand::DISPLAY_NAME))); + } + } if chinese_font.is_empty() { - log::warn!("lightcraft: no Simplified Chinese font supplied; Chinese-only glyphs will show as boxes"); + log::warn!("app: no Simplified Chinese font supplied; Chinese-only glyphs will show as boxes"); } let opts = Options::from_url(); wasm_bindgen_futures::spawn_local(async move { // one tab per library: two would each keep their own copy and overwrite each other's saves if opts.store != "memory" && safety::acquire_tab_lock().await == Some(false) { - safety::show_blocking( - "LightCraft is already open in another tab or window of this browser.\n\n\ + safety::show_blocking(&dac_brand::fill( + "{app} is already open in another tab or window of this browser.\n\n\ Switch to that tab, or close it and reload this page. (Two tabs would overwrite each other's changes.)", - ); + )); return; } let Some(canvas) = window() .and_then(|w| w.document()) - .and_then(|d| d.get_element_by_id("lightcraft_canvas")) + .and_then(|d| d.get_element_by_id("app_canvas")) .and_then(|e| e.dyn_into::().ok()) else { - log::error!("missing "); + log::error!("missing "); return; }; let boot = boot(opts).await; @@ -689,13 +696,13 @@ pub fn start(chinese_font: Vec) { let r = runner.start(canvas, eframe::WebOptions::default(), Box::new(move |cc| Ok(Box::new(WebApp::new(cc, boot, chinese_font))))).await; match r { Ok(()) => { - if let Some(el) = window().and_then(|w| w.document()).and_then(|d| d.get_element_by_id("lightcraft_loading")) { + if let Some(el) = window().and_then(|w| w.document()).and_then(|d| d.get_element_by_id("app_loading")) { el.remove(); } } Err(e) => { - log::error!("LightCraft failed to start: {e:?}"); - set_status(&format!("LightCraft failed to start: {e:?}")); + log::error!("{} failed to start: {e:?}", dac_brand::DISPLAY_NAME); + set_status(&format!("{} failed to start: {e:?}", dac_brand::DISPLAY_NAME)); } } }); diff --git a/apps/web/src/workers.rs b/apps/web/src/workers.rs index 452788dc55..7be646828e 100644 --- a/apps/web/src/workers.rs +++ b/apps/web/src/workers.rs @@ -240,15 +240,15 @@ impl Workers { inline_done: 0, inline_this_frame: false, }))); - let module = get(&js_sys::global(), "lightcraftModule"); + let module = get(&js_sys::global(), "appModule"); if module.is_undefined() { - log::warn!("render workers: no compiled module on the page (window.lightcraftModule); rendering on the main thread"); + log::warn!("render workers: no compiled module on the page (window.appModule); rendering on the main thread"); return w; } for i in 0..n { let opts = web_sys::WorkerOptions::new(); opts.set_type(web_sys::WorkerType::Module); - opts.set_name(&format!("lightcraft-render-{i}")); + opts.set_name(&format!("{}-render-{i}", dac_brand::BINARY)); let worker = match web_sys::Worker::new_with_options("./worker.js", &opts) { Ok(x) => x, Err(e) => { diff --git a/apps/web/worker.js b/apps/web/worker.js index 420bfcc232..c26a202553 100644 --- a/apps/web/worker.js +++ b/apps/web/worker.js @@ -1,4 +1,4 @@ -// LightCraft render worker: a second instance of the app's wasm module that renders jobs posted +// The render worker: a second instance of the app's wasm module that renders jobs posted // by the page (see apps/web/src/workers.rs). The first message carries the compiled // WebAssembly.Module and the storage backend kind; the module then takes over `onmessage`. import init, { worker_main } from "./dac_web.js"; diff --git a/assets/ATTRIBUTION.md b/assets/ATTRIBUTION.md index 52074466dd..762370d6e0 100644 --- a/assets/ATTRIBUTION.md +++ b/assets/ATTRIBUTION.md @@ -9,9 +9,10 @@ covers a whole directory), or if a licence file referenced in the Licence column | Path | Asset | Creator | Source | Licence | Added | Modifications | |---|---|---|---|---|---|---| | `assets/fonts/Inter-*.ttf` (Regular, Medium, SemiBold) | Inter | Rasmus Andersson | https://github.com/rsms/inter | SIL Open Font License 1.1 (`assets/fonts/OFL-Inter.txt`) | 2026-09-30 | none | -| `assets/app-icon/` (`lightcraft.svg` and the PNG/ICNS/ICO/SVG files derived from it) | LightCraft app icon (lynx) | LightCraft project owner (drawn in ArtCraft) | original work (vectorised from the owner's drawing; see `assets/app-icon/README.md`) | MIT OR Apache-2.0 (`assets/app-icon/LICENSE.txt`) | 2026-10-02 | vectorised to SVG; rendered to PNG/ICNS/ICO by `packaging/icons.sh` | +| `brand/icon.svg`, `brand/logo.svg` | Placeholder app icon and logo (six-blade lens aperture, no text) | the project contributors | original work for this repository | MIT (`LICENSE`) | 2026-10-10 | none | +| `assets/app-icon/` (PNG/ICNS/ICO/SVG files) | app icon renders | project contributors | original work, generated from `brand/icon.svg` by `packaging/icons.sh` | MIT (`assets/app-icon/LICENSE.txt`) | 2026-10-10 | rendered to PNG/ICNS/ICO | | `assets/camera-profiles/*.json` | Camera colour profiles (matrix + hue/saturation/value table), built into LightCraft | ILCE-7M4: Harald Hoyer | original work: fitted by `lightcraft-cli calibrate` to the contributor's own raw photos and their in-camera JPEGs (597 ILCE-7M4 photos, 2026); aggregate colour statistics only, no image content; no Adobe or third-party profile data | MIT OR Apache-2.0 | 2026-10-07 | none | -| `packaging/macos/dmg/` (`background.svg`, the `background.tiff` rendered from it by `generate.py`, and the `dmg-layout.DS_Store` layout file) | LightCraft macOS DMG window background | @XusBadia | original work for this repository, derived from the LightCraft app icon (`assets/app-icon/lightcraft.svg`, referenced via ``, not copied); text is outlined Inter / JetBrains Mono glyph paths | MIT OR Apache-2.0 | 2026-10-08 | none (original); used for the Finder window of the macOS DMG, `packaging/macos/dmg/generate.py` renders it to `background.tiff` | +| `packaging/macos/dmg/` (`background.svg`, the `background.tiff` rendered from it by `generate.py`, and the `dmg-layout.DS_Store` layout file) | macOS DMG window background | @XusBadia | original work for this repository; embeds the app icon (`brand/icon.svg`, referenced via ``, not copied); text is outlined Inter / JetBrains Mono glyph paths | MIT OR Apache-2.0 | 2026-10-08 | none (original); used for the Finder window of the macOS DMG, `packaging/macos/dmg/generate.py` renders it to `background.tiff` | | `assets/camera-profiles/X-H2S.json`, `assets/camera-profiles/X-T4.json` | Fujifilm camera colour profiles (matrix + hue/saturation/value table), built into LightCraft | LightCraft contributors; source photographs supplied by Sebastian Pfluegelmeier | original work: fitted by `lightcraft-cli calibrate` to 201 X-H2S and 545 X-T4 RAFs and their in-camera JPEGs; aggregate colour statistics only, no image content; no Adobe or third-party profile data | MIT OR Apache-2.0 | 2026-10-08 | none | | `crates/scenes/` (generated images) | Procedural demo photographs | LightCraft contributors | original work (generated at runtime, no source imagery) | MIT OR Apache-2.0 | 2026-09-30 | n/a | | `crates/ui-egui/src/icons.rs` | UI icons drawn as vector paths in code | LightCraft contributors | original work | MIT OR Apache-2.0 | 2026-09-30 | n/a | @@ -20,7 +21,6 @@ covers a whole directory), or if a licence file referenced in the Licence column | `docs/images/*-earthrise.jpg`, `docs/images/grid-pd.jpg` | "Earthrise" (AS08-14-2383) | NASA / Bill Anders, Apollo 8 (1968) | https://commons.wikimedia.org/wiki/File:NASA-Apollo8-Dec24-Earthrise.jpg | Public domain (NASA) | 2026-09-30 | developed in LightCraft; shown inside app screenshots | | `docs/images/*-blue-marble.jpg`, `docs/images/grid-pd.jpg` | "The Blue Marble" (AS17-148-22727) | NASA, Apollo 17 crew (1972) | https://commons.wikimedia.org/wiki/File:The_Earth_seen_from_Apollo_17.jpg | Public domain (NASA) | 2026-09-30 | developed in LightCraft; shown inside app screenshots | | `docs/images/*.jpg` (UI) | LightCraft application screenshots | LightCraft contributors | original work (captured with `docs/showcase/`) | MIT OR Apache-2.0 | 2026-09-30 | n/a | -| `docs/brand/` (artcraft-logo and artcraft-mark, SVG and PNG) | ArtCraft wordmark and mark | ArtCraft Team | original work (https://getartcraft.com/) | ArtCraft trademark, see `docs/brand/LICENSE-brand.txt` (not open source) | 2026-10-01 | none | | craft-fonts: optional build input, not files in this repository | BIZ UDPGothic (Regular, Bold), BIZ UDMincho Regular, Shippori Mincho Regular, Noto Sans CJK SC Regular | Morisawa Inc. / The BIZ UDGothic and BIZ UDMincho Project Authors; The Shippori Mincho Project Authors; Google and Adobe (Noto Sans CJK, maintainer-approved exception; see AGENTS.md) (per craft-fonts' attribution) | https://github.com/storytold/craft-fonts/blob/main/ATTRIBUTION.md | SIL Open Font License 1.1 (each font's OFL.txt in craft-fonts; release packages ship it as OFL-.txt) | 2026-10-06 | none; native builds made with `CRAFT_FONTS_DIR` embed the manifest fonts (all official releases); the web build embeds BIZ UDPGothic Regular and ships Noto Sans CJK SC Regular as a separate font file | Notes diff --git a/assets/app-icon/LICENSE.txt b/assets/app-icon/LICENSE.txt index 23da456b26..05951deab0 100644 --- a/assets/app-icon/LICENSE.txt +++ b/assets/app-icon/LICENSE.txt @@ -1,13 +1,2 @@ -LightCraft app icon (lightcraft.svg and every file derived from it in this directory: -lightcraft-small.svg, lightcraft-1024.png, lightcraft-macos-512.png, lightcraft.icns, -lightcraft.ico, hicolor/). - -Original artwork made for this project by the LightCraft project owner in ArtCraft (no -third-party material). Licensed like the rest of LightCraft, under either of - - * Apache License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0) - * MIT license (https://opensource.org/licenses/MIT) - -at your option. - -Regenerate the derived files with packaging/icons.sh. +The app icon (brand/icon.svg and every file derived from it in this directory) is original work by the +project contributors, licensed under the MIT licence (see LICENSE at the repository root). diff --git a/assets/app-icon/README.md b/assets/app-icon/README.md index 9e8e48114f..1eb213b1a8 100644 --- a/assets/app-icon/README.md +++ b/assets/app-icon/README.md @@ -1,49 +1,20 @@ -# LightCraft app icon +# App icon -A **lynx**, frontal head-and-shoulders portrait with an alert gaze, in the style of an engraving: the -Crafting Apps "owl template" (full-bleed colour field, tight portrait, the figure in paper with ink line -work and a crisp ink contour, no roundel or border). - -## Palette (exactly three colours) - -| Colour | Hex | Used for | -|---|---|---| -| Ink | `#0b0b0c` | line work and the contour | -| Paper | `#efe9dc` | the figure (the lynx) | -| LightCraft amber | `#f2a516` | the full-bleed field (the app colour) | - -## Geometry - -`viewBox="0 0 512 512"`, a rounded-square tile with `rx=112`, clipped; the colour fills the whole tile. -macOS files (`.icns`, `lightcraft-macos-512.png`) add Apple's transparent margin (an 824/1024 body); -Windows and Linux files use the full-bleed tile so the lynx reads at 16-48 px. - -## Provenance - -The owner's original drawing, made in ArtCraft (2880 px, keyed to the three colours), vectorised with -craftrules `assets/logo-options/_tools/vectorize_tile.py`. The source drawing stays in craftrules at -`assets/app-icons/lightcraft/source.png`; `lightcraft.svg` here is the canonical artwork. Licence: -`LICENSE.txt` (MIT OR Apache-2.0, like the repo). - -## Files +Every file here is generated from `brand.toml`'s `icon_svg` (`brand/icon.svg`) by `packaging/icons.sh`. +Do not edit them by hand: change the SVG (or point `icon_svg` at another one) and rerun the script. | File | What | |---|---| -| `lightcraft.svg` | canonical vector, traced at 2048 px (about 770 KB) | -| `lightcraft-small.svg` | lighter vector, traced at 1024 px (about 360 KB) | -| `lightcraft-1024.png` | 1024 px render (store listings, docs) | -| `lightcraft-macos-512.png` | runtime window/Dock icon on macOS (embedded by `apps/app/src/main.rs`) | -| `lightcraft.icns` | macOS bundle icon (`CFBundleIconFile`) | -| `lightcraft.ico` | Windows icon, 16-256 px, embedded in `lightcraft.exe` by `apps/app/build.rs` | -| `hicolor/x/apps/ai.storyteller.lightcraft.png` | Linux icon theme, 16-512 px; the 256 px one is also the runtime window icon on Windows and Linux | -| `hicolor/scalable/apps/ai.storyteller.lightcraft.svg` | Linux scalable icon (the small SVG) | +| `app-1024.png` | 1024 px render (store listings, docs) | +| `app-macos-512.png` | runtime window/Dock icon on macOS (embedded by `apps/app/src/main.rs`); Apple's grid, with a transparent margin | +| `app.icns` | macOS bundle icon (`CFBundleIconFile`) | +| `app.ico` | Windows icon, 16-256 px, embedded in the executable by `apps/app/build.rs` | +| `hicolor/x/apps/app.png` | Linux icon theme, 16-512 px; the 256 px one is also the runtime window icon on Windows and Linux | +| `hicolor/scalable/apps/app.svg` | Linux scalable icon (a copy of the source SVG) | -The app id is `ai.storyteller.lightcraft`: the Wayland app id, the `.desktop` file -(`packaging/linux/ai.storyteller.lightcraft.desktop`, `Icon=ai.storyteller.lightcraft`) and the hicolor icon -name. To install on Linux, copy `hicolor/` into `/usr/share/icons/hicolor/` (or `~/.local/share/icons/hicolor/`) -and the `.desktop` file into `applications/`. +Packaging installs the hicolor icons under the brand's app id (`packaging/env.sh` `install_icons`). ## Regenerate -Edit `lightcraft.svg` (or `lightcraft-small.svg`), then run `packaging/icons.sh` (needs `resvg`; `iconutil` -on macOS for the `.icns`; the `.ico` is packed by `cargo xtask ico`). Every output is committed. +`packaging/icons.sh` needs `resvg` (or `rsvg-convert`); the `.icns` needs `iconutil` (macOS) or Python Pillow, +and the `.ico` is packed by `cargo xtask ico`. Every output is committed. diff --git a/assets/app-icon/app-1024.png b/assets/app-icon/app-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..6fdacb070ee3389d4d217aa6335704514c6a1bb4 GIT binary patch literal 68664 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ð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 literal 0 HcmV?d00001 diff --git a/assets/app-icon/app-macos-512.png b/assets/app-icon/app-macos-512.png new file mode 100644 index 0000000000000000000000000000000000000000..8603a98ad91842be1f897a73f0b1fed88f5ab9a2 GIT binary patch literal 26048 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 z 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 KMNUMnLSTYTs9*K~ diff --git a/assets/app-icon/hicolor/128x128/apps/app.png b/assets/app-icon/hicolor/128x128/apps/app.png new file mode 100644 index 0000000000000000000000000000000000000000..f8d4ba0e1cd00f88ce07a2cc2dd6f0e01a67f4b9 GIT binary patch literal 7235 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 FKO*7NHgKX=_cOzUck~&?&CDMqb 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 R-|7GW002ovPDHLkV1f+^v||7O literal 0 HcmV?d00001 diff --git a/assets/app-icon/hicolor/16x16/apps/ai.storyteller.lightcraft.png b/assets/app-icon/hicolor/16x16/apps/ai.storyteller.lightcraft.png deleted file mode 100644 index 037a2c434d13fccf5f1c6f76eaf0db01eaa1aa2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 663 zcmV;I0%-k-P)@*?x+*AkS9PxjT#5_VUHd^0MbJh? z+DL3rQa_|g6A+4%F-og7ooTdH+wtAkCeCQ}!ei#$ch9-!+&5za3;DYHaCz3=8z0*k zKIR|B|Dyce2A8EW2&h*b$H(s)2@Dl?TxKPVWlmo3uXt8!#)bO=%CpumVF+tfRa~qV zw1*ndm+wGky5%ph_#=p+@vS(urvjIGdLgMA&KM2A_G(d4d>@KmjB_ z?ZC}^E5!QKNDUX@Sk}tcUWE$B(8?w0qJ24{KSi+R7AXRW- z?S|hNJ%Mck{i1^Cfd~Yl39094ME6G^Ghi^_=S%RqS>;d-W7HCq=U2nwu;byQfrXhc zB?RX7q!NOg{fNK(264u>G{H!vr3T227Wg6+q=tgXi6k@Eu{43xYC-XR39_P~>&PMA z^;~ZcJdD7}z!E#7cj+^5{>e^cru=#W51RogAnCD7mvOTDMD2{aSFP}U<0kYyU8yIK zCrcbm#Uz`aL`Wdo3u~HmGl_;YurI^IhG^tIRCb>zPkvnOcszE%9;mn!& z|MQ$y8*teIW0+ug!-UxOF89H$iy|o>y%R_2;iPz7b z5{X2Ar;_rN(7SqP5Dc1or?Y{JV|U55bTXUBuuKDww@-`Y~{}N%T*G?B#@?eWqg8nT2ozcVSSzK_ZX#I z9x3iL4H>cfk1$0 zG>TGieq@9>SCCAhgb)I&%gO4Ok0j@2kW%9A+KsP&0K2ylG!2i##sOoQ#}6h@seD~M z3S22wl3)GF%Itf}o14gTnM`y6tJ|r-re%yGzV;5~YxN#lh`K%eGg2d1ODyBDt9C%S zOlc#BC$LA=tXV9y4IZMQxk;60npr|Jx>!l3`+H?D807e+o4ozHKrxk8vK7~65%1nU z9A4iRxx~n1IMV85>i%tFu^$x$kw^qre31qtw+&YEEVde01q7|FP3Wbp0#{2Yn9jqA zan9`PrqSi7*A`{E-Abt0!DRSaHDqW=KAWC7S>}Wd_jeH*?8oD*{V8*lk9PVvEK`Ip zoFkv#9_4w_=D^PwFE? z)A-N;MH0aTHzuZi&=wP_(RQ~#8rtq`x704unJofavcvuE%w3i;ZQvxkbLZT--*?V; z&Ye5Ouq|`4e6N`^k0x$D+Jf8H5%JC9Va){QTyXWe+^(_ALy5UnEyNyS@2UMPheIoZ>gO{ZRy0l zlO`S!5}7Y8UKH@U(A3-v?PdfgQ-?8^_1ya!?@U4V)#XxMT2yL&u4Bg1U5Wm3M&0^)yy*NO~?L=VA zUWPW6LM%Rt_l_Qc_MaQk!4mXc_Tr0E|H#b3o3`Es5BQ-ktagHeBSB5s3~IJ*K{A=L z2npi%BV4%wK>^0hs>M9V{l8t3*XYIR2PX)X%)^*V%gFjKUXoeFhDYUG(~FJLN8^0k zD+jGbB_YRJITEl%8+JV|BUU5?ZrEKf?`e#hV@+hq?3m^0v7Pr}ITqPmvkTqlewJf` zAN%-22}C()l&+?F3$(K-Ny>4h2!}muS;SQNB}DCX7(G z$I4%5tcz~9b9`h}5^2{~I1^|y8B~jC8NJ#_K|2!#%z0*{^fxjYNy4kHXRMC%d!36M zaSe##wn?z2eWE>|s+WEeF#~4T`szVMf9jEb%BG~DRJ?NE1WIl!K_CvB8qY0!`E5_$ zM>2x6ijAcR*+CqKWrx+vc>;%3ojh6RBGU%1hH-kNPUtx3f-=y~oINkI zQ0?0-?n%$$b3nt6O$htac9h6Vz*ht#=8wCa`$K{A)xvS46uQV@ z{r661LZM9t+R>L-FVknSNy1E+8EZnRNWxCz##Gn+Rq=Dh;(+cDhyAhy#?_?I`aoW$ zq%9AnVWAl@i3yy4olK13NY!wM+dBQ-?aLA1R@!Po!)isfCny!)Q_SXTkp*R95S8n^ zc)xMHo!BmgVSl!~D~`Fn!Wmr5F;Q_0$y6HpymhFDE6U`x`-fi;6#dSg53XF$1McbG f166-^sLz%=HzySnp`Vt@00000NkvXXu0mjf*YziU diff --git a/assets/app-icon/hicolor/24x24/apps/app.png b/assets/app-icon/hicolor/24x24/apps/app.png new file mode 100644 index 0000000000000000000000000000000000000000..d5ae52b8e561ffabbcc7221990022998c3df28b8 GIT binary patch literal 1083 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 Hu0mjfd~Wap diff --git a/assets/app-icon/hicolor/256x256/apps/app.png b/assets/app-icon/hicolor/256x256/apps/app.png new file mode 100644 index 0000000000000000000000000000000000000000..9277828acbfa381f223ba116438267cc4625d36a GIT binary patch literal 14916 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 D7lK&K diff --git a/assets/app-icon/hicolor/32x32/apps/app.png b/assets/app-icon/hicolor/32x32/apps/app.png new file mode 100644 index 0000000000000000000000000000000000000000..f435ffc8f9f0c01b8f5bba04d67f5c5374024a20 GIT binary patch literal 1562 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 Ef=5w@asU7T literal 0 HcmV?d00001 diff --git a/assets/app-icon/hicolor/512x512/apps/ai.storyteller.lightcraft.png b/assets/app-icon/hicolor/512x512/apps/ai.storyteller.lightcraft.png deleted file mode 100644 index 5933c2802562d398fe7dd6232d1845f6688f4b75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 146129 zcmX6^cUaQj+Xhj=t+}vN9F>}xdk@T6S?<&<2bo#9Q*#UMzUE9z%UoHxSLPll=E#L< zskzO)ae;`yOTYL0!?-RE=kuIr-uLtTXKrfD#(bU`006MvykTGo0MOCi(g7fhw3nlx zU#9>%jjWpn*R6v-Y?E2Ca$JM=QsB{lfj{WW&Rt~sC>GBuDW(_ou;6}rzL&i+w{`RV z7|ElC`=SPC4UV@iPnDf;-%NFyW;>VqfUYC8 z#RFp#*Mx*bT^bNLCytr5AM;w|FLI6Km`+aitHK!|FiWh{gP3qVBO{|8dOcB4-nt}f z6s9J)I5mD}sTeU-}| zPB^#~#|2NKQ&=7Yke7jK**;qW(!y-U9KpC3UgydHP1I2ZsP#AEWN~ z4rLOV*r9CYb$+Iu{N?Y&80HX_gnlnpCIUEaqlto1EZ&!cZO7Be=v<^`BJemXsc8DhS_$DX?-+0YnDT$D2}a z{BVwkQabZ*&ZKwO%h9{BrPT4IA5&m{+`(L<#8->S0$d~M#(+kAW$`^lJ( zgm#ff{}wCoUCOpGIG^Qmsi<55E1>EGtiLYcIT*I(wRhokr2+kwIzESX>vFq{K6%P= z>{PQk?lU8*-ygowpn>^DcH-4J`SPAXts~8yyWFM}({N}098D_~6yiWasB2lpaUC)8 zfUCXmTfFcaheSjQf9wwU!@2Ppe|NGBGoY(>8nd!hbkBOB5hPqoKvPfT5j#0>rbDWa z6N&7e-HgG!@?y%%YE%B-S(SQIMRD0M(@*CkeZ2wZ#1cX3lhwblpyr=r9I_FHP_2{g zkYjk3jwiL6d?$}X8hto6wMWttiomTeB0AUHmFdPfG!()-4@tCry`?__tuVk)s>1*F z{suMy_nwdZZ$ue~ku%-TuG$S;sEv+x5}@fxOw9-zIym2NGIVQveh#M@8yTM6Fp(5> zh$h7&i13Q)iJWviyI*q7xyP-6C1f3H4w#SX_5X$^4vOnoz;|XdR^}cgX%p7%PDVM% ze+%T;<*$hYmY?U&wv#(+zGKnEpPpTFhuui$@fzd!_B({%$jk$<31y85F}5>bNu~Ux zS?B*-GD9>n>e}_97~hw^t^mmyvuhHG%B|}hacy-Qxum$Z3EKn5wNEz@y9FunbsXES zXl!urg{>UG|Noe6J!3zM56aJox=V0UbQLh*C=Ax+_@wn_a>=kjsGNwu(>0f^NHQp7 z-EBMeCADp#W==C{wp62NVZ!2p{^38Qw!sHIWJFmIEN9_rL8j1^#5;c$ zvIb%@^eHoH1})3X@a_c(-0skx!l|2aINFeQ;hMB+^l zYQOb<)f^$-rE|;7mr$5g-``~hgEBf%9$WpbFkdBiv7z>>z4R+woX798v;FV+TZGp| z{JAuw60aw!gPa#O$)=?6ApDnE?a$tB`C9>1kZ=z87;dgE5G|_Jx^@#EGWCnxb)%rK zGeiL3kgosFCZF_lnQim-u#6b4U-Y+vxSaGtRV@rv&VC|zlA7Vun+Y*y< z&Ns5Oi_9gt%dDuWU+v*YXl{{wnUX64tKMlZ>2z61QIVAVSQl_hoL&d9q~(e6F( z^WC?Ot8GjZoPZ0Lx#IkQ%Kj7~VxTLHjtK7xHDJ?H9|4B$egI3;4pAuN5q2%8e#PH3 z?GoAF;GjD? z))HZ&w%0hd=TLR}nU_#u7ZC13pO4$bp7fQl&C8f@<)2M>H){X0_w8p3zIlE_bBm>8 z5eW3s9}{9=p1<|ULZSh2KGfPSXrG`@Kx+ELXTYcT+T8N0Pse-p=G&^XDOU$InxzNd z%d1}v+2c~-tXK;C1c$K~GO3lv?w%qFx^zZ^H)SiC3wa910h1xe8MUuI^mijZAjT20 zY})fAUtbs4x#Xbk)oQG83LoG00H%MdlH+hK$D=#~H2sWt78yBCJ|m}i2=ws(i(xg= za(mR!n^}tP&-OR@Er=7#99_LSq+CiIHo})&?(_2vmFsaEv2O9Tm2d@`8ZA@BQMMOx z^JKdPmfRl-fkLHKgrTP@)NAFWpW=u^@w)ZP(@yp4CvpTfa_peL(i)njP;eS;x&HM> zx>@*<34-UL^?5+uLv-gDM(w*VSO-CMqO@hkn#|dTdXHy2!9vis(#tLjDbG)Ho-*fu zx?Al%7XCk#vyG-hx07~R%lO(mc#bj1)0`hy8PgnywxpPF$8SxGwbEWE9DZJvT1yl7 ze+H)WpauWu;RTMkyGYG4b4uM4;Phr2RT;5^r05()P$jxm;*Ijh##`6TG`gn0%s8CA zFowQbrv*KJjh((>D;Vhp)D?P{=7>&pj(P586vg^7w?+tOy-}SLFjdFD#MP6L=N}8T z8Y2KP)n9Lb27MR-R4aaS6>gFL8OS0n$!RiQheKxl=Iw$O2=TSvS|1@lyyfoIZ(3R1 zsRU*aH*Cq*)AG<`5qY6!q6p&Y4x;-GT(*^%q@Rb};3((yA;vvLbT=UFCCSt0@y1!m zpP>XfqME6XJ%T>w=VSWB_tyX!@a_nNpfnOOtl7Lx?RF|-+g5+tgZx9aeGm|!zX)rk zI^2{1NJafiO=lSr_J+yS2#6aj51=C^a3w|F+F}m~HQ+nMuGbnTuWjRfqsENx$9ELV z0Y07eiZx-A7e0yS)={ONEh03W_nhp3Y~852X)`3aFlKvouWQGx=xWuY*Tr6Rdgo zi9``ePoW1BaGC$vCnVJ{lZ=x&o|oBkk_-^cNN3-cKA>QKNmH<414bm)@9-;(9&x{^ zHT9JzC2o3^7PxI!VRfWE(;kr&-sP!{X3uQhoAdcT2WMSkD*OQna%4mOS9}(02-BFP zNGLH%^C7+|2qP2Dlt8G7r=lVpTxS5x6zNcMfp!yVOaEy*I>q25V!MidF~5=d{h&EXAYKr?jKyFTh?X zFbq+vSqkUS=E?}$*vIlCL;~lC< z(IWvJxr;bkIByHR@GH0rhXP$frZ+nll*|9R%|4HMQib;h@1eI*r*ipzX4FDC+;=M5 zK$Wyx$|wE&y~_KTL{%Xt2^NKrg{o^DELcsnDfeyPAOl^T5;YV;Xhapc!4v|s8oa~)m9FPLog;5h6XWET(7 zwV@>09nBM14)=Q`hZ zG*J+WPt=IrGgL)?F{d=dt}#DL4@-unmR_`PD!Ji$Zb)leHkeSetQZ=v?hRKH4D4gU z%tS}n7~JZu420`x$!Y;x>L5N_%2vZn_lT+}PCkTk!MzJ?b}xQ>MjR}QUIP@PfE7xA zAtE2;PB4T2B98_8@wT_nNr0WdUQ%IREA`-R!#y{Pmck!n?=OnIHn?K7VkYXm*HFnO zBvgP1k?I(bc-FKUrH={c_iX5=e%0$>LXCY)p7EUYWCTQqYcPU)f0ZxKGI#~W(SKe* z-1-kGN&m6VLqoGs9L}5zMX3 za{{8wKlYwVB3G0LhVrvWb5@uG>8eU}%2MCIX|cWu5kU>oDSm_ zbgFaIv-UP(V-)dLRS~f6oX5l z=zA<{DfG3;!G3ncK#7=ic3Aa)NLbTpK5k_Xt@TJL$^x@KINQlpJs=M7ftfA8K&Sov zhE$h4irDMLpTATkhz1K&TQQOyO9aUaf*FPX>VgGuHi6?%ClJ|YvYvG*9mD&IojG&9 z)y*!LJml#KS}~j8%7vR6OLJaY02h5;^UISJ%(54m>;dPUf)_ujo?U&EQTUR6Mw$4l z_r=rDg=*2($`+%_8b2a(q~X7&btLmcER*V?hJMa$+dUz0r5 zTrx?S+OkS69ug7NQwzfN8h<*IS}tTSd2>*-?mbKJg4jN&A6%Y16HEH`@PZ$5P>N>Ve}b*#(eDA43Lbffk;IZ9m;nrDjOaIFXc2T%hAAy$PqO2nQpJJ?6+rBg{%YF15yV+&scDbu^ANo=R11o zv5;p)ge0ZnJ{VJq72>Wu#kDP>v`KnB$>MwryRV;|nyLc&?k%@chk<;4v@E!K!)?^J zLpx8ss=!@@Vd;PO#+aqF`3ApA$;*r|EeO>@=IPP%?AKXRP{PQ4@Kts9$3fE>E&4sf zK#hQ{-z0oYPGXLR=8I`tf+oVp2ZxMJ%!x~9rv?O_l$0RGqF1^;Qr7Mj#m`gl??M^? z8&TBo-|)C_Ct|C+g5#99q;kRep!=c>%Val{g8i$wrmmf0}Iwx;( zesENev7#jMPVblvllC+|1kMP(L7M3MY4xo|9E5F&n48Ly&xrFgvNR8nXx6b+g+V{= zxNaA+=yvC_k~9wF)@ZT(N#Le{Kc7^zr>}z4&VUo~6@Q%jp88BPtIk2}9U5%H5#vYQ zp2XGLx{6KaL?+7xi8QNhU)<&ab?8wMxb4&$lj~0^9OPtC9|Vnb1u{GOf5V3vA_WAN zcrvMZ_*UfU@eh*h6~Q>0GisTbzDO?hE9ObZPh1^PNJt3r0!w9kCEKFR%0Axn+Pl%Y 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

|Tl4PrDU0i$_C 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

- https://raw.githubusercontent.com/storytold/lightcraft/main/docs/images/lightcraft-demo.jpg - - - - #9fd0ff - #1f64ba - - - 760 - - - keyboard - pointing - tablet - - - lightcraft - - - - - - diff --git a/packaging/linux/flatpak-bundle.sh b/packaging/linux/flatpak-bundle.sh index 6ad39ebec7..64bd56267c 100755 --- a/packaging/linux/flatpak-bundle.sh +++ b/packaging/linux/flatpak-bundle.sh @@ -1,22 +1,23 @@ #!/usr/bin/env bash -# Repackage a LightCraft Linux tarball as a single-file Flatpak bundle: +# Repackage the app's Linux tarball as a single-file Flatpak bundle (names from brand.toml): # -# $DIST/lightcraft--linux-.flatpak +# $DIST/--linux-.flatpak # # Usage: packaging/linux/flatpak-bundle.sh [--no-test] [TARBALL] # -# TARBALL defaults to $DIST/lightcraft--linux-.tar.gz from package.sh. The bundle +# TARBALL defaults to $DIST/--linux-.tar.gz from package.sh. The bundle # is built for the host architecture (x86_64 or aarch64), which must match the tarball's. # Needs flatpak, flatpak-builder and the SVG pixbuf loader (librsvg2-common) for the host's # `appstreamcli compose`; the freedesktop runtime and SDK named in the manifest are # installed per-user from Flathub. Unless --no-test, the bundle is then installed per-user and -# `lightcraft-cli --version` is run inside the sandbox as a smoke test. -# Manifest: packaging/linux/flatpak/ai.storyteller.lightcraft.bundle.yml. +# ` --version` is run inside the sandbox as a smoke test. +# Manifest template: packaging/linux/flatpak/{app_id}.bundle.yml.in. set -euo pipefail # shellcheck source=../env.sh . "$(dirname "${BASH_SOURCE[0]}")/../env.sh" HERE="$ROOT/packaging/linux" -APP_ID=ai.storyteller.lightcraft +APP_ID=$BRAND_APP_ID +APP=$BRAND_BINARY FLATHUB=https://dl.flathub.org/repo/flathub.flatpakrepo TEST=1 @@ -36,21 +37,21 @@ case "$ARCH" in aarch64 | arm64) ARCH=aarch64 ;; *) echo "unsupported architecture $ARCH" >&2; exit 2 ;; esac -BASENAME="lightcraft-$VERSION-linux-$ARCH" +BASENAME="$APP-$VERSION-linux-$ARCH" TARBALL="${TARBALL:-$DIST/$BASENAME.tar.gz}" [ -f "$TARBALL" ] || { echo "error: $TARBALL not found (run packaging/linux/package.sh --formats tar first)" >&2; exit 1; } for tool in flatpak flatpak-builder; do command -v "$tool" >/dev/null || { echo "error: $tool not found (apt install flatpak flatpak-builder librsvg2-common)" >&2; exit 1; } done -echo "==> LightCraft $VERSION Flatpak bundle for $ARCH from $(basename "$TARBALL")" +echo "==> $BRAND_DISPLAY_NAME $VERSION Flatpak bundle for $ARCH from $(basename "$TARBALL")" WORK="$CARGO_TARGET_DIR/flatpak-bundle" rm -rf "$WORK" mkdir -p "$WORK/stage" tar -xzf "$TARBALL" -C "$WORK/stage" --strip-components=1 -[ -x "$WORK/stage/bin/lightcraft" ] || { echo "error: $TARBALL has no bin/lightcraft" >&2; exit 1; } -cp "$HERE/flatpak/$APP_ID.bundle.yml" "$WORK/$APP_ID.yml" +[ -x "$WORK/stage/bin/$APP" ] || { echo "error: $TARBALL has no bin/$APP" >&2; exit 1; } +brand_render "$HERE/flatpak/{app_id}.bundle.yml.in" "$WORK/$APP_ID.yml" flatpak remote-add --user --if-not-exists flathub "$FLATHUB" # --disable-rofiles-fuse: no FUSE in containers and CI runners. @@ -65,7 +66,7 @@ echo "wrote $OUT" if [ "$TEST" = 1 ]; then flatpak install --user -y --noninteractive --reinstall "$OUT" flatpak info --user "$APP_ID" - flatpak run --command=lightcraft-cli "$APP_ID" --version + flatpak run --command="$BRAND_CLI_BINARY" "$APP_ID" --version flatpak run --command=sh "$APP_ID" -c 'ls /app/share/applications /app/share/metainfo /app/share/mime/packages /app/share/icons/hicolor/scalable/apps' fi echo "==> done" diff --git a/packaging/linux/flatpak/ai.storyteller.lightcraft.bundle.yml b/packaging/linux/flatpak/{app_id}.bundle.yml.in similarity index 63% rename from packaging/linux/flatpak/ai.storyteller.lightcraft.bundle.yml rename to packaging/linux/flatpak/{app_id}.bundle.yml.in index 752e1edecb..7370f15858 100644 --- a/packaging/linux/flatpak/ai.storyteller.lightcraft.bundle.yml +++ b/packaging/linux/flatpak/{app_id}.bundle.yml.in @@ -1,7 +1,8 @@ # Flatpak manifest for the single-file bundle attached to every GitHub release -# (lightcraft--linux-.flatpak). Build it with packaging/linux/flatpak-bundle.sh. +# (--linux-.flatpak). Build it with packaging/linux/flatpak-bundle.sh. +# A template: the {{…}} placeholders come from brand.toml. # -# It repackages the release's own Linux tarball (lightcraft--linux-.tar.gz, +# It repackages the release's own Linux tarball (--linux-.tar.gz, # built on Ubuntu 22.04 by package.sh) instead of compiling Rust inside flatpak-builder: no # network and no vendored crate sources during the build, a few seconds instead of 20+ minutes, # and byte-for-byte the same binaries as the AppImage/deb/rpm. The script unpacks the tarball @@ -9,13 +10,13 @@ # Wayland, xkbcommon and Vulkan at runtime; the freedesktop runtime has all of them, and the # GPU driver comes from its org.freedesktop.Platform.GL extension. # -# ai.storyteller.lightcraft.yml (same directory) is the from-source manifest for Flathub. Keep +# {app_id}.yml.in (same directory) is the from-source manifest for Flathub. Keep # runtime-version and finish-args identical in both (packaging-lint checks this). -id: ai.storyteller.lightcraft +id: {{app_id}} runtime: org.freedesktop.Platform runtime-version: '25.08' sdk: org.freedesktop.Sdk -command: lightcraft +command: {{binary}} finish-args: # Display: Wayland first; X11 only when no Wayland compositor is running. - --socket=wayland @@ -24,7 +25,7 @@ finish-args: - --share=ipc # GPU access for the wgpu renderer (Vulkan, or GL as a fallback). - --device=dri - # The library lives in ~/Pictures/LightCraft Library by default, and imports usually come from + # The library lives in ~/Pictures/{{library_default}} by default, and imports usually come from # Pictures. Open/Save dialogs go through the file-chooser portal (rfd's xdg-portal backend) and # drag-and-drop through the document portal, so picked folders elsewhere work without broad # filesystem access. @@ -32,19 +33,19 @@ finish-args: # Deliberately not granted: home/host filesystem access, and network. The network is only for # the optional SAM 3 model download (AI Object/Describe masks, docs/ai-masks.md); without it # that download fails with an error and everything else works. Users who want it run - # `flatpak override --user --share=network ai.storyteller.lightcraft`. + # `flatpak override --user --share=network {{app_id}}`. modules: - - name: lightcraft + - name: {{binary}} buildsystem: simple build-commands: - - install -Dm755 bin/lightcraft /app/bin/lightcraft - - install -Dm755 bin/lightcraft-cli /app/bin/lightcraft-cli - - install -Dm644 share/applications/ai.storyteller.lightcraft.desktop /app/share/applications/ai.storyteller.lightcraft.desktop + - install -Dm755 bin/{{binary}} /app/bin/{{binary}} + - install -Dm755 bin/{{cli_binary}} /app/bin/{{cli_binary}} + - install -Dm644 share/applications/{{app_id}}.desktop /app/share/applications/{{app_id}}.desktop # The same MIME definitions the deb/rpm install. - - install -Dm644 share/mime/packages/ai.storyteller.lightcraft.xml /app/share/mime/packages/ai.storyteller.lightcraft.xml + - install -Dm644 share/mime/packages/{{app_id}}.xml /app/share/mime/packages/{{app_id}}.xml # Already has the release's version and date substituted by package.sh. - - install -Dm644 share/metainfo/ai.storyteller.lightcraft.metainfo.xml /app/share/metainfo/ai.storyteller.lightcraft.metainfo.xml - - mkdir -p /app/share/icons /app/share/doc && cp -R share/icons/hicolor /app/share/icons/ && cp -R share/doc/lightcraft /app/share/doc/ + - install -Dm644 share/metainfo/{{app_id}}.metainfo.xml /app/share/metainfo/{{app_id}}.metainfo.xml + - mkdir -p /app/share/icons /app/share/doc && cp -R share/icons/hicolor /app/share/icons/ && cp -R share/doc/{{binary}} /app/share/doc/ sources: - type: dir path: stage diff --git a/packaging/linux/flatpak/ai.storyteller.lightcraft.yml b/packaging/linux/flatpak/{app_id}.yml.in similarity index 51% rename from packaging/linux/flatpak/ai.storyteller.lightcraft.yml rename to packaging/linux/flatpak/{app_id}.yml.in index 079c85dfd2..7f71a3894e 100644 --- a/packaging/linux/flatpak/ai.storyteller.lightcraft.yml +++ b/packaging/linux/flatpak/{app_id}.yml.in @@ -1,24 +1,26 @@ -# Flatpak manifest for LightCraft, ready for a Flathub submission. +# Flatpak manifest for {{display_name}}, ready for a Flathub submission. A template: `cargo xtask package` +# renders it, with the desktop entry, MIME type and metainfo it installs, into target/package/linux/. # # Flatpak builds run offline, so the crate sources must be vendored first. From the repo root: # +# cargo xtask package --render-only # curl -fsSLO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.py -# python3 flatpak-cargo-generator.py Cargo.lock -o packaging/linux/flatpak/cargo-sources.json -# flatpak-builder --user --install --force-clean build-flatpak packaging/linux/flatpak/ai.storyteller.lightcraft.yml -# flatpak run ai.storyteller.lightcraft +# python3 flatpak-cargo-generator.py Cargo.lock -o target/package/linux/flatpak/cargo-sources.json +# flatpak-builder --user --install --force-clean build-flatpak target/package/linux/flatpak/{{app_id}}.yml +# flatpak run {{app_id}} # -# For Flathub, replace the `dir` source with a `git` source pinned to a release tag and commit. +# For Flathub, replace the workspace `dir` source with a `git` source pinned to a release tag and commit. # -# ai.storyteller.lightcraft.bundle.yml (same directory) builds the .flatpak attached to every +# {app_id}.bundle.yml.in (same directory) builds the .flatpak attached to every # release from the prebuilt binaries. Keep runtime-version and finish-args identical in both # (packaging-lint checks this). -id: ai.storyteller.lightcraft +id: {{app_id}} runtime: org.freedesktop.Platform runtime-version: '25.08' sdk: org.freedesktop.Sdk sdk-extensions: - org.freedesktop.Sdk.Extension.rust-stable -command: lightcraft +command: {{binary}} finish-args: # Display: Wayland first; X11 only when no Wayland compositor is running. - --socket=wayland @@ -27,7 +29,7 @@ finish-args: - --share=ipc # GPU access for the wgpu renderer (Vulkan, or GL as a fallback). - --device=dri - # The library lives in ~/Pictures/LightCraft Library by default, and imports usually come from + # The library lives in ~/Pictures/{{library_default}} by default, and imports usually come from # Pictures. Open/Save dialogs go through the file-chooser portal (rfd's xdg-portal backend) and # drag-and-drop through the document portal, so picked folders elsewhere work without broad # filesystem access. @@ -35,35 +37,40 @@ finish-args: # Deliberately not granted: home/host filesystem access, and network. The network is only for # the optional SAM 3 model download (AI Object/Describe masks, docs/ai-masks.md); without it # that download fails with an error and everything else works. Users who want it run - # `flatpak override --user --share=network ai.storyteller.lightcraft`. + # `flatpak override --user --share=network {{app_id}}`. build-options: append-path: /usr/lib/sdk/rust-stable/bin modules: - - name: lightcraft + - name: {{binary}} buildsystem: simple build-options: env: - CARGO_HOME: /run/build/lightcraft/cargo + CARGO_HOME: /run/build/{{binary}}/cargo CARGO_NET_OFFLINE: 'true' build-commands: - cargo --offline build --release --locked -p dac-app -p dac-cli - - install -Dm755 target/release/lightcraft /app/bin/lightcraft - - install -Dm755 target/release/lightcraft-cli /app/bin/lightcraft-cli - - install -Dm644 packaging/linux/ai.storyteller.lightcraft.desktop /app/share/applications/ai.storyteller.lightcraft.desktop - - install -Dm644 packaging/linux/ai.storyteller.lightcraft.mime.xml /app/share/mime/packages/ai.storyteller.lightcraft.xml - - mkdir -p /app/share/icons && cp -R assets/app-icon/hicolor /app/share/icons/ + - install -Dm755 target/release/app /app/bin/{{binary}} + - install -Dm755 target/release/app-cli /app/bin/{{cli_binary}} + - install -Dm644 rendered/{{app_id}}.desktop /app/share/applications/{{app_id}}.desktop + - install -Dm644 rendered/{{app_id}}.mime.xml /app/share/mime/packages/{{app_id}}.xml + - install -Dm644 rendered/{{app_id}}.metainfo.xml /app/share/metainfo/{{app_id}}.metainfo.xml - >- - version=$(awk '/^\[/{p=($0=="[workspace.package]");next} p&&$1=="version"{gsub(/[" ]/,"",$3);print $3;exit}' Cargo.toml); - install -d /app/share/metainfo; - sed -e "s/@VERSION@/$version/" -e "s/@DATE@/$(date -u +%Y-%m-%d)/" - packaging/linux/ai.storyteller.lightcraft.metainfo.xml.in > /app/share/metainfo/ai.storyteller.lightcraft.metainfo.xml + for f in assets/app-icon/hicolor/*/apps/*; do + size=$(basename "$(dirname "$(dirname "$f")")"); + install -Dm644 "$f" "/app/share/icons/hicolor/$size/apps/{{app_id}}.${f##*.}"; + done sources: + # the workspace (this file is rendered to target/package/linux/flatpak/) - type: dir - path: ../../.. + path: ../../../.. skip: - target - dist - corpus - build-flatpak - .flatpak-builder + # the rendered desktop entry, MIME type and metainfo (version and date filled in) + - type: dir + path: .. + dest: rendered - cargo-sources.json diff --git a/packaging/linux/nfpm.yaml b/packaging/linux/nfpm.yaml.in similarity index 69% rename from packaging/linux/nfpm.yaml rename to packaging/linux/nfpm.yaml.in index 3242910a52..a7c5c15657 100644 --- a/packaging/linux/nfpm.yaml +++ b/packaging/linux/nfpm.yaml.in @@ -1,9 +1,7 @@ -# .deb and .rpm packages (nfpm: https://nfpm.goreleaser.com). Run by package.sh, which stages -# the file tree, substitutes its path for ${STAGE} (nfpm doesn't expand env vars in `src`) and -# exports VERSION and NFPM_ARCH. -# -# nfpm package -f packaging/linux/nfpm.yaml -p deb -t dist/release/ -name: lightcraft +# .deb and .rpm packages (nfpm: https://nfpm.goreleaser.com). A template: package.sh fills the {{…}} +# placeholders from brand.toml, stages the file tree, substitutes its path for ${STAGE} (nfpm +# doesn't expand env vars in `src`) and exports VERSION, NFPM_ARCH and PACKAGE_MAINTAINER. +name: {{binary}} arch: ${NFPM_ARCH} platform: linux version: ${VERSION} @@ -12,15 +10,15 @@ version_schema: semver release: 1 section: graphics priority: optional -maintainer: ${LIGHTCRAFT_MAINTAINER} -vendor: Learning Machines LLC -homepage: https://getartcraft.com/apps/app -license: MIT OR Apache-2.0 +maintainer: ${PACKAGE_MAINTAINER} +vendor: {{vendor}} +homepage: {{homepage}} +license: MIT AND Apache-2.0 description: |- Open-source, native photo library and raw developer that works the way Lightroom users expect. Import, rate, keyword and organise photos; develop raw files non-destructively with exposure, tone, color grading, masks and - presets; GPU processing (wgpu). Includes lightcraft-cli, a headless renderer + presets; GPU processing (wgpu). Includes {{cli_binary}}, a headless renderer and command runner. # The binaries link only glibc and libgcc_s directly. Windowing (X11/Wayland, xkbcommon) and the @@ -56,11 +54,11 @@ overrides: - xdg-desktop-portal contents: - - src: ${STAGE}/usr/bin/lightcraft - dst: /usr/bin/lightcraft + - src: ${STAGE}/usr/bin/{{binary}} + dst: /usr/bin/{{binary}} file_info: { mode: 0755 } - - src: ${STAGE}/usr/bin/lightcraft-cli - dst: /usr/bin/lightcraft-cli + - src: ${STAGE}/usr/bin/{{cli_binary}} + dst: /usr/bin/{{cli_binary}} file_info: { mode: 0755 } - src: ${STAGE}/usr/share/ dst: /usr/share/ diff --git a/packaging/linux/package.sh b/packaging/linux/package.sh index 361a4a315d..ed7b54bf62 100755 --- a/packaging/linux/package.sh +++ b/packaging/linux/package.sh @@ -1,11 +1,12 @@ #!/usr/bin/env bash -# Build and package LightCraft for Linux ( is x86_64 or aarch64): +# Build and package the app for Linux ( is x86_64 or aarch64; and every other name +# come from brand.toml): # -# $DIST/lightcraft--linux-.AppImage any distro with glibc >= the build host's -# $DIST/lightcraft--linux-.AppImage.zsync delta updates (needs zsyncmake) -# $DIST/lightcraft--linux-.deb Debian, Ubuntu, Mint, Pop!_OS, ... -# $DIST/lightcraft--linux-.rpm Fedora, openSUSE, RHEL, ... -# $DIST/lightcraft--linux-.tar.gz plain FHS-style tree (bin/, share/) +# $DIST/--linux-.AppImage any distro with glibc >= the build host's +# $DIST/--linux-.AppImage.zsync delta updates (needs zsyncmake) +# $DIST/--linux-.deb Debian, Ubuntu, Mint, Pop!_OS, ... +# $DIST/--linux-.rpm Fedora, openSUSE, RHEL, ... +# $DIST/--linux-.tar.gz plain FHS-style tree (bin/, share/) # # Usage: packaging/linux/package.sh [--skip-build] [--formats "appimage deb rpm tar"] # @@ -17,7 +18,9 @@ set -euo pipefail # shellcheck source=../env.sh . "$(dirname "${BASH_SOURCE[0]}")/../env.sh" HERE="$ROOT/packaging/linux" -APP_ID=ai.storyteller.lightcraft +APP_ID=$BRAND_APP_ID +APP=$BRAND_BINARY +CLI=$BRAND_CLI_BINARY SKIP_BUILD=0 FORMATS="appimage deb rpm tar" @@ -36,10 +39,10 @@ case "$ARCH" in aarch64 | arm64) ARCH=aarch64; DEB_ARCH=arm64 ;; *) echo "unsupported architecture $ARCH" >&2; exit 2 ;; esac -export LIGHTCRAFT_MAINTAINER="${LIGHTCRAFT_MAINTAINER:-LightCraft maintainers }" -BASENAME="lightcraft-$VERSION-linux-$ARCH" +export PACKAGE_MAINTAINER="${PACKAGE_MAINTAINER:-$BRAND_VENDOR }" +BASENAME="$APP-$VERSION-linux-$ARCH" -echo "==> LightCraft $VERSION for Linux $ARCH ($FORMATS)" +echo "==> $BRAND_DISPLAY_NAME $VERSION for Linux $ARCH ($FORMATS)" if [ "$SKIP_BUILD" = 0 ]; then (cd "$ROOT" && cargo build --release --locked -p dac-app -p dac-cli) @@ -50,18 +53,15 @@ STAGE="$WORK/root" rm -rf "$WORK" # ---- stage an FHS tree (shared by every format) ------------------------------------------------- -install -Dm755 "$BIN/lightcraft" "$STAGE/usr/bin/lightcraft" -install -Dm755 "$BIN/lightcraft-cli" "$STAGE/usr/bin/lightcraft-cli" -strip "$STAGE/usr/bin/lightcraft" "$STAGE/usr/bin/lightcraft-cli" 2>/dev/null || true -install -Dm644 "$HERE/$APP_ID.desktop" "$STAGE/usr/share/applications/$APP_ID.desktop" -install -Dm644 "$HERE/$APP_ID.mime.xml" "$STAGE/usr/share/mime/packages/$APP_ID.xml" -mkdir -p "$STAGE/usr/share/metainfo" -sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$LIGHTCRAFT_BUILD_DATE/g" \ - "$HERE/$APP_ID.metainfo.xml.in" >"$STAGE/usr/share/metainfo/$APP_ID.metainfo.xml" -mkdir -p "$STAGE/usr/share/icons" -cp -R "$ROOT/assets/app-icon/hicolor" "$STAGE/usr/share/icons/" -mkdir -p "$STAGE/usr/share/doc/lightcraft" -copy_docs "$STAGE/usr/share/doc/lightcraft" +# The cargo binaries have neutral names (app, app-cli); packages carry the brand's. +stage_binaries "$BIN" "$STAGE/usr/bin" +strip "$STAGE/usr/bin/$APP" "$STAGE/usr/bin/$CLI" 2>/dev/null || true +brand_render "$HERE/{app_id}.desktop.in" "$STAGE/usr/share/applications/$APP_ID.desktop" +brand_render "$HERE/{app_id}.mime.xml.in" "$STAGE/usr/share/mime/packages/$APP_ID.xml" +brand_render "$HERE/{app_id}.metainfo.xml.in" "$STAGE/usr/share/metainfo/$APP_ID.metainfo.xml" +install_icons "$STAGE/usr/share/icons" +mkdir -p "$STAGE/usr/share/doc/$APP" +copy_docs "$STAGE/usr/share/doc/$APP" if command -v desktop-file-validate >/dev/null; then desktop-file-validate "$STAGE/usr/share/applications/$APP_ID.desktop" @@ -86,7 +86,8 @@ if has deb || has rpm; then export VERSION export NFPM_ARCH="$DEB_ARCH" # nfpm expands env vars in fields like `version` and `arch`, but not in `contents[].src`. - sed "s|\${STAGE}|$STAGE|g" "$HERE/nfpm.yaml" >"$WORK/nfpm.yaml" + brand_render "$HERE/nfpm.yaml.in" "$WORK/nfpm.brand.yaml" + sed "s|\${STAGE}|$STAGE|g" "$WORK/nfpm.brand.yaml" >"$WORK/nfpm.yaml" for fmt in deb rpm; do if has "$fmt"; then (cd "$ROOT" && nfpm package -f "$WORK/nfpm.yaml" -p "$fmt" -t "$DIST/$BASENAME.$fmt"); fi done @@ -94,12 +95,12 @@ fi # ---- AppImage ----------------------------------------------------------------------------------- if has appimage; then - APPDIR="$WORK/LightCraft.AppDir" + APPDIR="$WORK/$APP.AppDir" cp -R "$STAGE" "$APPDIR" mv "$APPDIR/usr/share/doc" "$WORK/doc-unused" - ln -s usr/bin/lightcraft "$APPDIR/AppRun" - cp "$HERE/$APP_ID.desktop" "$APPDIR/$APP_ID.desktop" - cp "$ROOT/assets/app-icon/hicolor/256x256/apps/$APP_ID.png" "$APPDIR/$APP_ID.png" + ln -s "usr/bin/$APP" "$APPDIR/AppRun" + cp "$STAGE/usr/share/applications/$APP_ID.desktop" "$APPDIR/$APP_ID.desktop" + cp "$STAGE/usr/share/icons/hicolor/256x256/apps/$APP_ID.png" "$APPDIR/$APP_ID.png" ln -s "$APP_ID.png" "$APPDIR/.DirIcon" TOOL="${APPIMAGETOOL:-$(command -v appimagetool || true)}" @@ -120,13 +121,18 @@ if has appimage; then # Update information: AppImageUpdate, AppImageLauncher and the like read it from the file and # fetch only the blocks that changed in a newer release, through the .zsync published next to # each AppImage on GitHub Releases. `latest` is the newest published release that is not a - # pre-release. A fork's builds point at its own releases through GITHUB_REPOSITORY. - REPO="${GITHUB_REPOSITORY:-storytold/lightcraft}" - UPDATE_INFO="gh-releases-zsync|${REPO%%/*}|${REPO#*/}|latest|lightcraft-*-linux-$ARCH.AppImage.zsync" + # pre-release. Builds point at the releases of GITHUB_REPOSITORY, else of brand.toml's + # repository when that is on GitHub; with neither, the AppImage has no update information. + REPO="${GITHUB_REPOSITORY:-}" + case "$BRAND_REPOSITORY" in https://github.com/*/*) REPO="${REPO:-${BRAND_REPOSITORY#https://github.com/}}" ;; esac + UPDATE_ARGS=() + if [ -n "$REPO" ]; then + UPDATE_ARGS=(-u "gh-releases-zsync|${REPO%%/*}|${REPO#*/}|latest|$APP-*-linux-$ARCH.AppImage.zsync") + fi # Extract-and-run: works without FUSE (containers, CI). The output embeds the static runtime, # so users don't need libfuse2 either. With zsyncmake on the host (CI installs the zsync # package) appimagetool also writes the .zsync, into its working directory, hence the cd. - (cd "$DIST" && ARCH="$ARCH" APPIMAGE_EXTRACT_AND_RUN=1 "$TOOL" --no-appstream -u "$UPDATE_INFO" "$APPDIR" "$OUT") + (cd "$DIST" && ARCH="$ARCH" APPIMAGE_EXTRACT_AND_RUN=1 "$TOOL" --no-appstream ${UPDATE_ARGS[@]+"${UPDATE_ARGS[@]}"} "$APPDIR" "$OUT") echo "wrote $OUT" if [ -s "$OUT.zsync" ]; then echo "wrote $OUT.zsync" @@ -135,6 +141,6 @@ if has appimage; then fi fi -"$STAGE/usr/bin/lightcraft-cli" --version +"$STAGE/usr/bin/$CLI" --version echo "==> done" ls -lh "$DIST" diff --git a/packaging/linux/ai.storyteller.lightcraft.desktop b/packaging/linux/{app_id}.desktop.in similarity index 71% rename from packaging/linux/ai.storyteller.lightcraft.desktop rename to packaging/linux/{app_id}.desktop.in index f827c58202..74ebf3a639 100644 --- a/packaging/linux/ai.storyteller.lightcraft.desktop +++ b/packaging/linux/{app_id}.desktop.in @@ -1,12 +1,12 @@ [Desktop Entry] Type=Application -Name=LightCraft +Name={{display_name}} GenericName=Photo Library and Raw Developer -Comment=Organise photos and develop raw files, non-destructively -Exec=lightcraft %F -Icon=ai.storyteller.lightcraft +Comment={{tagline}} +Exec={{binary}} %F +Icon={{app_id}} Terminal=false Categories=Graphics;2DGraphics;RasterGraphics;Photography; Keywords=photo;raw;camera;library;develop; -StartupWMClass=ai.storyteller.lightcraft +StartupWMClass={{app_id}} MimeType=image/jpeg;image/png;image/tiff;image/webp;image/x-adobe-dng;image/x-sony-arw;image/x-canon-cr2;image/x-canon-cr3;image/x-nikon-nef;image/x-fuji-raf;image/x-olympus-orf;image/x-panasonic-rw2;image/x-panasonic-rw;image/x-pentax-pef; diff --git a/packaging/linux/{app_id}.metainfo.xml.in b/packaging/linux/{app_id}.metainfo.xml.in new file mode 100644 index 0000000000..51a2d09437 --- /dev/null +++ b/packaging/linux/{app_id}.metainfo.xml.in @@ -0,0 +1,54 @@ + + + + {{app_id}} + CC0-1.0 + MIT AND Apache-2.0 + {{display_name}} + {{tagline}} + + {{vendor}} + + +

+ {{display_name}} is a photo library and raw developer. Organise photos and develop raw files, non-destructively. +

+
+ {{app_id}}.desktop + {{app_id}} + + {{homepage}} + {{repository}}/issues + {{repository}} + + Graphics + RasterGraphics + Photography + + + photo + raw + library + develop + + + #9fd0ff + #1f64ba + + + 760 + + + keyboard + pointing + tablet + + + {{binary}} + + + + + +
diff --git a/packaging/linux/ai.storyteller.lightcraft.mime.xml b/packaging/linux/{app_id}.mime.xml.in similarity index 100% rename from packaging/linux/ai.storyteller.lightcraft.mime.xml rename to packaging/linux/{app_id}.mime.xml.in diff --git a/packaging/macos/Info.plist.in b/packaging/macos/Info.plist.in index f571d18eda..3a935b66ad 100644 --- a/packaging/macos/Info.plist.in +++ b/packaging/macos/Info.plist.in @@ -1,19 +1,19 @@ - + CFBundleDevelopmentRegion en CFBundleDisplayName - LightCraft + {{display_name}} CFBundleName - LightCraft + {{short_name}} CFBundleExecutable - LightCraft + {{display_name}} CFBundleIdentifier - ai.storyteller.lightcraft + {{app_id}} CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType @@ -21,15 +21,15 @@ CFBundleSignature ???? CFBundleShortVersionString - @SHORT_VERSION@ + {{short_version}} CFBundleVersion - @SHORT_VERSION@ - LightCraftVersion - @VERSION@ - LightCraftBuildCommit - @BUILD_SHA@ + {{short_version}} + AppFullVersion + {{version}} + AppBuildCommit + {{build_sha}} CFBundleIconFile - LightCraft + {{display_name}} LSApplicationCategoryType public.app-category.graphics-design + UTExportedTypeDeclarations UTTypeIdentifier - ai.storyteller.lightcraft.document + {{app_id}}.document UTTypeDescription - LightCraft Document + {{display_name}} Document UTTypeConformsTo public.data public.image UTTypeIconFile - LightCraft + {{display_name}} UTTypeTagSpecification public.filename-extension pcraft public.mime-type - application/x-lightcraft + application/x-{{binary}} @@ -90,7 +90,7 @@ UTTypeIdentifier - ai.storyteller.lightcraft.qoi + {{app_id}}.qoi UTTypeDescription QOI Image UTTypeConformsTo diff --git a/packaging/macos/dmg/README.md b/packaging/macos/dmg/README.md index 2b2e1a1338..2eab1a3b92 100644 --- a/packaging/macos/dmg/README.md +++ b/packaging/macos/dmg/README.md @@ -7,17 +7,17 @@ Finder scripting on CI, nothing extra installed in the signing job). | File | What | |---|---| -| `background.svg` | Source of the background: the app icon (`assets/app-icon/lightcraft.svg`, linked, not copied) cropped as a cover on the LightCraft colour field (`#f2a516`), Ink and Paper. Its text (Inter, JetBrains Mono) is outlined, so rendering it needs no fonts. | +| `background.svg` | Source of the background: the app icon (`brand/icon.svg`, linked, not copied) cropped as a cover on the brand colour field (`#f2a516`), Ink and Paper. Its text (Inter, JetBrains Mono) is outlined, so rendering it needs no fonts. | | `background.tiff` | The background at 1x (660 × 400 px, 72 dpi) and 2x (1320 × 800 px, 144 dpi) in one HiDPI TIFF (Deflate, sRGB). Goes to `.background/background.tiff`. | -| `dmg-layout.DS_Store` | Finder's view settings for the volume: window size, icon size 128, LightCraft.app at (326, 205), `Applications` at (574, 205), and the background. Goes to `.DS_Store` in the image; named so it isn't mistaken for (or ignored like) a Finder-generated `.DS_Store`. | +| `dmg-layout.DS_Store` | Finder's view settings for the volume: window size, icon size 128, `.app` at (326, 205), `Applications` at (574, 205), and the background. Goes to `.DS_Store` in the image; named so it isn't mistaken for (or ignored like) a Finder-generated `.DS_Store`. | | `generate.py` | Writes `background.tiff` and `dmg-layout.DS_Store` from the SVG and the layout above. | ## The volume name has no version -The mounted volume is called `LightCraft`, not `LightCraft `. The layout points at the background +The mounted volume is called `` (brand.toml), not ` `; after changing the name, rerun `generate.py` so `dmg-layout.DS_Store` matches. The layout points at the background through an alias that includes the volume name, and Finder resolves it by that name: with a versioned name the window keeps its size and icon positions but shows no background (tested). -The DMG file name (`lightcraft--macos-.dmg`) still carries the version. +The DMG file name (`--macos-.dmg`) still carries the version. ## Rules diff --git a/packaging/macos/dmg/background.svg b/packaging/macos/dmg/background.svg index 7dd108ea6a..0c0c59bf33 100644 --- a/packaging/macos/dmg/background.svg +++ b/packaging/macos/dmg/background.svg @@ -6,7 +6,7 @@ - + diff --git a/packaging/macos/dmg/generate.py b/packaging/macos/dmg/generate.py index 35305238b0..22b891f9ab 100644 --- a/packaging/macos/dmg/generate.py +++ b/packaging/macos/dmg/generate.py @@ -23,12 +23,16 @@ from PIL import Image, ImageCms HERE = os.path.dirname(os.path.abspath(__file__)) -# Keep in sync with package.sh (volume name) and README.md (layout). -VOLUME = "LightCraft" +# The volume and app names are brand.toml's display_name (package.sh uses the same); rerun this +# script after changing it, since dmg-layout.DS_Store records both. +import tomllib + +with open(os.path.join(HERE, "../../../brand.toml"), "rb") as _f: + VOLUME = tomllib.load(_f)["product"]["display_name"] WIDTH, HEIGHT = 660, 400 # window content, pt; the background's 1x size TITLE_BAR = 32 ICON_SIZE = 128 -ICONS = {"LightCraft.app": (326, 205), "Applications": (574, 205)} +ICONS = {f"{VOLUME}.app": (326, 205), "Applications": (574, 205)} # A fixed date for the alias and the colour profile. Finder never matches it against the image # (each build is a new volume): it finds the background by volume name and path. FIXED_DATE = datetime.datetime(2026, 10, 8, tzinfo=datetime.timezone.utc) diff --git a/packaging/macos/entitlements.plist b/packaging/macos/entitlements.plist index 8b8cd128f9..c8bddcfb37 100644 --- a/packaging/macos/entitlements.plist +++ b/packaging/macos/entitlements.plist @@ -1,6 +1,6 @@ - diff --git a/packaging/macos/import-cert.sh b/packaging/macos/import-cert.sh index ef966034e4..53d16168b3 100755 --- a/packaging/macos/import-cert.sh +++ b/packaging/macos/import-cert.sh @@ -18,8 +18,8 @@ if [ -z "${APPLE_CERTIFICATE:-}" ]; then fi TMP="${RUNNER_TEMP:-${TMPDIR:-/tmp}}" -KEYCHAIN="$TMP/lightcraft-signing.keychain-db" -CERT="$TMP/lightcraft-signing.p12" +KEYCHAIN="$TMP/app-signing.keychain-db" +CERT="$TMP/app-signing.p12" KC_PASS="${KEYCHAIN_PASSWORD:-$(openssl rand -hex 24)}" trap 'rm -f "$CERT"' EXIT diff --git a/packaging/macos/package.sh b/packaging/macos/package.sh index 569f9b0750..38240b6707 100755 --- a/packaging/macos/package.sh +++ b/packaging/macos/package.sh @@ -1,8 +1,9 @@ #!/usr/bin/env bash # Build, sign and (optionally) notarize the macOS release artifacts: # -# $DIST/lightcraft--macos-.dmg LightCraft.app on a drag-to-Applications DMG -# $DIST/lightcraft-cli--macos-.zip the headless CLI +# $DIST/--macos-.dmg .app on a drag-to-Applications DMG +# $DIST/--macos-.zip the headless CLI +# (names from brand.toml) # # Usage: packaging/macos/package.sh [--arch universal|aarch64|x86_64] [--skip-build] # @@ -37,11 +38,12 @@ esac # Keep in sync with LSMinimumSystemVersion in Info.plist.in. export MACOSX_DEPLOYMENT_TARGET=11.0 IDENTITY="${MACOS_SIGN_IDENTITY:--}" -SHORT_VERSION="${VERSION%%-*}" WORK="$CARGO_TARGET_DIR/macos-package" -APP="$WORK/LightCraft.app" -DMG="$DIST/lightcraft-$VERSION-macos-$ARCH.dmg" -CLI_ZIP="$DIST/lightcraft-cli-$VERSION-macos-$ARCH.zip" +NAME="$BRAND_DISPLAY_NAME" +CLI="$BRAND_CLI_BINARY" +APP="$WORK/$NAME.app" +DMG="$DIST/$BRAND_BINARY-$VERSION-macos-$ARCH.dmg" +CLI_ZIP="$DIST/$CLI-$VERSION-macos-$ARCH.zip" NOTARIZE=0 if [ "$IDENTITY" = "-" ]; then @@ -52,7 +54,7 @@ else warn "macOS: APPLE_ID / APPLE_PASSWORD / APPLE_TEAM_ID incomplete; signed but not notarized" fi -echo "==> LightCraft $VERSION for macOS ($ARCH), identity: $IDENTITY, notarize: $NOTARIZE" +echo "==> $NAME $VERSION for macOS ($ARCH), identity: $IDENTITY, notarize: $NOTARIZE" # ---- build ------------------------------------------------------------------------------------- if [ "$SKIP_BUILD" = 0 ]; then @@ -63,11 +65,13 @@ fi rm -rf "$WORK" mkdir -p "$WORK/bin" -for bin in lightcraft lightcraft-cli; do +# neutral cargo names (app, app-cli) -> brand names +for pair in "app:$BRAND_BINARY" "app-cli:$CLI"; do + bin="${pair%%:*}" out="${pair#*:}" inputs=() for t in "${TARGETS[@]}"; do inputs+=("$CARGO_TARGET_DIR/$t/release/$bin"); done - lipo -create -output "$WORK/bin/$bin" "${inputs[@]}" - lipo -info "$WORK/bin/$bin" + lipo -create -output "$WORK/bin/$out" "${inputs[@]}" + lipo -info "$WORK/bin/$out" done # ---- signing helpers --------------------------------------------------------------------------- @@ -97,15 +101,14 @@ notarize() { fi } -# ---- LightCraft.app ---------------------------------------------------------------------------- +# ---- .app ---------------------------------------------------------------------------- echo "==> assembling $APP" mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources" # Executable and icon carry the display name (CFBundleExecutable / CFBundleIconFile). -cp "$WORK/bin/lightcraft" "$APP/Contents/MacOS/LightCraft" -cp "$ROOT/assets/app-icon/lightcraft.icns" "$APP/Contents/Resources/LightCraft.icns" -sed -e "s/@VERSION@/$VERSION/g" -e "s/@SHORT_VERSION@/$SHORT_VERSION/g" \ - -e "s/@BUILD_SHA@/${LIGHTCRAFT_BUILD_SHA:-unknown}/g" \ - "$HERE/Info.plist.in" >"$APP/Contents/Info.plist" +cp "$WORK/bin/$BRAND_BINARY" "$APP/Contents/MacOS/$NAME" +ICNS="$(ls "$ROOT"/assets/app-icon/*.icns | head -n 1)" +cp "$ICNS" "$APP/Contents/Resources/$NAME.icns" +brand_render "$HERE/Info.plist.in" "$APP/Contents/Info.plist" plutil -lint "$APP/Contents/Info.plist" printf 'APPL????' >"$APP/Contents/PkgInfo" # Licences (and the craft-fonts font licences when built with CRAFT_FONTS_DIR) inside the bundle. @@ -114,13 +117,13 @@ copy_docs "$APP/Contents/Resources/Licenses" # Sign inside-out: nested code first, then the bundle itself (no --deep on the final signature). # Today the only nested code is the main executable; frameworks/helpers would be signed here too. -sign --options runtime --entitlements "$HERE/entitlements.plist" "$APP/Contents/MacOS/LightCraft" +sign --options runtime --entitlements "$HERE/entitlements.plist" "$APP/Contents/MacOS/$NAME" sign --options runtime --entitlements "$HERE/entitlements.plist" "$APP" codesign --verify --strict --deep --verbose=2 "$APP" if [ "$NOTARIZE" = 1 ]; then - ditto -c -k --keepParent "$APP" "$WORK/LightCraft-notarize.zip" - notarize "$WORK/LightCraft-notarize.zip" + ditto -c -k --keepParent "$APP" "$WORK/app-notarize.zip" + notarize "$WORK/app-notarize.zip" xcrun stapler staple "$APP" xcrun stapler validate "$APP" spctl --assess --type execute -vvv "$APP" @@ -130,7 +133,7 @@ fi echo "==> building $DMG" STAGE="$WORK/dmg" mkdir -p "$STAGE" -ditto "$APP" "$STAGE/LightCraft.app" +ditto "$APP" "$STAGE/$NAME.app" ln -s /Applications "$STAGE/Applications" # Finder window layout: background, icon size and positions (packaging/macos/dmg/README.md). mkdir -p "$STAGE/.background" @@ -140,7 +143,7 @@ rm -f "$DMG" "$WORK/raw.dmg" # makehybrid + convert builds the image without attaching a device, unlike `create -srcfolder`, # which is flaky on CI runners ("Resource busy") and hangs in sandboxed sessions. # The volume name has no version: .DS_Store finds the background through an alias that includes it. -hdiutil makehybrid -hfs -hfs-volume-name "LightCraft" -hfs-openfolder "$STAGE" -o "$WORK/raw.dmg" "$STAGE" +hdiutil makehybrid -hfs -hfs-volume-name "$NAME" -hfs-openfolder "$STAGE" -o "$WORK/raw.dmg" "$STAGE" hdiutil convert "$WORK/raw.dmg" -format UDZO -imagekey zlib-level=9 -o "$DMG" rm -f "$WORK/raw.dmg" sign "$DMG" @@ -154,17 +157,17 @@ fi # ---- CLI --------------------------------------------------------------------------------------- echo "==> building $CLI_ZIP" -CLI_DIR="$WORK/lightcraft-cli-$VERSION-macos-$ARCH" +CLI_DIR="$WORK/$CLI-$VERSION-macos-$ARCH" mkdir -p "$CLI_DIR" -cp "$WORK/bin/lightcraft-cli" "$CLI_DIR/" +cp "$WORK/bin/$CLI" "$CLI_DIR/" copy_docs "$CLI_DIR" -sign --options runtime "$CLI_DIR/lightcraft-cli" -codesign --verify --strict --verbose=2 "$CLI_DIR/lightcraft-cli" +sign --options runtime "$CLI_DIR/$CLI" +codesign --verify --strict --verbose=2 "$CLI_DIR/$CLI" rm -f "$CLI_ZIP" ditto -c -k --keepParent "$CLI_DIR" "$CLI_ZIP" # A bare Mach-O can't carry a stapled ticket; Gatekeeper looks the notarization up online. if [ "$NOTARIZE" = 1 ]; then notarize "$CLI_ZIP"; fi -"$WORK/bin/lightcraft-cli" --version +"$WORK/bin/$CLI" --version echo "==> done" ls -lh "$DMG" "$CLI_ZIP" diff --git a/packaging/web/README.md b/packaging/web/HOSTING.md.in similarity index 91% rename from packaging/web/README.md rename to packaging/web/HOSTING.md.in index e938819345..9622fc7589 100644 --- a/packaging/web/README.md +++ b/packaging/web/HOSTING.md.in @@ -1,4 +1,4 @@ -# Hosting LightCraft for the web +# Hosting {{display_name}} for the web > **Experimental.** The browser version keeps its library (catalog and imported photos) in the > browser's own storage for the site. Browsers may clear that storage (site data cleared, @@ -6,8 +6,8 @@ > keep their original photos elsewhere and to use **File ▸ Back Up Library…**. See > `docs/web.md` in the source for details. -`lightcraft-web-.zip` (from the GitHub release, or `packaging/web/package.sh`) holds a -static site in `lightcraft-web-/`: +`{{binary}}-web-.zip` (from the GitHub release, or `packaging/web/package.sh`) holds a +static site in `{{binary}}-web-/`: | File | What it is | |---|---| @@ -15,7 +15,7 @@ static site in `lightcraft-web-/`: | `dac_web.js` | wasm-bindgen glue (generated, ES module) | | `dac_web_bg.wasm` | The app, about 13 MB (about 3 MB with brotli) | | `worker.js` | Starts the render workers (each runs the same module) | -| `lightcraft_zh_hans.otf` | Simplified Chinese UI font, included when built with `CRAFT_FONTS_DIR` | +| `app_zh_hans.otf` | Simplified Chinese UI font, included when built with `CRAFT_FONTS_DIR` | | `OFL-noto-sans-cjk-sc.txt` | The bundled Chinese font's SIL Open Font License | | `*.gz`, `*.br` | Precompressed copies of the files above (optional to serve) | | `_headers`, `.htaccess` | Sample header rules for Netlify/Cloudflare Pages and Apache | @@ -25,7 +25,7 @@ There is no server-side code. Upload the folder's contents anywhere that serves ## Any path works All URLs in `index.html` are relative, so the site works at a domain root -(`https://example.com/`), under a prefix (`https://example.com/tools/lightcraft/`) and from a +(`https://example.com/`), under a prefix (`https://example.com/tools/{{binary}}/`) and from a CDN bucket. ## Required server settings @@ -52,7 +52,7 @@ CDN bucket. nginx example: ```nginx -location /lightcraft/ { +location /{{binary}}/ { types { application/wasm wasm; text/javascript js; text/html html; } gzip_static on; # serves the .gz copies # brotli_static on; # with ngx_brotli: serves the .br copies @@ -75,8 +75,8 @@ One tab at a time can have the library open; a second tab shows a message instea ```html
Editing The Great Wave off Kanagawa with type layers and adjustment layers