Merged with our fix-up d5139d177 (pr-1199-fixup), which merged main as of 8f09d122d.
Conflicts with main since then and with batch 8:
- photocraft-cli: main split the CLI into clap modules (#7071); the model wiring
(local_headless, configure_cli_models, batch's shared backend, droplet) is re-applied there.
- Cargo.lock regenerated: crates/ml pins ureq =3.4.2, so the app's ureq goes 3.5.0 -> 3.4.2.
- cutout_cmds: main's subject area (#8235) kept for the classical path beside the model path.
- file_cmds batch: main's per-input closure takes `s` later, so the backend and
integrations prefs are read before the closure instead of inside it.
- prefs_ui: model-choice filter with #4573's pref_choice_label; Integrations stays visible
(#4097) with the model choices only where models run; the translation-coverage test main
deleted (c3aa3f9e5) stays deleted; old section_fields test calls take PreferenceFieldOptions.
- Semantic clashes git did not flag: #4097's Integrations test literals in
apps/photocraft take ..Default::default() for the new model fields; main's and #4573's
section_fields test calls pass PreferenceFieldOptions.
- engine lib.rs, prefs.rs, smartselect tests, snapshot example, jobs_ui_tests, people.toml,
docs and i18n catalogs merged as unions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/file-format-parity.md: main's PSD row with the round-trip count
258/258. docs/scorecard.md: regenerated with `cargo xtask scorecard`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Say which packages install them and how to generate and install them
by hand from a checkout. The desktop app has neither.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Say that `photocraft --help` lists the flags and their variables, that
a flag wins and an empty variable is unset, and what is a usage error;
that a bad --present-mode or --frame-latency is one while a bad
variable is still ignored; list PHOTOCRAFT_IN_WINDOW_MENUS; and that a
token with a token file is a usage error for the control server too.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Say that PHOTOCRAFT_CONTROL_PORT is the fallback for serve --port and
mcp --bridge (with the stderr notice and the empty-is-unset escape),
and list the CLI's variables on the book's CLI page, which also says
the automation root variables stay the desktop app's.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Delete the coverage tests, the per-language parity checks and the tests
of one language's exact wording. Catalog integrity, placeholder and
plural-form checks stay, as do the engine tests (locale resolution,
plural rules, fallback, language scoping, drawing in a language); those
compare against tr() or the plural rule rather than catalog wording.
Docs describe the report instead of a failing test.
swept_blocks_match_the_pixel_search skips the cases where the colour mode reaches extrude only
through a channel count and ink setting an earlier mode already covered. It and
damaged_layer_data_opens_flattened run a quarter of their cases per run, a different quarter each
UTC day (photocraft-testkit's Sweep). PHOTOCRAFT_FULL_SWEEP=1 runs every case, and
PHOTOCRAFT_SWEEP_PART=<n> replays the part a failing run printed.
cargo xtask test and the ci test step run cargo nextest over libs, bins and tests when nextest is
installed (cargo test otherwise, with a notice), then cargo test --doc. The wasm check is one
cargo check with --keep-going over the wasm-safe crates, plus one call per optional web feature.
Clippy runs with --keep-going.
- gpu: the test modules share one GPU_LOCK, and timing and vector_mask
take it too, so one process drives one wgpu device at a time.
- ui-egui: the wgpu tests in pattern_preview_canvas, adjust_preview_gpu,
marquee_autoscroll and layout_perf take gpu_lock().
- affinity compound_limits: the child process selects its test by the
module path (compound_limits::<name>); with --exact, the bare name
matches no test and the child passes without running the check.
- xtask scorecard reads crates/io/tests/it/corpus.rs.
- Docs and comments name the new test paths and the --test it filters.
- Preferences > Integrations: default and web builds showed the section
with two single-option "Classical" dropdowns, "Local models aren't
available in this build" and disabled Download buttons; main hides it
(#204). The model choices are now hidden where no model can run
(prefs::LOCAL_ML_ONLY), and main's hidden-section test is back.
- A model choice saved by a local-ml build (the preferences file is
shared) made every Select Subject, Object Selection box and Remove
Background fail in a default build, with no control left to switch
back. There it now means Classical; local-ml builds stay strict, and
an explicit "model" param still fails.
- models.download / models.remove: the automation gate let a control or
MCP agent start about 1.8 GB of downloads or delete installed models
outside its workspace. Both are now refused like other ambient file
effects; models.list stays allowed.
- Select Subject / Object Selection with a model run as jobs, so "No
subject found" / "found nothing there" never showed. The job result
now gets the same message as the classical path, including the
Object Selection options bar's "try a rectangle" hint.
- local-models.yml pins its third-party actions by SHA, as ci.yml does.
- docs/development.md: Windows local-ml builds fail to link ONNX Runtime
1.28's prebuilt with MSVC 14.42 (unresolved __std_search_1 etc.), and
Linux ones need glibc 2.38 / GCC 13 (Ubuntu 22.04 fails with
__isoc23_strtol).
Tests that fail without the fix: model_cmds
a_model_saved_by_a_local_ml_build_means_classical_in_a_build_without_models,
prefs_ui unimplemented_preferences_are_hidden_from_the_dialog, workspace
local_model_downloads_and_removals_are_not_automation_commands, jobs_ui
a_model_selection_that_finds_nothing_says_so_like_the_classical_one.
Co-authored-by: mighty-programmer <83077551+mighty-programmer@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main moved about 2100 commits since the branch's last merge. Resolved:
- smartselect_cmds.rs: main's empty-layer check for Object Selection
(check_sampled_pixels, #5246) now runs before the SAM branch, which
returned before it in a plain merge.
- cutout_cmds.rs: the classical path keeps main's cancellable stage;
the BiRefNet path is unchanged.
- prefs_ui.rs: main split section_fields into field_visible/field_rows;
the model labels, the filtered model choices and the options struct
move into that structure.
- apps: main's trusted_local() CLI session, Linux print spooler and frame
cap kept beside the local-model setup.
- channel_view.rs: main's version (#4915); the branch's change there was
unrelated to local models.
- i18n, people.toml, SOURCES.md, architecture.md, gaps.md: both sides.
Cargo.lock and docs/scorecard.md from main, then regenerated.
Co-authored-by: mighty-programmer <83077551+mighty-programmer@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crates/format/src/store.rs: kept both field sets in PcraftWriter::default (main's blob_hash_cache/compressed_budget and the PR's lock_wait) and both setters (set_compressed_cache_budget, set_lock_wait).
PhotoCraft reads GIMP's .xcf (and .xcf.gz) files, read only, through a new
reader in photocraft-io written from the public XCF specification: versions
0 to 26, uncompressed, RLE and zlib tiles, 8/16/32-bit integer and
16/32/64-bit float precisions (linear precisions get a linear profile),
pixel layers at any position, groups by item path with pass-through,
layer masks applied or disabled, opacity, visibility, locks, colour tags,
the 2.10 and legacy blend modes mapped to Photoshop's (modes without an
equivalent open as Normal with a note), the ICC profile, resolution,
guides, the comment, extra channels and the saved selection; indexed
images open as RGB. Text, vector and link layers open as their pixels;
layer effects, paths and floating selections are reported.
Fixtures are written by GIMP 3.2 itself (scripts/xcf_fixtures.py), each
with GIMP's merged rendering as a PNG. In gamma-encoded blend and
composite spaces our composite matches GIMP within 0.5/255; GIMP's
linear-light default, its Clip to backdrop and its clamp-after-alpha
for unbounded modes are documented and measured in docs/xcf.md.
layer.smartObjects.replaceContents takes an ambient path and is refused in
serve/mcp. Add the capability-scoped sibling of doc.place: the file is read
beneath --automation-read-root and handed to the command's own core, as an
RPC method (doc.replaceSmartObject) and an MCP tool (doc_replace_smart_object).
Conflict in apps/photocraft/src/main.rs: main added
`app.perf.gpu_info.set_available(&rs.available_adapters)` where this branch
installs the texel guard; both are kept (set_available first, then
texel_guard::install).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>