docs: README (MCP, CLI, export, status, contributing), AGENTS.md (asset enforcement, crash recovery, testing/perf), screenshots re-captured with Inter
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No files matched your search
@@ -9,27 +9,55 @@ LightCraft is a clean-room, open-source, pure-Rust photo library + non-destructi
|
||||
|
||||
`plan/` is gitignored (local-only).
|
||||
|
||||
**Resuming after a crash / another session:** check `git status` on main, `git worktree list`, and each worktree's
|
||||
`git log main..HEAD` + `git status` for unmerged commits or uncommitted work before starting anything new. Commit small
|
||||
and often so a crash loses minutes, not hours.
|
||||
|
||||
## Non-negotiables
|
||||
- **Clean-room.** Never read/disassemble anything inside Adobe app bundles (names/listings only). Never copy Adobe icons, presets, profiles (DCP), lens profiles (LCP), camera matrices, fonts. Observation of the installed Lightroom is read-only (it syncs the user's personal library: never import/edit/rate/delete there). Never copy GPL/LGPL/AGPL code (darktable, RawTherapee, ART, LibRaw, rawspeed, rawloader, rawler, lensfun, dcraw-derived GPL code…).
|
||||
- **Pure Rust** in the product. No C/C++ dependencies.
|
||||
- **Layering** (`plan/architecture.md` §3, enforced by `cargo xtask layers`): nothing below L5 depends on egui/eframe/winit/rfd.
|
||||
- **Everything is a command** (`crates/engine`): id, label, menu path, shortcut, params, enabled(), run(). UI, CLI, control channel and MCP all dispatch by id. Every slider is a `develop` control spec.
|
||||
- **Resolution independence:** settings use normalized image coordinates and relative radii; previews and exports must match.
|
||||
- **Quality gates** before every commit: `cargo xtask ci` (fmt, clippy -D warnings, tests, layers, wasm).
|
||||
- **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.
|
||||
|
||||
## 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
|
||||
Adobe-published icon sets, sample photos, colour profiles or LUTs — even when OFL/MIT. The UI font is Inter (OFL).
|
||||
- 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.
|
||||
- **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.
|
||||
- Icons drawn in code (e.g. `crates/ui-egui/src/icons.rs`) are original work and are recorded in `assets/ATTRIBUTION.md` as such; do not trace them from Adobe icons.
|
||||
- Demo/test images: generated procedurally by `lightcraft-scenes`, or CC0 downloads kept in the gitignored `corpus/` with their source recorded. Screenshots of Adobe apps live only in the gitignored `plan/` and are never committed or published.
|
||||
- **Enforced:** `cargo xtask assets` (in `ci`) fails when an image/icon/font/sound/video/raw/ICC/XMP file is not matched
|
||||
by a path pattern in the first column of `assets/ATTRIBUTION.md`, when a referenced licence file is missing, when a
|
||||
file name suggests Adobe material, or when an Adobe profile/template format (`.dcp`, `.lcp`, `.lrtemplate`, …) appears.
|
||||
Never weaken this check to make a commit pass — fix the attribution or remove the asset.
|
||||
- When in doubt about an asset's licence: don't use it.
|
||||
|
||||
## Running and looking at the app
|
||||
- `cargo run --release -p lightcraft -- --control 7980` opens the desktop app with the JSON-lines control server (see `docs/control-protocol.md`).
|
||||
- For UI work, **look at the result**: drive via the control channel and take `ui.screenshot`, compare with `plan/lightroom/screenshots/`.
|
||||
- MCP: `lightcraft-cli mcp` (see `docs/mcp.md`).
|
||||
- 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`.
|
||||
- Export goes through `lightcraft_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`.
|
||||
- Parallel agents: separate git worktrees and `CARGO_TARGET_DIR=target/agent-<name>`; keep every `Cargo.toml` valid at all times (the `crates/*` glob means one broken manifest breaks everyone).
|
||||
- Test corpora: `cargo xtask corpus --download` into `corpus/` (gitignored, CC0 only). Never commit media.
|
||||
|
||||
## Testing & performance (do this often)
|
||||
- Unit/property tests next to the code; end-to-end tests drive real binaries (`crates/mcp/tests/e2e.rs`,
|
||||
`apps/lightcraft-cli/tests/`). New features need at least one test that would fail without them.
|
||||
- **Run the app after every user-visible change**: launch with `--control 7980`, drive it with a JSON-lines script
|
||||
(`docs/showcase/run.py file.jsonl`), take `ui.screenshot`, and look at it. Check `ui.inspect` → `perf`.
|
||||
- **Measure, don't guess**: `LIGHTCRAFT_PROFILE=1` 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 (`lightcraft-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`, `wasm`, `corpus`, `stats`).
|
||||
@@ -9,27 +9,55 @@ LightCraft is a clean-room, open-source, pure-Rust photo library + non-destructi
|
||||
|
||||
`plan/` is gitignored (local-only).
|
||||
|
||||
**Resuming after a crash / another session:** check `git status` on main, `git worktree list`, and each worktree's
|
||||
`git log main..HEAD` + `git status` for unmerged commits or uncommitted work before starting anything new. Commit small
|
||||
and often so a crash loses minutes, not hours.
|
||||
|
||||
## Non-negotiables
|
||||
- **Clean-room.** Never read/disassemble anything inside Adobe app bundles (names/listings only). Never copy Adobe icons, presets, profiles (DCP), lens profiles (LCP), camera matrices, fonts. Observation of the installed Lightroom is read-only (it syncs the user's personal library: never import/edit/rate/delete there). Never copy GPL/LGPL/AGPL code (darktable, RawTherapee, ART, LibRaw, rawspeed, rawloader, rawler, lensfun, dcraw-derived GPL code…).
|
||||
- **Pure Rust** in the product. No C/C++ dependencies.
|
||||
- **Layering** (`plan/architecture.md` §3, enforced by `cargo xtask layers`): nothing below L5 depends on egui/eframe/winit/rfd.
|
||||
- **Everything is a command** (`crates/engine`): id, label, menu path, shortcut, params, enabled(), run(). UI, CLI, control channel and MCP all dispatch by id. Every slider is a `develop` control spec.
|
||||
- **Resolution independence:** settings use normalized image coordinates and relative radii; previews and exports must match.
|
||||
- **Quality gates** before every commit: `cargo xtask ci` (fmt, clippy -D warnings, tests, layers, wasm).
|
||||
- **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.
|
||||
|
||||
## 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
|
||||
Adobe-published icon sets, sample photos, colour profiles or LUTs — even when OFL/MIT. The UI font is Inter (OFL).
|
||||
- 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.
|
||||
- **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.
|
||||
- Icons drawn in code (e.g. `crates/ui-egui/src/icons.rs`) are original work and are recorded in `assets/ATTRIBUTION.md` as such; do not trace them from Adobe icons.
|
||||
- Demo/test images: generated procedurally by `lightcraft-scenes`, or CC0 downloads kept in the gitignored `corpus/` with their source recorded. Screenshots of Adobe apps live only in the gitignored `plan/` and are never committed or published.
|
||||
- **Enforced:** `cargo xtask assets` (in `ci`) fails when an image/icon/font/sound/video/raw/ICC/XMP file is not matched
|
||||
by a path pattern in the first column of `assets/ATTRIBUTION.md`, when a referenced licence file is missing, when a
|
||||
file name suggests Adobe material, or when an Adobe profile/template format (`.dcp`, `.lcp`, `.lrtemplate`, …) appears.
|
||||
Never weaken this check to make a commit pass — fix the attribution or remove the asset.
|
||||
- When in doubt about an asset's licence: don't use it.
|
||||
|
||||
## Running and looking at the app
|
||||
- `cargo run --release -p lightcraft -- --control 7980` opens the desktop app with the JSON-lines control server (see `docs/control-protocol.md`).
|
||||
- For UI work, **look at the result**: drive via the control channel and take `ui.screenshot`, compare with `plan/lightroom/screenshots/`.
|
||||
- MCP: `lightcraft-cli mcp` (see `docs/mcp.md`).
|
||||
- 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`.
|
||||
- Export goes through `lightcraft_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`.
|
||||
- Parallel agents: separate git worktrees and `CARGO_TARGET_DIR=target/agent-<name>`; keep every `Cargo.toml` valid at all times (the `crates/*` glob means one broken manifest breaks everyone).
|
||||
- Test corpora: `cargo xtask corpus --download` into `corpus/` (gitignored, CC0 only). Never commit media.
|
||||
|
||||
## Testing & performance (do this often)
|
||||
- Unit/property tests next to the code; end-to-end tests drive real binaries (`crates/mcp/tests/e2e.rs`,
|
||||
`apps/lightcraft-cli/tests/`). New features need at least one test that would fail without them.
|
||||
- **Run the app after every user-visible change**: launch with `--control 7980`, drive it with a JSON-lines script
|
||||
(`docs/showcase/run.py file.jsonl`), take `ui.screenshot`, and look at it. Check `ui.inspect` → `perf`.
|
||||
- **Measure, don't guess**: `LIGHTCRAFT_PROFILE=1` 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 (`lightcraft-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`, `wasm`, `corpus`, `stats`).
|
||||
@@ -174,12 +174,23 @@ lightcraft --control 7980 ~/Pictures/trip
|
||||
{"method": "ui.screenshot", "params": {"path": "after.png"}}
|
||||
```
|
||||
|
||||
- **90 engine commands** and **48 UI commands** — list them all with `engine.commands`, read every slider's range,
|
||||
- **91 engine commands** and **48 UI commands** — list them all with `engine.commands`, read every slider's range,
|
||||
default and current value with `develop.controls`.
|
||||
- **MCP server** — `lightcraft-cli mcp` gives Claude (or any MCP client) ~100 tools: import, query, develop, mask,
|
||||
render (returned as an image), export — headless, or attached to the running app with screenshots, clicks and
|
||||
gestures. See [docs/mcp.md](docs/mcp.md).
|
||||
|
||||
```sh
|
||||
cargo build --release -p lightcraft-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
|
||||
```
|
||||
- **Scriptable CLI** — `lightcraft-cli 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 can operate the real UI, not a
|
||||
side door.
|
||||
- The screenshots in this README were produced by [`docs/showcase/`](docs/showcase/) scripts, end to end.
|
||||
Protocol reference: [docs/control-protocol.md](docs/control-protocol.md).
|
||||
|
||||
<br>
|
||||
|
||||
@@ -208,12 +219,14 @@ LightCraft is young and moving fast — see the [roadmap](ROADMAP.md) for estima
|
||||
| Light, Color, Effects, Tone Curve, Color Mixer, Color Grading, B&W | ✅ |
|
||||
| Masking: brush, linear, radial, luminance/colour range, add/subtract/intersect | ✅ (AI subject/sky use classical heuristics for now) |
|
||||
| Crop, straighten, flip, rotate, aspect ratios, overlays | ✅ |
|
||||
| Presets, versions, history, copy/paste/sync settings | ✅ |
|
||||
| Profiles (Color, Neutral, Vivid, Landscape, Portrait, Monochrome — our own looks), presets, versions, history, copy/paste/sync settings | ✅ |
|
||||
| Control channel + every widget addressable | ✅ |
|
||||
| RAW: DNG, CR2 | ✅ · NEF, ARW, CR3, RAF, ORF, RW2… 🚧 |
|
||||
| Detail (sharpening ✅, noise reduction 🚧), Optics, Geometry/Upright | 🚧 |
|
||||
| Remove / Heal / Clone, Red Eye | 🚧 (spots are recorded; rendering lands in M8) |
|
||||
| Export dialog, MCP server, CLI, GPU pipeline, web build | 🚧 |
|
||||
| RAW: DNG, CR2, ARW, NEF (uncompressed) | ✅ · compressed NEF, CR3, RAF, ORF, RW2, PEF… 🚧 |
|
||||
| Detail: sharpening, luminance + colour noise reduction | ✅ · AI Denoise, Super Resolution ⬜ |
|
||||
| Remove / Heal / Clone spots (auto source) | ✅ · content-aware fill (PatchMatch), Red Eye 🚧 |
|
||||
| Export: JPEG / PNG / TIFF / WebP / AVIF, sizing, file-size limit, output sharpening, naming, batch | ✅ · metadata policy, watermark, DNG ⬜ |
|
||||
| MCP server, CLI, control channel | ✅ |
|
||||
| Optics, Geometry/Upright, GPU pipeline, web build, persistent library | 🚧 |
|
||||
|
||||
<br>
|
||||
|
||||
@@ -224,6 +237,7 @@ git clone https://github.com/storytold/lightcraft && cd lightcraft
|
||||
cargo run --release -p lightcraft # opens with a procedurally generated demo library
|
||||
cargo run --release -p lightcraft -- ~/Pictures/trip # or point it at your photos (folders are scanned)
|
||||
cargo run --release -p lightcraft -- --control 7980 # with the automation channel
|
||||
cargo run --release -p lightcraft-cli -- render photo.jpg -o out.jpg --set light.exposure=0.5
|
||||
cargo xtask ci # fmt, clippy, tests, layering, wasm checks
|
||||
```
|
||||
|
||||
@@ -235,7 +249,20 @@ Keyboard: <kbd>G</kbd> grid · <kbd>D</kbd> detail · <kbd>E</kbd> edit · <kbd>
|
||||
|
||||
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.
|
||||
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`.
|
||||
|
||||
## Contributing
|
||||
|
||||
Humans and agents follow the same rules — read [AGENTS.md](AGENTS.md) first. The short version:
|
||||
|
||||
- **Clean-room.** Never read Adobe binaries or GPL raw/photo code (darktable, RawTherapee, LibRaw, rawspeed, dcraw…);
|
||||
work from public specs and black-box observation.
|
||||
- **No Adobe assets, ever** — no icons, screenshots, presets, profiles, LUTs or fonts from Adobe products. Every
|
||||
image, icon and font in the repo is original, public domain, Creative Commons, OFL or permissively licensed, and has
|
||||
an entry in [assets/ATTRIBUTION.md](assets/ATTRIBUTION.md) added in the same commit.
|
||||
- **Pure Rust**, enforced crate layering, everything is a command, and `cargo xtask ci` green before every commit
|
||||
(one task id per commit).
|
||||
|
||||
<br>
|
||||
|
||||
@@ -258,7 +285,7 @@ Clean-room, pure-Rust creative tools from the same workshop — native on macOS,
|
||||
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:
|
||||
Source Sans 3 (SIL OFL). All icons are original. See [assets/ATTRIBUTION.md](assets/ATTRIBUTION.md).
|
||||
Inter (SIL OFL). All icons are original. See [assets/ATTRIBUTION.md](assets/ATTRIBUTION.md).
|
||||
|
||||
LightCraft is an independent project and is not affiliated with or endorsed by Adobe. Licence: MIT OR Apache-2.0.
|
||||
By the artcraft team.
|
||||
|
Before Width: | Height: | Size: 980 KiB After Width: | Height: | Size: 987 KiB |
|
Before Width: | Height: | Size: 427 KiB After Width: | Height: | Size: 434 KiB |
|
Before Width: | Height: | Size: 916 KiB After Width: | Height: | Size: 923 KiB |
|
Before Width: | Height: | Size: 762 KiB After Width: | Height: | Size: 768 KiB |
|
Before Width: | Height: | Size: 601 KiB After Width: | Height: | Size: 610 KiB |
|
Before Width: | Height: | Size: 679 KiB After Width: | Height: | Size: 687 KiB |
|
Before Width: | Height: | Size: 821 KiB After Width: | Height: | Size: 792 KiB |
|
Before Width: | Height: | Size: 630 KiB After Width: | Height: | Size: 637 KiB |
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 750 KiB |
|
Before Width: | Height: | Size: 528 KiB After Width: | Height: | Size: 537 KiB |
|
Before Width: | Height: | Size: 821 KiB After Width: | Height: | Size: 828 KiB |
|
Before Width: | Height: | Size: 361 KiB After Width: | Height: | Size: 370 KiB |
|
Before Width: | Height: | Size: 592 KiB After Width: | Height: | Size: 604 KiB |
|
Before Width: | Height: | Size: 502 KiB After Width: | Height: | Size: 515 KiB |