Commit Graph
1228 Commits
Author SHA1 Message Date
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
b07b7fab55 perf(seam): the shrink proxy drops its original-column map, same pixels (−15 % at 24 MP) (#8526)
* perf(seam): drop the original-column map from the shrink proxy, same pixels (-15 % at 24 MP)

Content-Aware Scale's proxy seam search tracked each panel column's original
column in an idx map, one usize per proxy pixel, shifted by every seam. The
original column is x plus the number of columns already taken at or left of it,
so a per-row list of the taken columns answers the same question without a
buffer the size of the energy map.

The recorded P28 budget number predates the proxies: the 2026-10-05 baseline
commit carves at full height and recomputes energy per seam, and measures
266 s for the 24 MP case on the machine this was timed on, against 2.6 s now.
Documented in docs/seam-carving-performance.md; enforce stays off until a
budgeted-class run can vouch for the whole row.

* review: generate exactly ch samples per pixel in bench_seam, reject ch > 4

The fixture flattened four samples per pixel and then truncated to w*h*ch, so a
three-channel run grouped samples across pixel boundaries and any ch above four
built a buffer shorter than the rows carve_width indexes.

Generate ch samples inside the per-pixel closure and refuse ch outside 1..=4.
The three-channel row is dropped from the perf note rather than re-measured
here: it moved inside the timer noise either way, and the other agents' builds
on this machine make a fresh number worthless. The four-channel hashes are
unchanged, which is the check that this edit touched only the fixture.

* perf(seam): find the removed column by binary search, not a linear scan

Recording a seam recovered each removed original column by scanning the row's
list of already-taken columns, so a deep shrink paid a comparison per removed
column on every row and every seam: quadratic in the seam count, and worse than
the index map this PR replaced once a shrink got deep enough.

`o - i` never decreases along the row's sorted list, so that count is a binary
search, and the original column belongs where the search stopped; the rows are
independent and update in parallel, like the pixel shift. What is left per
removed column is one insert.

Output is unchanged: same columns, same order, same hashes (10 % and 50 % width
cases below), and `counted_removed_columns_match_the_tracked_map` now runs a
tracking and a counting carver side by side to one column and compares every
row's list after every seam.

docs/seam-carving-performance.md gains those cases, states that the ~104x
figure is the two example runs rather than the baseline row, and names
perf/baseline.json as the source of the 954 s.

---------

Co-authored-by: ebosido444-ai <ebosido444-ai@users.noreply.github.com>
2026-10-24 11:14:00 -04:00
AyanandGitHub 47d9266fa1 Make Crystallize 4x and Pointillize 3x faster on 24 MP layers (#6200)
* Speed up Crystallize and Pointillize with cell-space rasterization

* Measure pixelate commands on unlocked layers and Background separately

* Record pixel-exact 24 MP filter and command benchmarks
2026-10-24 11:13:03 -04:00
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
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 9c5a7b907a Merge remote-tracking branch 'origin/main' into integration-batch-7
# Conflicts:
#	crates/ui-egui/src/i18n/tr.tsv
#	docs/ui-parity.md
2026-10-24 00:34:11 +02: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
2b83be6c81 Levels, Curves and the other adjustments: ⌥ plus the shortcut opens the dialog at its last settings (#8900) (#8969)
* Levels, Curves and the other adjustments: ⌥ plus the shortcut opens the dialog at its last settings (#8900)

* Image › Adjustments: ⌥ while choosing an item opens it at its last settings (#8900)

* Tests: the ⌥-click test picks the Image menu's Adjustments row, not the panel tab (#8900)

* Image › Adjustments: an item opened with ⌥ lands in Edit › Search's recents too (#8900)

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-23 17:55:18 -04:00
JGFandGitHub 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
Gert Pellin - GPEandGitHub 10a20743ea Soft Light: dark backdrops follow Photoshop's W3C curve (#8804) (#8817)
* fix(blend): Soft Light uses the W3C curve over dark backdrops (#8804)

Photoshop's Soft Light moves the backdrop towards D(cb) in the upper half,
and D(cb) is the cubic ((16·cb − 12)·cb + 4)·cb below a quarter, not
sqrt(cb). With sqrt the Soft Light cell of psd-tools rgb-blend-modes.psd
was up to 20 levels too light over the dark rainbow; with the cubic it is
within 4 of Photoshop's merged image.

Same change in compose.wgsl so the GPU compositor stays at CPU parity.
Krita's own soft_light (the sqrt curve) now opens as the approximation and
svg:soft-light / krita:soft_light_svg as the exact match, without warning.

Fixes #8804

* compose: the see-through Soft Light test expects the W3C curve over a dark backdrop (#8804)

The #6232 test computed Photoshop's Soft Light of yellow as sqrt(b) for red and
green. Its backdrop #04170F is below a quarter in both channels, where the W3C
curve (Photoshop's, measured in #8804) uses ((16b - 12)b + 4)b instead.
2026-10-23 17:39:40 -04:00
41599c591c Crop default mode: moving the image under the box snaps (#8580) (#8622)
* Crop default mode: moving the image under the box snaps (#8580)

In the default (non-Classic) crop mode a drag inside the box moves the
image under it, but snapping was switched off for that drag, so content
couldn't be centred in a larger box without leaving for the Move tool.

The drag now snaps like a Classic Mode frame move: the frame moves by the
image's travel the other way over the document, its edges and centre snap
to the document, layers, guides and grid (smart guides when those are
empty), and the pointer is corrected in the press camera, as crop_ui reads
the drag. A turned box still doesn't snap.

Fixes #8580

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Crop image move: smart guides snap when no Snap To target is in reach (#8622 review)

The document's bounds keep the regular targets non-empty, so the smart
guides were never tried: with View › Snap To › Layers off, the box never
snapped to a layer while the image moved under it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Khawar Zamman Wani <wanikhawar@Khawars-MacBook-Air.local>
2026-10-23 17:39:02 -04:00
aiongg 7aaa59712a Merge main into integration-batch-7 2026-10-23 20:37:05 +00:00
aiongg 4b51647955 Merge remote-tracking branch 'upstream/main' into xtask-ci-gate
# Conflicts:
#	xtask/src/main.rs
2026-10-23 19:44:29 +00:00
aionggandGitHub 1ecb61db42 Merge pull request #8964 from aiongg/translation-gaps-pass
Tests: missing translations don't fail; xtask ci lists them
2026-10-23 15:43:33 -04:00
aiongg a75a414310 CI: cargo xtask ci is the gate, and the workflow runs it 2026-10-23 19:29:31 +00:00
aiongg c3aa3f9e51 Tests: missing translations don't fail; xtask ci prints them
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.
2026-10-23 19:07:23 +00:00
aiongg 9acf9a0cf9 CI: the Linux gate runs through the suite's shared gate workflow 2026-10-23 18:32:21 +00:00
aionggandGitHub cf0960b520 Merge pull request #8915 from aiongg/ci-speed-2
CI: no debug info for dependencies, nextest in xtask ci, long sweeps spread over days
2026-10-23 13:48:36 -04:00
aiongg 20ad9f1f4e Docs: the final check before a PR runs the full sweep 2026-10-23 16:40:24 +00:00
aiongg b87cfb3c6a Tests: spread the two longest sweeps over the days
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.
2026-10-23 07:20:54 +00:00
aiongg 175c9c1e75 xtask: test with nextest, doctests separately, one wasm check call
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.
2026-10-23 06:00:38 +00:00
Khawar Zamman WaniandClaude Opus 5.5 4970534e05 feat(engine): Select and Mask tool edits as select.refineEdge params
select.refineEdge takes `edits`: the Select and Mask workspace's Quick
Selection, Brush, Lasso, Object Selection, Select Subject, Clear Selection
and Invert, applied in order to the starting selection (or layer mask)
before the edge is refined. Cancel discards them, OK is one history step,
and agents drive them over MCP and the control channel.

- engine/select_mask_edits.rs: parse (bounded, every bad field an Err)
  and a pure apply/apply_one the workspace preview can share
- algo matting::brush_region: soft round brush coverage (hardness)
- ATN export reports steps with edits instead of dropping them
- "Edits" label in the 21 catalogs

Part of #7069 and #8148 (the workspace UI follows in a second PR).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 10:30:46 +05:30
David MannandClaude Opus 5.5 72bafe9d25 Address CodeRabbit review: Type checklist counts match the scorecard (#6230)
The Features row said Type 5 / 4 / 1 and "RTL paragraph direction UI
missing"; scorecard/type.toml has 5 done / 5 partial / 0 missing, as the
status line says, and TYPE-218-2 is partial: the direction buttons exist,
the visual RTL caret is missing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 00:28:19 +02: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 1efa06b715 Integration: merge main (c36e46c38 #8680, #8668, #6705)
# Conflicts:
#	docs/ui-parity.md
2026-10-22 23:47:54 +02:00
David Mann ca73fb4724 Merge PR #6966: perf(canvas): skip occluded checker on CPU textures 2026-10-22 23:40:20 +02:00
David Mann 7ecac105c2 Merge PR #8556: perf(oil-paint): drop the libm floor/round calls from the LIC gathers, same pixels (1.23x) 2026-10-22 23:40:19 +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 8d23a06eae Merge PR #6094: Fix legacy PSD point-text placement after font resolution 2026-10-22 23:40:19 +02:00
David Mann c436f61d53 Merge PR #7202: fix(atn): import a recorded Save As with its destination (#7102) 2026-10-22 23:40:18 +02:00
David Mann 3fdcabded4 Merge PR #5248: Keep adjustment clipping visible in compact Properties panels 2026-10-22 23:40:15 +02:00
David Mann 49a98690ad Merge PR #8354: Keep the CPU canvas sharp at 100% zoom 2026-10-22 23:40:14 +02:00
David Mann 14d68f972b Merge PR #8035: CLI: reject ignored or conflicting mcp/serve launch options 2026-10-22 23:40:13 +02:00
David Mann 837242536b Merge PR #7840: gpu, docs: fix timing test skip guard and document Windows ARM64 build on RTX Spark 2026-10-22 23:40:12 +02:00
David MannandClaude Opus 5.5 494cdb236a Integration: batch tests join the io test binary, regenerate the scorecard
Main's #8644 builds each crate's integration tests as one binary; #3356's
cmyk_export.rs and #5769's cylinder_warp.rs move into crates/io/tests/it.
docs/scorecard.md regenerated for the batch (#5485 DIST-220-1, #6055
UI-217-17, preferences).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:40:12 +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 Mann c6e628afad Integration: stack #5815 (its merge onto main, conflicts resolved) 2026-10-22 23:40:10 +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 cab3ef6191 Merge PR #5815: perf(doc): share the XMP packet, Duotone PSD data and unsupported adjustment bytes between snapshots
- crates/engine/src/tests.rs: kept both tests (main's restore_layer_selection test and the PR's history_states_share_large_document_payloads).
- crates/io/src/psd_import.rs: kept main's parsed Duotone inks (duotone_map) with the PR's Arc<[u8]> psd_raw; also main's unknown-adjustment-key import (#6575) now builds Arc<[u8]> raw.
- crates/io/tests/adjust_warnings.rs: moved to tests/it/adjust_warnings.rs on main; PR's .into() edits applied there, plus #6322's Color Lookup test (raw.as_slice().into()).
- docs/architecture.md: union; status line names both changes, both revision-history rows kept.
- Adapted main-new sites to the PR's types: psd_export.rs (Duotone write-back via as_deref/to_vec, Unsupported block compare by slice), inspect.rs and ui-egui unsupported_marker_tests.rs (raw .into()), io tests/it/psd_unknown_adjustment.rs (slice compare).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 23:38:56 +02:00
0ec95fa266 View › Extras (Cmd+H) hides the Move tool's transform controls (#6699) (#6705)
As in Photoshop, the Move tool's Show Transform Controls box and handles are an Extra: hiding
Extras hides them, and their handles stop responding (no hover cursor, a press doesn't start Free
Transform). Cmd+H again brings them back. Show Transform Controls and the layer are unchanged.

Fixes #6699

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 17:38:53 -04: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
249eae743f Integration: make Oil Paint's round_i32 exact for every f32 (#8556)
round_i32 added 0.5 in f32, which rounds up at the binade crossing:
0.49999997 (0.5 - 2^-25) + 0.5 becomes 1.0, so round_i32 gave 1 (and -1 for
the negative) where f32::round gives 0. The sum is now taken in f64, where
it is exact for every f32 the i32 cast does not saturate; still no roundf call.

rounding_matches_the_standard_library now covers +-0.49999997, the ties and
8388607.5, and a new test compares every f32 bit pattern in [-4096, 4096]
against f32::round (0.6 s). Both fail on the previous head. The code comment
and docs/oil-paint-performance.md no longer claim the f32 sum is exact.

Co-authored-by: ebosido444-ai <316167330+ebosido444-ai@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:31:24 +02:00
David Mann 1e3323f64c Integration: merge main (#6966) 2026-10-22 21:28:41 +02:00
David MannandClaude Opus 5.5 018d3605b1 Integration: merge main (#6094)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 21:13:36 +02:00