Commit Graph
219 Commits
Author SHA1 Message Date
David MannandClaude Opus 5.5 33e09e56fe Merge PR #3567: History panel: New Snapshot dialog and the first snapshot (#2966)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 13:37:08 +01:00
David MannandClaude Opus 5.5 8c15e55cbf Integration: merge main, resolve conflicts (#3567)
panels.rs: the PR's snapshot rows next to main's History Brush source
and scroll-to-current; ui-parity.md: main's status line.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 13:36:40 +01:00
fab7d9739e Integration: keep foreign raw sidecars, develop before the workflow conversion (#5128)
Open wrote PhotoCraft's crs: subset over any existing sidecar, on by
default: a Lightroom or Bridge IMG_0001.xmp lost its crop, masks, rating
and keywords, even when the raw was only opened with Open in Camera Raw
off (FredApps' review). Now a sidecar is only written when the settings
changed, never over one whose x:xmptk isn't PhotoCraft's (a notice says
it was kept, camera_raw_xmp::is_photocraft_xmp), and never for a control
or MCP request, which has no authority to write beside the user's files.
A write error goes to a notice instead of a status line the develop
overwrote at once.

The Camera Raw Defaults' colour space, 8-bit and smart-object steps ran
before the Camera Raw step, so with the default Adobe RGB every raw opened
with the dialog's settings applied to other pixels than it previewed. They
now follow the step (also when a background re-develop lands), as
Camera Raw converts to the workflow space last. Main already sets the raw
resolution at import (#7811), so the PR's Image Size step is dropped.

Two raws opened back to back with raw-stage edits: the second one's
background re-develop replaced the first one's pending entry, so the first
never got its Camera Raw step, conversions or unmodified mark. Pending
re-develops are now a list keyed by job. Sidecars are read only from
regular files of at most MAX_XMP_BYTES (a pipe or a huge file named
IMG.xmp no longer blocks or fills memory), and a conversion that fails
after the Camera Raw step is reported instead of leaving the dialog open
for a second Open that would apply the step twice.

Tests: a_foreign_sidecar_is_never_overwritten,
a_rating_only_sidecar_is_left_alone,
opening_without_the_dialog_does_not_rewrite_the_sidecar,
a_control_request_never_writes_the_sidecar,
a_sidecar_write_error_stays_reported,
the_camera_raw_step_runs_before_the_workflow_conversion (inline and
background), two_raws_opened_back_to_back_both_finish_their_open,
sidecars_are_read_from_small_regular_files_only,
is_photocraft_xmp_reads_the_toolkit_marker; the existing
sidecar round trip now uses a PhotoCraft-written fixture.

Co-authored-by: Fabio Lissi <3223836+FabioLissi@users.noreply.github.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 13:03:14 +01:00
David MannandClaude Opus 5.5 028d400454 Integration: merge main, resolve conflicts (#5128)
prefs.rs keeps main's demosaic default and the PR's write_xmp_sidecars, and
unhides the Camera Raw Defaults the PR makes live; the raw-open RawOpen built
without the dialog gains main's developed_with/demosaic; i18n and docs as
unions; docs/scorecard.md is regenerated in the fix-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 12:02:10 +01:00
aiongg c65b5d25d3 Merge pull request #9061 from wanikhawar/wanikhawar/modal-workspaces
fix(ui): Liquify, Content-Aware Fill, Filter Gallery and Adaptive Wide Angle are modal, like Camera Raw
2026-10-24 22:11:26 -04:00
Khawar Zamman Wani 874ff42a9e docs(control): Adaptive Wide Angle is a modal workspace too 2026-10-25 06:49:07 +05:30
IvanandClaude Opus 5.5 e96b5e2b11 docs(app): describe the desktop flags' variables and usage errors (#7071)
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>
2026-10-24 19:45:27 +03:00
IvanandClaude Opus 5.5 23548ee92a fix(cli): check the token pair only where a token is read (#7071)
With the environment fallbacks, clap's conflicts_with on the token pair
made a stale exported PHOTOCRAFT_CONTROL_TOKEN and
PHOTOCRAFT_CONTROL_TOKEN_FILE a usage error for every mcp and serve, though
headless mcp and stdio serve read no token. As on main, the pair is now
refused only by serve on TCP and mcp bridging, still as clap's either/or
usage error naming each half as it was given.

An automation root on the command line with PHOTOCRAFT_CONTROL_PORT set
is a usage error too: the variable would switch mcp to bridging, which
drops the roots, with only a note on stderr.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 19:45:26 +03:00
IvanandClaude Opus 5.5 b4949702e2 docs(cli): describe the mcp and serve environment fallbacks (#7071)
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>
2026-10-24 19:45:26 +03:00
IvanandClaude Opus 5.5 2f13a1564c refactor(cli): share ControlArgs and AutomationArgs, typed --bridge (#7071)
Step 4 of the issue: the control token flags and the automation roots
move to photocraft-automation's new args module as two clap structs,
which mcp and serve flatten and the desktop app can flatten in step 5
without moving them again. clap is a plain dependency of the crate.

- ControlArgs holds --control-token and --control-token-file;
  AutomationArgs holds the roots, and AutomationArgs::workspace opens
  them (replacing the CLI's automation_workspace).
- The port value parser is photocraft_automation::args::control_port,
  with its unit tests, for serve --port and --bridge now and the
  desktop app's --control later. It ignores surrounding spaces and
  refuses anything else with a typed NotAPort.
- --bridge parses to Bridge::Port or Bridge::Addr: it takes a bare
  port, meaning 127.0.0.1:<port>, or any value containing a ':', which
  the bridge client then validates. Anything else is a usage error
  (exit 2) instead of a bridge error.
- 127.0.0.1 addresses are built from Ipv4Addr::LOCALHOST.

mcp_bridge_takes_a_port_or_an_address is new: `--bridge nope` is a
usage error, and `--bridge 1` bridges to 127.0.0.1:1, which a tool
call names when nothing listens there.

No new environment behaviour: the token variables are still read at
run time through security::token_inputs, and the roots stay flag-only.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 19:45:26 +03:00
Khawar Zamman WaniandClaude Opus 5.5 3466d93204 docs(control): workspace continuations wait for dialogs, prompts and blocking crops; cargo fmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:00:39 +05:30
Khawar Zamman WaniandClaude Opus 5.5 e466b9bd53 fix(ui): ui.menu.list greys what the modal gate refuses, like the native menu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 11:12:15 +05:30
Khawar Zamman Wani 4bd6638cc4 fix(ui): Liquify, Content-Aware Fill and Filter Gallery are modal, like Camera Raw
An agent's ui.menu.invoke reached the main window's menus while a full-window workspace was
open: window.document.N switched documents and the workspace closed, dropping its work.
Photoshop makes these dialogs modal.

menus::modal_allows now refuses other menu commands while one is open (distort_ui::
modal_workspace), so ui.menu.invoke and the macOS menu bar wait for OK or Cancel. The
control channel's Camera Raw continuation is generalised: the open workspace's own
{"ui": {...}} requests still pass, unless another dialog, a discard prompt or a crop is
pending. The menus' cache key includes the open workspace, so opening or cancelling one
without input rebuilds them. engine.execute (MCP run_command) is not a menu click and is
not gated.

Puppet Warp, Perspective Warp and Vanishing Point are on-canvas modes here, with the
in-window menus live, so they stay out.
2026-10-24 10:40:51 +05:30
David Mann 2b0deddec2 Merge remote-tracking branch 'origin/main' into integration-batch-7
# Conflicts:
#	crates/ui-egui/src/panels.rs
2026-10-24 00:51:37 +02:00
A Hazy Reign Is FluidandBrandon Thomas 6a36c48670 fix(automation): release idle headless TCP server ports (#3914)
* fix(automation): release idle headless TCP server ports

* fix(automation): retry aborted incoming TCP connections

* test(automation): synchronize idle daemon client acceptance

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-23 18:36:14 -04:00
David Mann 8c04b175ec Merge remote-tracking branch 'origin/main' into integration-batch-7
# Conflicts:
#	crates/automation/src/rpc.rs
#	crates/automation/src/server.rs
#	crates/gpu/src/health.rs
#	crates/text/src/tests.rs
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/panels.rs
#	docs/control-protocol.md
#	docs/ui-parity.md
2026-10-24 00:23:15 +02:00
JGF 35cb32be20 fix(export): report skipped layers in doc_export_layers (#8491) (#8713)
* fix(export): report skipped layers across automation surfaces

* test(export): use the MCP visible_only parameter spelling

* test(export): restore old adapter for hosted regression proof

* Revert "test(export): restore old adapter for hosted regression proof"

This reverts commit 397a5ffa2a.

* docs(export): qualify workspace-only response guarantees
2026-10-23 17:41:19 -04:00
David MannandClaude Opus 5.5 b54ab8ff30 Address CodeRabbit review: bridge-mode doc_replace_smart_object refuses index (#8150)
The bridge forwards Replace Contents to the app, which runs it on its
active document, so a given `index` was silently dropped and could replace
another document's contents. It is now refused before anything reaches the
app, as bridge previews and saves already do; documented in the schema and
control-protocol.md. A fake-app test checks the indexed call never arrives.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 00:25:18 +02:00
David Mann 7c9d6ac344 Merge PR #8150: fix(automation): doc.replaceSmartObject replaces Smart Object contents from the read root (#8061) 2026-10-22 23:40:19 +02:00
David Mann fff01d8918 Integration: stack #7335 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David Mann 9e7b35b716 Integration: stack #6055 (its merge onto main, conflicts resolved) 2026-10-22 23:40:11 +02:00
David MannandClaude Opus 5.5 6c7e920d5a Merge PR #7335: Gradient Overlay: add Method selector and retain editable source stops
- crates/ui-egui/src/layer_style.rs: values_of keeps the PR's method/smoothness keys and source-stop ends, and main's (#7072) unconditional From/To and geometry fields.
- crates/compose/src/cmyk_tests.rs (no textual conflict): add the PR's new `interpolation: None` field to main's CMYK test GradientOverlay literal.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:14 +02:00
David MannandClaude Opus 5.5 945a10dc7c Merge PR #6055: Color panel: Photoshop's panel-menu modes, the same in every theme (#6000)
Conflicts:
- crates/ui-egui/src/i18n/{cs,de,el,es,fr,hu,id,it,ja,ko,nl,pl,pt-br,ru,sr,tr,uk,vi,zh-hans,zh-hant}.tsv: kept every key of both sides (main's block, then the PR's Color panel block); no duplicate keys.
- crates/ui-egui/src/panels.rs: took the PR's removal of color_picker/hsb_sliders/rgb_sliders (moved to color_panel_ui.rs); kept main's color_field_height doc comment; main's #5842 slider recolour tests ported to color_panel_tests.rs for the new HSB/RGB slider modes; main's black-HSB test dropped as the PR's hsb_sliders_take_values_on_black covers it.
- crates/ui-egui/src/color_panel_ui.rs (no textual conflict, adapted): set_color now goes through apply_color::foreground_changed with the gesture (was type_tool::foreground_changed), so every mode (sliders, ramp, alerts, wheel) recolours selected type/shapes tool-gated in one undo step per gesture; panel() calls apply_color::track_focus.
- crates/ui-egui/src/color_panel_tests.rs (adapted): new every_slider_mode_recolours_the_selected_shape test.
- docs/gaps.md, docs/ui-parity.md: union of both sides' status lines, rows and revision history; the PR's done row replaces the old "missing" Color panel row.
- docs/scorecard.md: generated, took b7-base's version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:39:04 +02:00
David MannandClaude Opus 5.5 f56147655d Merge PR #5485: Add opt-out startup release checks and manual update status
Conflicts resolved:
- crates/ui-egui/src/i18n/hu.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/i18n/ru.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/i18n/sr.tsv: kept base's added sections, then the PR's update-check keys
- crates/ui-egui/src/i18n/tr.tsv: kept base's Bevel & Emboss keys, then the PR's update-check keys
- crates/ui-egui/src/menus.rs: kept base's saved-workspace entries, then the PR's Help › Check for Updates reordering
- docs/gaps.md: base status line with the PR's G17 clause prepended; PR revision row above base's rows
- docs/target-app-parity.md: base status line (updated 2026-10-22) with the PR's clause prepended; PR revision row above base's rows
- docs/scorecard.md: generated, took b7-base's version

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:46 +02:00
95c3af68c3 Integration: prove doc.replaceSmartObject replaces and undoes (#8150)
The rpc test only checked the returned layer id, so a no-op that echoed
{"layer": id} passed, its undo check passed on doc.place's own step, and
the bad-layer case asserted on an empty reason. It now checks the smart
object's file name and rendered centre pixel (42 -> 200 after the
replace, back to 42 on undo, 200 on redo), that every refusal changes
nothing, and that layer 999999 fails with "no such layer".

The bridge row in docs/control-protocol.md claimed doc_replace_smart_object
maps onto layer.smartObjects.replaceContents; the desktop refuses that
command (ambient path), like doc_place's file.placeEmbedded. The row now
says so and points to the headless / workspace server method.

Co-authored-by: VishnuByrraju <112673081+VishnuByrraju@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:36:42 +02:00
aiongg 5857afd121 Integration: track t11
# Conflicts:
#	apps/photocraft-cli/src/lib.rs
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	docs/gaps.md
2026-10-22 15:38:31 +00:00
aiongg 446b74a8de Integration: track t07
# Conflicts:
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/uk.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	crates/ui-egui/src/layer_shortcut_tests.rs
2026-10-22 15:38:21 +00:00
aiongg 82cf3c828c Integration: track t01
# Conflicts:
#	crates/ui-egui/src/i18n/cs.tsv
#	crates/ui-egui/src/i18n/de.tsv
#	crates/ui-egui/src/i18n/el.tsv
#	crates/ui-egui/src/i18n/es.tsv
#	crates/ui-egui/src/i18n/fr.tsv
#	crates/ui-egui/src/i18n/hu.tsv
#	crates/ui-egui/src/i18n/id.tsv
#	crates/ui-egui/src/i18n/it.tsv
#	crates/ui-egui/src/i18n/ja.tsv
#	crates/ui-egui/src/i18n/ko.tsv
#	crates/ui-egui/src/i18n/nl.tsv
#	crates/ui-egui/src/i18n/pl.tsv
#	crates/ui-egui/src/i18n/pt-br.tsv
#	crates/ui-egui/src/i18n/ru.tsv
#	crates/ui-egui/src/i18n/sr.tsv
#	crates/ui-egui/src/i18n/tr.tsv
#	crates/ui-egui/src/i18n/vi.tsv
#	crates/ui-egui/src/i18n/zh-hans.tsv
#	crates/ui-egui/src/i18n/zh-hant.tsv
#	docs/file-format-parity.md
#	docs/gaps.md
2026-10-22 15:38:14 +00:00
6f56a4d750 Integration: merge main, resolve conflicts (#5485)
Main moved about 1,860 commits since the PR's last merge. i18n catalogs keep both
sides' rows; control.rs keeps updatesOpen next to main's strokeTrace (39 fields);
Services keeps check_updates next to main's place_inbox; Cargo.lock is main's,
re-resolved for ureq and semver; docs/gaps.md, docs/target-app-parity.md and
docs/scorecard.md are main's (the PR's entries come back in the next commit).

Co-authored-by: ZhuanTou33212 <285931757+ZhuanTou33212@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 16:36:42 +02:00
Khawar Zamman WaniandClaude Opus 5.5 cb56c99fbd Merge main into feat/6000-color-panel-modes
Main's Color panel HSB/RGB slider switch (#7172, #7317) is replaced by this
branch's panel-menu modes, which include RGB Sliders and HSB Sliders; its
control test now sets colorPanel.mode. The panel takes main's shared
photocraft_color HSB conversions and ui.set's f32-range checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 09:34:24 +05:30
Yonghyuk Choi bea003acd8 Rebuild unrecorded Gradient Overlays from their end colours 2026-10-22 12:38:20 +09:00
Yonghyuk Choi dc029b93c5 Merge main into Gradient Overlay method branch 2026-10-22 12:38:20 +09:00
aiongg dfde38919e Merge PR #7883: Save As JPEG: JPEG Options dialog (quality 0–12, Baseline / Optimized / Progressive) (FILE-215-19)
crates/ui-egui/src/lib.rs: replay_save doc comment names both Export As and JPEG; replay_save uses the PR's FormatChoices::from_step, after main's export_dialog::replay branch.
docs/file-format-parity.md: header keeps main's text plus the JPEG Options item (last updated 2026-10-19); TIFF row is main's, JPEG row is the PR's; change-log rows once each, newest first.
docs/gaps.md: header keeps main's text plus the G10 item (last updated 2026-10-19).
2026-10-22 02:27:46 +00:00
aiongg a77b078589 Merge PR #7417: Camera Raw: choose the demosaic method when a raw opens
crates/io/src/lib.rs: kept main's import_psd (and its call in import_stages); import_stages takes the PR's ImportOptions argument.
crates/io/src/raw.rs: the PR's demosaic summary on main's developed_document(name, bytes, ...) call.
docs/scorecard.md: ours (regenerated at combine).
2026-10-22 02:25:41 +00:00
aiongg 48f391e912 Merge PR #6897: GPU fallback: Retry GPU after an error rebuilds the GPU canvas now, no restart (#6577)
crates/ui-egui/src/lib.rs: union in the PhotocraftApp fields, the initialiser and set_wgpu (main's window_device/window_lost/window_recovery_retry and set_available, the PR's gpu_render_state/gpu_fault).
docs/control-protocol.md: ui.gpu.simulateLoss line takes the PR's text and keeps main's destroy: true sentences.
2026-10-22 02:25:08 +00:00
aiongg f271b0e07d Merge PR #7051: Save: ask before replacing a file that an added or lowercased extension names 2026-10-22 02:24:07 +00:00
aiongg b2ae473eab Merge PR #6415: Save for Web: Width, Height, Percent and Resample in Image Size, linked in proportion (#6388) 2026-10-22 02:24:04 +00:00
aiongg c08a6ad9cf Merge PR #5317: Brush Pose: preserve independent Tilt X/Y overrides
crates/paint/src/brush_tests.rs: both sides added tests at the same spot; kept main's four smoothing tests and added the PR's three pose_axes tests after them.
docs/brush-parity.md: kept main's header and added the PR's change item.
docs/gaps.md: kept main's header, added the PR's change item; G4 progress notes and the change-log row kept from both sides.
docs/control-protocol.md: kept main's eyedropper line (with the document.sampleColor wording) and added the PR's Brush Pose line before it.
2026-10-22 02:22:51 +00:00
aiongg 6afb66de55 Merge PR #3775: Control protocol: document.pixel / document.sampleColor reply ranges (#3666)
docs/control-protocol.md: kept main's table rows (document.inspect with snapshots, layer.list) and added the PR's four-floats wording to document.pixel.
2026-10-22 02:21:55 +00:00
aiongg e8c68586c6 Merge PR #5644: Layer Mask Display Options: set the layer mask rubylith's colour and opacity
docs/scorecard.md: kept ours (regenerated at combine).
2026-10-22 02:21:54 +00:00
UnemarsandClaude Opus 5.5 c695493153 Control protocol: the open-time Camera Raw dialog's demosaic choice
openingRaw is {name, path, demosaic}; ui.demosaic is accepted only while a raw
opens; rawDefaults.demosaic is the method the app's raw opens develop with; Open
re-develops when the chosen method differs from the one the open used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:44:44 +02:00
aiongg 94d28535d3 Merge PR #6464: Survive a lost window GPU device: draw nothing, save unsaved work for recovery, close (#3438, #1215) 2026-10-21 18:15:02 +00:00
Higgs32584andClaude Opus 5.5 f916c98536 Merge upstream/main into revive/4330-jpeg-options
Conflicts only in the parity docs: status lines take main's text with the
JPEG Options entry (FILE-215-19) on top; scorecard takes main's rows with
FILE-215-19 done and File compatibility 10 / 12 / 5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:56:32 -04:00
Marco Arnulfo 562601eb47 Save for Web: Width, Height, Percent and Resample in Image Size, linked in proportion (#6388) 2026-10-21 11:40:38 +02:00
VishnuByrraju 6b99ac877c fix(automation): doc.replaceSmartObject replaces Smart Object contents from the read root (#8061)
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).
2026-10-21 11:04:23 +05:30
aiongg 4699d3605c Merge PR #7026: Automation: place and layer/data-set export by index keep the active document (#7025) 2026-10-21 05:04:01 +00:00
Khawar Zamman Wani 7aaed6de0d Merge remote-tracking branch 'origin/main' into feat/6000-color-panel-modes 2026-10-21 10:09:04 +05:30
Higgs32584andClaude Opus 5.5 92d1ff42f9 Merge upstream/main into revive/4330-jpeg-options
Main added DDS saving (#5993): DDS Options, and FormatChoices carrying the
Targa and DDS answers through every save path (this branch's SaveChoices
carried Targa and JPEG). Resolved by keeping main's name and making it
the one struct for all three answers.

- lib.rs: FormatChoices { tga_bits, dds, jpeg } with from_params (strict),
  from_step (lenient JPEG read of a recorded step), apply and record;
  main's separate block is folded in. Both prompts (dds_options and
  jpeg_options) are kept everywhere: save_to asks Targa, then DDS, then
  JPEG Options; save_options_open covers all four. save_in_place takes
  main's (path, choices) signature and records the plain-Save step with
  plain_save_step for JPEG plus the Targa/DDS answers (save_in_place_with
  folded into it). journal_as_plain_save relabels a parked Targa, DDS or
  JPEG prompt and keeps tgaBits/dds*/quality/jpegFormat when dropping the
  path. replay_save reads choices with from_step.
- SAVE_OPTIONS_OPEN names all four prompts; DDS Options uses it too.
- targa_options_ui: main's plain-Save step (no path) through this
  branch's write_answered_save. JPEG Options gets main's Enter-on-a-
  focused-Cancel fix.
- view_cmds Save a Copy asks Targa, DDS, then JPEG Options; write_copy
  takes FormatChoices.
- control.rs: both app.save tests (JPEG and DDS) kept.
- engine file_cmds: SaveOpts keeps jpeg_format and dds; param docs list
  both jpegFormat and ddsCompression/ddsMipmaps. CLI: both --jpeg-format
  and --dds-compression/--dds-mipmaps. codecs re-exports JpegFormat and
  DdsCompression/DdsOptions.
- docs/book: both entries kept (control-protocol app.save lists both).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 20:43:26 -04:00
dotCooCoo eeb4f5cc1e Merge main into fix/save-added-extension-asks-before-replacing 2026-10-20 10:25:03 -07:00
Guillem Hermida 872748fb5b Codecs: save DDS textures, uncompressed or BC1–BC3, with optional mipmaps (#1327) (#5993)
DDS textures can now be saved, not just opened: uncompressed (BGRA, BGRX, L8, A8L8; lossless) or BC1/BC2/BC3 (DXT1/3/5) from a clean-room block encoder, with an optional box-filtered mip chain, in the legacy header. Save As and Save a Copy ask with DDS Options; scripts pass `ddsCompression`/`ddsMipmaps` (file commands, control `app.save`, RPC `doc.save`, MCP `doc_save`/`doc_export`), and the CLI takes `--dds-compression`/`--dds-mipmaps`. Targa and DDS answers travel together as `FormatChoices` through the Save As flow.

Review follow-ups:
- File › Save behind DDS or Targa Options records a plain Save with its answer, and replaying `file.save` applies it (#3531).
- The block encoder finds the principal axis from every channel, so a channel that varies on its own can't hide the others' variation.
- DDS joins the shared round-trip suite; the header is built before the output buffer is allocated.
- Enter on a focused Cancel in DDS, Targa or TIFF Options cancels instead of saving.
2026-10-20 11:02:39 -06:00