chore: sync upstream (1205 Commits) #14
No reviewers
Labels
No labels
herkunft/alpha-feedback
status
blockiert
status
zu-testen
typ
bug
typ
docs
typ
enhancement
typ
feature
typ
idea
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
iris/effectcraft!14
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "chore/sync-upstream-20261030"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Upstream-Sync von
upstream/main(1205 Commits). Fast-Forward.0555b526Merge pull request #2668 from nanox333/codex/gradient-stroke-widtha16f37d8Merge pull request #2667 from storytold/land/2663d242bab1Merge pull request #701 from vbasky/fix/687-adjustment-footprint-key3a8ff240Merge pull request #2669 from storytold/fix/ui-egui-tests-one-binaryace7d563Merge pull request #1287 from vbasky/fix/1218-wheel-scrubf0b5e4ee#2668: cover mixed strokes and stretched layer timing18ab2e3fMerge pull request #2664 from zitann2020/ui/2589-unselected-self-drop4ced49aaMerge remote-tracking branch 'origin/main' into HEAD697556f2ui-egui: the accessibility and keyboard tests join the one test binary0ea9867fMerge remote-tracking branch 'origin/main' into HEADe9ca27e5Merge remote-tracking branch 'origin/main' into HEAD742a085fMerge remote-tracking branch 'origin/main' into HEAD1f15f8a5Merge pull request #2665 from storytold/docs/gaps-ci-gatec6858118Merge remote-tracking branch 'origin/main' into HEAD36c8d8a7UPD.1: honor app pretend versions in update checks (#2663)Pro Levels2 keeps its Alpha controls one group down, under Alpha, and a script's effect.property("Alpha Input White") only searched the effect's direct children, so it returned null. The lookup now searches the groups nested below the direct children, up to three levels, after the direct match fails. Direct children keep their priority. A regression test checks the name on the effect and the same control through the Alpha group. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>addProperty("ADBE Text Tracking Amount") returned the first property added to the animator, which is the Tracking Type companion, so the script changed the wrong value. The engine now reports the requested property's position in the Properties group, and the script returns that property. An animator's Properties group also finds its properties by their After Effects names, such as ADBE Text Tracking Amount, which the name table already had in the other direction. A regression test checks the property returned, its value, and the lookup by name. Not covered: the Advanced and Wiggly selector children and the Expression amount, which still keep their own names. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>In After Effects, holding Alt while dropping the expression pick whip refers to an effect's property by its index, effect("Color Control")(1), instead of its name, ("Color"). prop.pickWhip takes byIndex: the effect keeps its name and each property inside it is selected by its one-based place among its group's children (nested groups too), which is what an expression's (1) reads. Other properties, dimensions ([1]), insertion at the cursor and match names (Compact English off) are as before. An index still reads a renamed property, but another one if properties are reordered. Tests: pick_whip_by_index_selects_effect_properties_by_their_index (engine, the references); effectcraft-host pick_whip (by index and by name read the same values, nested and per dimension)."N minutes ago" and "N hours ago" have rows in all seven catalogs; a Japanese interface read `保存日時:… {m} minutes ago`. Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>terminate:aff4b082d7Review follow-up to the panel/dialog step: the composition-settings tabs translate "Basic" and "Advanced" through `tr(variable)` and the Preview transport translates "Play/Stop", but none of the three had a catalog row, so they stayed English. Add them to the Japanese, Simplified and Traditional Chinese catalogs and pin them in `japanese_rows_translate_the_panels`. The shared "Type" key means "kind" in the Project column and the Camera Settings dialog, so the Chinese rows read 类型/類型 instead of 文字 ("text"). Keep the graph button bar's automation labels English: translate only the drawn label and tooltip, and translate the stored English strings when the hidden-button menu draws them. Recount the docs from the catalogs: 628 menu rows, 996 Japanese and 998 Chinese panel rows; count Simplified Chinese's 306 effect names in its numerator (46%) and average the ten After Effects languages the table actually names (21%, not the stale 27%). Update the measurement basis, the cross-references in gaps.md and target-app-parity.md, and ROADMAP.File ▸ Scripts gets a Recent Script Files submenu with the ten scripts run last, newest first: script files run with Run Script File… or a command, and the installed and bundled scripts of File ▸ Scripts. ScriptUI panels are not listed. The list is kept in the settings. Each entry runs its script again through `file.runScript {"recent": i}`, and Cmd+Alt+Shift+D runs the most recent one; the key can be changed in Edit ▸ Keyboard Shortcuts. An entry records whether it ran a file or an installed script, so a file named like a bundled script runs again as that file.A subfolder of a Scripts folder can be a link to another folder (an extension's own checkout). `file.uninstallScript {"name": "Motion Kit/Animate.jsx"}` then deleted Animate.jsx in that folder, outside the settings folder. Uninstall now refuses `Folder/File.jsx` names and removes only scripts at the top of the Scripts folders, where Install puts them; listing and running through a linked folder still work. Regression test: uninstall_never_deletes_through_a_linked_subfolder (failed before the fix). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>Edit ▸ Keyboard Shortcuts now lists the scripts File ▸ Scripts lists, under File ▸ Scripts, and a key given to one runs it as its menu entry does. The key is bound to the script's file name (file.runScript {"name": ...}) and is saved with the preset. File ▸ Scripts and the macOS menu show it. The shortcut table lists the Scripts folder again when a script is installed or uninstalled, when the editor opens and when shortcuts.list runs. shortcuts.set and shortcuts.reset look a script up in File ▸ Scripts' list as it is now, and a script it doesn't list is an error instead of a key for Run Script File....Layer > Create > Create 3D Layer Instance, as After Effects (public docs): 3D model layers take no masks or effects, so the command puts a comp-sized solid at the top of the layer stack with CC Composite referencing the selected model, and switches the model off (back on to keep its shadow) - a 2D copy of its render, through the comp's camera, that 2D effects can be applied to. - CC Composite (ec.channel.cccomposite) gains an optional Layer parameter: with a layer chosen it takes the original's place; In Front replaces the solid's pixels, alpha included, the other Composite Original modes blend with them. The GPU compositor runs such an instance on the CPU. - FxHost serves a referenced model or primitive layer as After Effects does - the layer rendered on its own through the comp's camera (Renderer::solo_3d); the owner keeps no cache entry for it (it moves with the camera and lights, without a trace in its own properties). - layer.create {op: instance3d} skips layers that are not 3D model or primitive layers (the ones that take no effects); one undo step, the copy selected, the model's video off. Tests: tests_instance3d.rs (behaviour, pixels, undo/redo, serde, 2D effects on the copy), a CC Composite layer-parameter unit test; docs/effects.md regenerated (3033 parameters)."შემოუერთდით ArtCraft-ის Discord-ს" ran past the right edge of the fixed-width Discord button at the foot of the Home sidebar (v0.17.0, macOS). "შემოგვიერთდით Discord-ზე" ("Join us on Discord") fits; the Help menu item keeps its full wording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>terminate:e04ec3da1a29612588into integration/bugfix-effectcraft-bugfix 07eef0a175Conflicts: crates/ui-egui/src/menus.rs (upstream split it into menus/{bar,commands,entries,frontend,invoke,shortcuts,tests}.rs) and panels/settings.rs (ComboBox is now craft_ui::ComboBox). - menus.rs: took upstream's slim module; re-applied the branch's two hunks in the new locations: nudge() now also skips Effects & Presets and Render Queue (menus/invoke.rs), and Enter is left to those panels in handle_shortcuts (menus/shortcuts.rs). - panels/settings.rs: kept the branch's accessibility lines (shown_name, value_text) on top of craft_ui::ComboBox. The accessibility audit BASELINE still matches the measured findings. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>In After Effects a layer is a property group: thisLayer("transform"), thisComp.layer("Other")("effects")("Blur"), thisLayer(1). In EffectCraft's expression runtime a Layer was a plain object, so those failed with "TypeError: not a callable function", including the references the pick whip writes with Compact English off (thisComp.layer("Other")("effects")("ec.noise.fractal")(...)). A Layer is now callable like a property group (built as __mkGroup builds groups), looking up its own properties by match name, name or index, and keeps its methods, name and index. The places that took a layer for a plain object (the result reading as the layer's index, thisComp.layer(layer, offset), a Layer Control's value handed through the property proxy) accept it. Test: layers_are_callable_property_groups (fails before).EffectCraft writes its own templates as `media/<item id>/<file>` entries, and extraction trusted both halves. `base_name` splits on `/` and `\`, but the item id was taken with `split('/')` alone, and it is pasted in front of a base name another item already used. So a second `media/..\..\..\Startup\x/clip.mp4` entry became `<dir>/..\..\..\Startup\x-clip.mp4`, which on Windows is three folders up, with the attacker choosing how the name ends. The id is now used only when it is one, and the name goes through `safe_file_name`: separators, drive colons and NUL become `_`, and `.` / `..` become `footage`. Reached from `templates.create` with `path`, from File ▸ New from Template, and from a template dropped in the user Templates folder. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>`Prefs::set` makes a JSON pointer of the key (`key.replace('.', "/")`), so `scripting/allowScriptsWriteFiles` resolves as well as the dotted spelling, and the page on its own (`{key: "scripting", value: {…}}`) replaces every setting on it — `coerce` takes an object for an object, and the page deserializes with `serde(default)`. A prefix check on `scripting.` let both through. The page is now read from the key's first segment, split on either separator. Found by CodeRabbit on the pull request; reproduced before fixing, with `prefs.set {key: "scripting/allowScriptsWriteFiles", value: true}` answering `{"scripting/allowScriptsWriteFiles": true}` under confinement. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>`render.preRender` takes an Output Module template where a path goes, and the confinement skips the path check for one. That made `given` true, so the new lookup was skipped — and the template's own output is relative, so it resolved exactly like an output the agent never gave: `render.preRender {output: "Lossless"}` on an unsaved project queued `~/Movies/Lossless.mov` and `~/Movies/Lossless_RenderLog.txt`. The lookup now asks whether a *file* was named, so a template name takes the same route as no output at all. Found by CodeRabbit on the pull request. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>`file.createProxy` and `renderQueue.add` read a single string (`str_p`), so `{path: ["…/a.mov"]}` leaves them on their default while the confinement saw a path it could check and let the queue go ahead: on an unsaved project that was `~/Movies/A_proxy.mov` again. Only a plain string now counts as an output the agent named. Found by CodeRabbit on the pull request, which reported it fixed by9cc23209; it was not, and the case is in the test now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>effect.cryptomatteAt rendered the effect's input on every call to learn its pixel grid (up to ~1 s per hover on a 3D precomp). The aux channels and that grid are now kept in a CryptoProbe on the Session, keyed by the project revision, layer, effect, frame, scale and render prefs (nested switches, draft shadows). On footage with nothing animated before the Cryptomatte effect the frame is the source frame, so a still or a held frame keeps one probe for every comp time. The effect's own Selection doesn't count: the probe never reads it, so an animated Selection keeps the probe too. Session::crypto_probe_ready says whether a query answers from the kept probe and changes nothing. Session::crypto_probe_job builds it on another thread for the viewer; asking for a job is starting it. Each started job has a generation: it stores its result only while it is the newest, a newer job or an edit cancels it, and a panic in the build becomes the probe's error. A cancelled build checks its generation between its stages (reading the IDs, rendering the effect's input), so it stops early and lets go of what it read. `probeOnly` makes cryptomatteAt / pickCryptomatte answer {pending} instead of building on the caller. A pick re-keys the probe (it only edits the Selection), and undo, redo and history jumps over picks keep it too (each pick is labelled "Pick Cryptomatte"). Any other edit, footage changes, Open / New and Session::drop_crypto_probe (the eyedropper disarmed) let it go. The slot's type is crate-private (the Session field stays public, doc(hidden), so other crates can still build a Session); crypto_probe_stats and crypto_probe_jobs (jobs run, cancelled ones included) are doc(hidden), for tests.Conflict in crates/track/src/camtrack/bundle.rs (imports): upstream replaced the linalg glob import with an explicit list; kept that list and added the branch's SolveError import (use super::{Distortion, SolveError}). Input validation, size budget and Result-returning adjust/cost are unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>terminate:5f560d7075CLI: run --commands reads {"command", "params"} steps from a JSON or JSON Lines file, or standard input (#2251)sequenceimports as itself, as in After Effects (#2018) 6b75033485The encoder's first-frame user_data_unregistered SEI now lists its settings ("... - options: rc=vbr bitrate=10000 ... scenecut=1", 211 bytes where "filmcraft-h264enc 0.1.1 - clean-room H.264 encoder" took 50): +161 bytes. The same build gives (104322, 11051847956767423392), the pin Linux CI took on a base before the 19-byte nclx colr box, when that box is left out, so the bytes match across platforms.Add a muted flag to Keyframe. Muted keys stay in the Timeline and Graph Editor (dimmed, selectable and movable) but evaluation skips them, so the active neighbours interpolate as if they were not there; auto-Bezier and eases use the active neighbours. When every key is muted the property falls back to its static value.\n\nkeys.setMuted {muted} mutes or unmutes the selected keys in one undo step. The Timeline context menu offers Mute/Unmute Keyframes and the Animation menu has Mute Keyframes. Muted keys have no Bezier handles and motion-path points are dimmed.\n\nLottie export omits muted keys (with a warning) because Lottie has no mute state; scripting keeps seeing them in numKeys/key().\n\nTests: keyframe evaluation (linear, auto-Bezier spatial, all muted), serialization and value replacement, engine command + undo, Lottie export.The menu only carried Mute, so unmuting meant the timeline's context menu. Add the second row bound to `keys.setMuted {"muted":false}`, its translation in the ten catalogs, and a test that runs both rows through Session::execute with undo and redo.rc.ras a Lottie property d249f255aeThe equal-radii and zero fallback branches wrote a bare number where the uniform branch (and every other Value field) writes `{a, k}`; external players may reject that form even though our importer reads it. Write `{"a": 0, "k": value}` in both branches and update the export assertions.e6f2cce7d) b13a80b882e6f2cce7d) 50392e46cce6f2cce7d) 98909ec52d"Warn User When Executing Files" said the cursor, not the user, was warned. The other 27 rows give the same English term one Japanese spelling in the menu table and another in the UI table (track/tracking, Region of Interest, Time Remapping, Separate Dimensions, Stabilize Motion, Hold, Brightness, Vector Layer, Small Screen, Straight, Expression and a few more), or read awkwardly ("({}) Selected Objects", "Interpret Unlabeled Alpha As"). Each now follows the spelling the rest of the file already uses. Only Japanese values change; no key or English text does. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K5NRZNWfaSLBWVzV8hivySAbout 94 rows write Latin text and numbers directly against Japanese ("360度", "EffectCraftについて", "メモリとCPU"); 37 rows put a space on one side ("メモリと CPU", "3D レンダラー", "{} 回使用"), and no row mixes the two. The spaced rows now follow the majority. "getartcraft.com の EffectCraft" keeps its spaces so the domain stays readable. Only Japanese values change; no key or English text does. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K5NRZNWfaSLBWVzV8hivySf262e39c6) c1c6e048f4