Skip to content

v2.0.0-preview.4

Choose a tag to compare

@github-actions github-actions released this 26 Jun 12:19
· 13 commits to main since this release
eb945f7

日本語のリリースノートはこちらです。

What's Changed

Windows

macOS

Linux

New Features

  • Added Ctrl+Shift+P command palette for quickly searching and executing commands
  • Added history view with jump-to-step for navigating the undo history
  • Added 2D transform handles on the preview for directly manipulating position, scale, and rotation
  • Added keyboard shortcuts for nudging timeline elements, duplicating clips (Ctrl+D / Alt+drag), and seeking to the next/previous keyframe
  • Added a Go-to-timecode dialog for precise playhead positioning in the player
  • Added onion-skin overlay to the preview player
  • Moved player settings to a dedicated Preview Settings tool tab
  • Added an "Add Adjustment Layer" menu entry to the editor
  • Implemented resolution-independent rendering pipeline — effects and filters now scale correctly at any output resolution (breaking change)
  • Added audio effects:
    • Compressor
    • Limiter (brick-wall peak limiter)
  • Added Flatpak packaging for Linux distribution
  • Expanded telemetry sensitive-data redaction

Improvements & Refactoring

  • Refactored Timeline editing to route through a dedicated editor services layer, improving plugin extensibility (breaking change)
  • Removed many deprecated and dead API surfaces, including the legacy encoder pipeline, obsolete ISample structs, dead Configuration surface, BcTabView/BcTabItem controls, unused byte-LUT chain, ICanvas/INode/GraphicsException, and ProjectService/EditorService/ExtensionProvider singletons — all breaking changes
  • Made IFrameProvider/ISampleProvider implement IDisposable for reliable resource cleanup (breaking change)
  • Removed MediaFoundation DXVA2/audio dead paths and no-op settings (breaking change)
  • Removed the in-process FFmpeg path; collapsed the FFmpegOutOfProcess configuration axis (breaking change)
  • Relocated IPC frame/sample providers to the MIT-licensed Beutl.FFmpegIpc project
  • Multiple performance improvements:
    • Pooled per-sample speed buffers in SpeedNode
    • Reused onion-skin snapshot bitmap during compositing
    • Made FFmpeg codec property editors async and cached
    • Shared FFmpegOptionsCache across editor instances to reduce IPC round-trips
    • Reused the retained buffer for same-frame re-requests in IpcFrameProvider
  • Upgraded ReactiveUI.Avalonia and Dock.Avalonia packages

Bug Fixes

  • File compatibility: Fixed deserialization of legacy 1.x element files missing the $type discriminator
  • Editor:
    • Fixed index out-of-range error when dragging gradient color stops
    • Fixed output profiles being overwritten on restore failure
    • Fixed corrupt config files causing crashes (JSON errors now caught gracefully)
    • Fixed scene failing to open when the view state config was corrupt
    • Fixed partial relocation failures not being reported during project export
    • Fixed history mutation not pausing playback; scene settings are now applied correctly after pause
  • Player / Preview:
    • Fixed transform-handle overlay blocking the UI during playback
    • Fixed onion-skin config being read off the UI thread
  • Audio:
    • Fixed audio resampler not being disposed during FFmpeg encoding cleanup
    • Fixed UseGlobalClock and parent-relative time not being respected in audio animations
    • Fixed silent audio buffer sample count alignment
    • Fixed limiter deque overflow during audio release
    • Fixed integer overflow in audio/media sample-index conversions
    • Fixed waveform thumbnail sample math overflow
    • Multiple audio buffer leak fixes across audio graph nodes
  • FFmpeg / Video:
    • Fixed FFmpeg install dialog not appearing when worker libraries were missing
    • Fixed FFmpeg worker not respecting BEUTL_HOME when locating libraries
    • Fixed IpcFrameProvider returning the wrong frame on non-sequential requests
    • Multiple IpcFrameProvider/IpcSampleProvider reliability fixes (leak guards, size validation, prefetch, EOF clamping)
    • Fixed encode cancellation not being surfaced as OperationCanceledException
    • Fixed FFmpeg seek returning -22 Invalid argument when seeking past EOF
  • Engine / Rendering:
    • Fixed multiple FormattedText resource leaks and use-after-dispose bugs
    • Fixed integer overflow in Animator interpolation
    • Fixed video thumbnail count against degenerate frame sizes
    • Fixed double-dispose in rasterize paths when an operation throws on Dispose
    • Fixed SKColorFilter leak in ParticleRenderNode
  • MediaFoundation (Windows):
    • Fixed resource cleanup and initialization failure handling across MFReader and MFDecoder
    • Fixed frame buffer size overflow
    • Fixed video-only files not opening correctly in AudioVideo mode
  • Stability:
    • Fixed NotificationService crash and UI thread starvation
    • Fixed TimeRange.IsEmpty returning wrong result for zero-duration ranges
    • Fixed thread-safety race in the shutdown/wait path
    • Fixed encoder extension matching to be case-insensitive
    • Fixed keyframe animations being skipped when parent offset was unresolvable
    • Rolled back project state when persistence fails
    • Rolled back failed extension loads in the API layer
    • Hardened Counter<T> against reorder and AddRef TOCTOU races
    • Hardened IpcConnection cancellation handling in the multiplexed path
Changelog
  • ci: add scheduled code review workflow posting to Projects v2 by @yuto-trd in #1766
  • build(deps): bump actions/checkout from 4 to 6 by @dependabot[bot] in #1769
  • feat: Expand telemetry sensitive-data redaction by @yuto-trd in #1770
  • fix: deserialize 1.x Element files missing $type discriminator by @yuto-trd in #1771
  • fix: dispose audio resampler in FFmpeg encoding cleanup by @yuto-trd in #1772
  • feat: Add Ctrl+Shift+P command palette for searchable commands by @yuto-trd in #1776
  • test: Expand unit-test coverage across Core, Engine, Utilities by @yuto-trd in #1778
  • test: Expand unit-test coverage across Core, Graphics, Utilities by @yuto-trd in #1783
  • fix(command-palette): address remaining PR #1776 review comments by @yuto-trd in #1779
  • feat: add history view with jump-to-step by @yuto-trd in #1780
  • fix: dispose SKColorFilter in ParticleRenderNode by @yuto-trd in #1788
  • fix: surface FFmpeg install dialog when worker libraries are missing by @yuto-trd in #1786
  • feat: add Flatpak packaging for Linux distribution by @yuto-trd in #1784
  • feat: route FFmpegWorker logs to host logger by @yuto-trd in #1787
  • fix: prevent NotificationService crash and UI thread starvation by @yuto-trd in #1789
  • build(deps): bump actions/cache from 4 to 5 by @dependabot[bot] in #1790
  • fix: exclude AVFoundation extension from Linux/Windows builds by @yuto-trd in #1795
  • Bump Microsoft.Extensions.ObjectPool from 10.0.7 to 10.0.8 by @dependabot[bot] in #1805
  • Bump Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Logging by @dependabot[bot] in #1803
  • Bump Microsoft.Extensions.Logging.Console from 10.0.7 to 10.0.8 by @dependabot[bot] in #1804
  • Bump Microsoft.Extensions.FileSystemGlobbing from 10.0.7 to 10.0.8 by @dependabot[bot] in #1802
  • Bump Microsoft.Extensions.DependencyModel from 10.0.7 to 10.0.8 by @dependabot[bot] in #1801
  • Bump System.CommandLine from 2.0.7 to 2.0.8 by @dependabot[bot] in #1816
  • Bump NuGet.Protocol and NuGet.Resolver by @dependabot[bot] in #1814
  • Bump Microsoft.Extensions.TimeProvider.Testing from 10.5.0 to 10.6.0 by @dependabot[bot] in #1811
  • Bump NuGet.ProjectModel from 7.3.1 to 7.6.0 by @dependabot[bot] in #1812
  • Bump System.Management from 10.0.7 to 10.0.8 by @dependabot[bot] in #1817
  • fix: avoid ObjectDisposedException on PlayerViewModel dispose by @yuto-trd in #1798
  • fix: prevent index out-of-range when dragging gradient stops by @yuto-trd in #1799
  • fix: protect output profiles from overwrite on restore failure by @yuto-trd in #1809
  • fix: catch JsonException in JsonRestore for corrupt config files (#1807) by @yuto-trd in #1810
  • feat: add debug-only main window capture to MP4 by @yuto-trd in #1796
  • fix: respect UseGlobalClock and parent local time in audio animations by @yuto-trd in #1818
  • ci: register published release assets to beutl-reflect-release API by @yuto-trd in #1819
  • fix: correct TimeRange.IsEmpty for zero duration by @yuto-trd in #1820
  • fix: align silent audio buffer sample count with ceiling by @yuto-trd in #1821
  • fix: prevent crash from async void in EditorHostViewModel by @yuto-trd in #1822
  • fix: harden Counter against reorder and AddRef TOCTOU races by @yuto-trd in #1823
  • feat: Add keyboard nudge shortcuts for timeline elements by @yuto-trd in #1824
  • fix: keep scene openable when view state config is corrupt by @yuto-trd in #1825
  • fix: harden cancellation handling in IpcConnection multiplexed path by @yuto-trd in #1826
  • fix: surface partial relocation failures during project export by @yuto-trd in #1827
  • docs: expand PR template with guidance and Test plan section by @yuto-trd in #1833
  • feat: add clip duplication via Ctrl+D and Alt+drag by @yuto-trd in #1828
  • feat: add 2D transform handles for direct preview manipulation by @yuto-trd in #1782
  • fix: avoid overflow in integer Animator interpolation by @yuto-trd in #1830
  • feat: Add goto timecode for player playhead seeking by @yuto-trd in #1829
  • build(deps): bump actions/github-script from 7 to 9 by @dependabot[bot] in #1835
  • chore: scaffold AI-native development workflow by @yuto-trd in #1837
  • feat: Add next/previous key frame seek commands by @yuto-trd in #1831
  • chore: expand AI workflow scaffolding (per-module anchors, pre-PR skill, statusline, etc.) by @yuto-trd in #1839
  • feat: add Spec-Kit git extension hooks by @yuto-trd in #1840
  • Bump NUnit from 4.6.0 to 4.6.1 by @dependabot[bot] in #1842
  • chore: install .NET SDK in Claude Code on the web sessions by @yuto-trd in #1844
  • fix: localize 3D camera mode tooltips in PlayerView by @yuto-trd in #1847
  • fix: ensure all FFmpeg native resources are disposed when one Dispose throws by @yuto-trd in #1848
  • fix: close TOCTOU race in FFmpegInstallNotifier throttle by @yuto-trd in #1849
  • build(deps): bump dotnet/nbgv from 0.5.1 to 0.5.2 by @dependabot[bot] in #1846
  • Bump coverlet.collector from 10.0.0 to 10.0.1 by @dependabot[bot] in #1836
  • feat: Add onion skin overlay to the preview player by @yuto-trd in #1861
  • docs: improve contributor onboarding and add SECURITY/CODEOWNERS by @yuto-trd in #1860
  • Bump HarfBuzzSharp.NativeAssets.Linux from 8.3.1.3 to 8.3.1.5 by @dependabot[bot] in #1853
  • Bump SkiaSharp.NativeAssets.Linux from 3.119.2 to 3.119.4 by @dependabot[bot] in #1856
  • Bump Microsoft.NET.Test.Sdk from 18.5.1 to 18.6.0 by @dependabot[bot] in #1859
  • Bump Avalonia and Avalonia.Diagnostics by @dependabot[bot] in #1858
  • Bump HarfBuzzSharp, SkiaSharp and SkiaSharp.HarfBuzz by @dependabot[bot] in #1855
  • Bump Avalonia.Themes.Fluent from 11.3.13 to 11.3.17 by @dependabot[bot] in #1866
  • Bump Avalonia.Desktop from 11.3.13 to 11.3.17 by @dependabot[bot] in #1865
  • refactor!: route Timeline editing through Beutl.Editor.Services by @yuto-trd in #1845
  • Upgrade package versions for ReactiveUI.Avalonia and Dock.Avalonia by @yuto-trd in #1869
  • fix: harden Dispatcher timer wait and resource disposal by @yuto-trd in #1870
  • docs: document follow-up task capture in AGENTS.md by @yuto-trd in #1871
  • perf(engine): pool per-sample speed buffer in SpeedNode.ProcessAnimatedSpeed by @yuto-trd in #1872
  • docs(ai-workflow): add beutl-ai-review-task skill by @yuto-trd in #1873
  • feat: migrate player settings to a Preview Settings tool tab by @yuto-trd in #1875
  • refactor(engine): consolidate Delay parameter constants into DelayParameters by @yuto-trd in #1876
  • refactor(engine): unify DelayNode/GainNode animation guard to Animation != null by @yuto-trd in #1877
  • feat: Add audio Compressor effect by @yuto-trd in #1724
  • fix(core): roll back project state when persist fails by @yuto-trd in #1878
  • docs: shorten recently added code comments by @yuto-trd in #1879
  • Bump Microsoft.Extensions.DependencyModel from 10.0.8 to 10.0.9 by @dependabot[bot] in #1882
  • Bump Microsoft.Extensions.FileSystemGlobbing from 10.0.8 to 10.0.9 by @dependabot[bot] in #1883
  • Bump Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Logging by @dependabot[bot] in #1884
  • Bump Microsoft.Extensions.Logging.Console from 10.0.8 to 10.0.9 by @dependabot[bot] in #1885
  • Bump OpenTelemetry and OpenTelemetry.Exporter.Console by @dependabot[bot] in #1891
  • Bump Microsoft.Windows.CsWin32 from 0.3.275 to 0.3.287 by @dependabot[bot] in #1889
  • Bump Microsoft.Extensions.ObjectPool from 10.0.8 to 10.0.9 by @dependabot[bot] in #1887
  • Bump Microsoft.Extensions.TimeProvider.Testing from 10.6.0 to 10.7.0 by @dependabot[bot] in #1888
  • fix: Phase 0 verified-bug fixes from refactoring audit by @yuto-trd in #1892
  • fix(engine): dispose consumed AudioBuffer in audio graph nodes by @yuto-trd in #1893
  • chore: remove tests/KeySplineEditor leftover prototype app by @yuto-trd in #1895
  • chore: remove unused PackageReferences and dead PackageVersion pins by @yuto-trd in #1896
  • refactor!: remove unused BcTabView/BcTabItem control cluster from Beutl.Controls by @yuto-trd in #1898
  • refactor: remove dead observable/endpoint machinery and the no-op startup guard by @yuto-trd in #1899
  • refactor!: remove three unused ISample structs by @yuto-trd in #1906
  • refactor!: drop dead Beutl.Core/Configuration surface by @yuto-trd in #1901
  • refactor!: remove dead FFmpegIpc protocol surface (QueryDefaultCodec, EncodeProgress, Handshake) by @yuto-trd in #1908
  • refactor!: remove legacy encoder pipeline and obsolete Page/Layer extensions by @yuto-trd in #1905
  • refactor!: collapse cross-type TypeConverter matrices to string-only converters by @yuto-trd in #1907
  • refactor!: drop assorted dead Engine surface by @yuto-trd in #1904
  • refactor: remove unreachable legacy (non-ring-buffer) ReadVideo path from FFmpegWorker by @yuto-trd in #1900
  • refactor!: remove [Obsolete] byte-LUT chain by @yuto-trd in #1902
  • fix(encoding): surface encode cancellation as OperationCanceledException by @yuto-trd in #1894
  • fix: prevent IpcFrameProvider from returning wrong frame on non-sequential requests by @yuto-trd in #1912
  • fix(threading): make _running volatile and cover the Shutdown/Wait race by @yuto-trd in #1911
  • docs: multi-agent audit playbook + refactoring-plan Phase 1/3 corrections by @yuto-trd in #1913
  • feat: add 'Add Adjustment Layer' menu (refactor ElementDescription to EngineObjectFactory) by @yuto-trd in #1880
  • fix(extensibility): compare encoder extensions case-insensitively in IsSupported by @yuto-trd in #1918
  • refactor: drop unreachable NotoSansJP UI weights, stale AVF dylibs, and orphan icon by @yuto-trd in #1897
  • refactor: remove in-process FFmpeg path, collapse FFmpegOutOfProcess axis, relocate GPL sources by @yuto-trd in #1909
  • refactor!: remove dead StringHash and BaseUriHelper helpers by @yuto-trd in #1920
  • refactor!: make GainNode.Gain a required non-null property by @yuto-trd in #1921
  • fix(engine): dispose child AudioBuffer consumed by SpeedProcessor.Read by @yuto-trd in #1919
  • refactor: strip dead null-guards from DelayNode body by @yuto-trd in #1923
  • refactor: remove stale InternalsVisibleTo for deleted Beutl.PackageTools CLI by @yuto-trd in #1922
  • fix(test): gamma-encode linear HDR pixels to sRGB in Graphics3DTests debug PNGs by @yuto-trd in #1924
  • refactor(core): extract fragile legacy type-name literals into LegacyTypeNames constants by @yuto-trd in #1925
  • refactor: remove unused ReactiveUI.Avalonia references from WaitingDialog and PackageTools.UI by @yuto-trd in #1927
  • fix(worker): respect BEUTL_HOME when locating FFmpeg libraries by @yuto-trd in #1929
  • fix(worker): stop prefetch before disposing ReaderState in DecodingHandler.Dispose by @yuto-trd in #1928
  • fix: skip keyframe animations with unresolvable parent offset by @yuto-trd in #1926
  • refactor(editor): extract keyframe-seek logic to KeyFrameNavigationHelper and add tests by @yuto-trd in #1930
  • Bump OpenTelemetry.Exporter.OpenTelemetryProtocol from 1.15.3 to 1.16.0 by @dependabot[bot] in #1915
  • Bump Microsoft.Windows.CsWin32 from 0.3.287 to 0.3.296 by @dependabot[bot] in #1914
  • Bump System.CommandLine from 2.0.8 to 2.0.9 by @dependabot[bot] in #1917
  • feat!: resolution-independent rendering pipeline (003) by @yuto-trd in #1886
  • test(editor): cover KeyFrameNavigationHelper NodeGraph member path by @yuto-trd in #1932
  • fix(hooks): pin and checksum-verify dotnet-install.sh before executing by @yuto-trd in #1933
  • refactor!: remove dead public graphics surface (ICanvas, INode, GraphicsException, FpsText/DrawFps) by @yuto-trd in #1903
  • Bump System.Management from 10.0.8 to 10.0.9 by @dependabot[bot] in #1941
  • test(rendering): cover FR-036 escape hatch through FilterEffect.Resource.Push by @yuto-trd in #1943
  • refactor(ffmpeg-ipc): relocate IPC frame/sample providers to MIT Beutl.FFmpegIpc + add seek/cancel tests by @yuto-trd in #1934
  • fix(editor): read onion-skin config on the UI thread in PlayerViewModel.OnSceneEdited by @yuto-trd in #1935
  • fix(app): replace window-capture stop busy-spin with a single-flight async gate by @yuto-trd in #1931
  • fix!: address 003 resolution-independent rendering review follow-ups by @yuto-trd in #1937
  • test: deflake Counter ParallelTryAddRefRace race-window guard by @yuto-trd in #1947
  • perf(engine): hoist loop-invariant rowFill out of AudioSpectrogramDrawable cell loop by @yuto-trd in #1939
  • perf(ffmpeg): make the three codec property editors async + cached by @yuto-trd in #1936
  • feat: Add audio Limiter (brick-wall peak limiter) effect by @yuto-trd in #1725
  • perf(player): reuse one snapshot bitmap for onion-skin compositing by @yuto-trd in #1944
  • Bump Microsoft.Windows.CsWin32 from 0.3.296 to 0.3.298 by @dependabot[bot] in #1945
  • Bump Refit from 10.2.0 to 11.2.0 by @dependabot[bot] in #1946
  • chore(deps): bump actions/checkout from 6 to 7 by @dependabot[bot] in #1948
  • fix(engine): sanitize degenerate maxWorkingScale on public surface by @yuto-trd in #1942
  • fix(player): stop transform-handle overlay from blocking the UI during playback by @yuto-trd in #1949
  • refactor!: remove MediaFoundation DXVA2/audio dead paths and no-op settings by @yuto-trd in #1910
  • refactor!: remove RenderNodeCache LastAccessedTime by @yuto-trd in #1951
  • fix: guard limiter deque overflow in release by @yuto-trd in #1953
  • fix(player): dispose CancellationTokenSource in BufferedPlayer.WaitRender/WaitTimer by @yuto-trd in #1950
  • fix(audio): dispose output buffer on failure across all audio nodes by @yuto-trd in #1952
  • fix(engine): avoid double-dispose in RasterizeAndConcat and RasterizeAt when an op throws on Dispose by @yuto-trd in #1954
  • cleanup(player): remove dead DrawFrame() by @yuto-trd in #1959
  • build: drop blanket dual-TFM default, hoist MSBuild blocks, unify coverlet (Phase 2) by @yuto-trd in #1955
  • fix(engine): guard audio/media sample-index conversions against Int32 overflow by @yuto-trd in #1960
  • test: consolidate Beutl.UnitTests scaffolding, modernize assertions, unblock Editor.Components (Phase 2) by @yuto-trd in #1956
  • fix: bound dotnet session-start hook operations by @yuto-trd in #1962
  • fix(engine): guard waveform thumbnail sample math overflow by @yuto-trd in #1965
  • chore: add hook that flags newly added comments for review by @yuto-trd in #1971
  • docs: document shader uniform migration by @yuto-trd in #1963
  • refactor(editor): extract encoder settings JSON handling by @yuto-trd in #1969
  • docs: fix Graphics3D NUnit test routing across guidance docs by @yuto-trd in #1968
  • perf(ffmpeg): share FFmpegOptionsCache across editor instances to dedupe worker IPC by @yuto-trd in #1961
  • test(nodegraph): cover NodeGraphFilterEffectRenderNode scale forwarding by @yuto-trd in #1967
  • refactor: move interactive previewers/sample out of tests/, invert ArtifactProvider opt-in (Phase 2) by @yuto-trd in #1957
  • test(engine): cover SpeedIntegrator long-timeline sample index by @yuto-trd in #1980
  • fix(mediafoundation): compile sideload timestamp utilities by @yuto-trd in #1972
  • fix(engine): preserve rasterize cleanup exceptions by @yuto-trd in #1970
  • fix(editor): pause playback before history mutations by @yuto-trd in #1966
  • test: make Beutl.Graphics3DTests and SourceGeneratorTest real NUnit suites (Phase 2) by @yuto-trd in #1958
  • fix(engine): guard op-dispose loops against leaking remaining ops on throw by @yuto-trd in #1973
  • fix(editor): apply latest scene settings after pause by @yuto-trd in #1977
  • fix(engine): deterministically dispose FormattedText Skia handles by @yuto-trd in #1974
  • fix(ffmpeg): avoid -22 Invalid argument on seek past EOF by @yuto-trd in #1985
  • fix(engine): guard video thumbnail count against degenerate frame size by @yuto-trd in #1978
  • fix(player): prevent BufferedPlayer timer dispose hang by @yuto-trd in #1981
  • Bump Microsoft.NET.Test.Sdk from 18.6.0 to 18.7.0 by @dependabot[bot] in #1986
  • fix(mediafoundation): guard frame buffer size overflow by @yuto-trd in #1976
  • fix(mediafoundation): dispose MFReader resources on init failure by @yuto-trd in #1964
  • fix(api): roll back failed extension loads by @yuto-trd in #1979
  • fix(mediafoundation): dispose MFDecoder on init failure by @yuto-trd in #1987
  • fix(ci): select x64 debian release asset by @yuto-trd in #1975
  • test(rendering): assert LayerRenderNode emits Unbounded EffectiveScale by @yuto-trd in #1989
  • test(rendering): cover non-origin DestRect and ImageBrush fill density by @yuto-trd in #1993
  • fix(mediafoundation): open video-only files in AudioVideo mode by @yuto-trd in #1991
  • docs: Harden branch naming and auto-register follow-ups in AI-review skill by @yuto-trd in #1996
  • docs: Forbid deferring tasks instead of capturing follow-ups by @yuto-trd in #2001
  • fix(engine): dispose truncated FormattedText glyph resources on shrink by @yuto-trd in #1990
  • refactor(ffmpeg): extract codec-editor query/apply decisions for unit tests by @yuto-trd in #1994
  • fix(engine): rebuild cached glyph geometry path on FormattedText slot reuse by @yuto-trd in #1995
  • perf(ffmpeg-ipc): reuse retained buffer for same-frame re-requests in IpcFrameProvider by @yuto-trd in #1988
  • fix(engine): preserve rasterize output and exceptions when RenderTarget disposal throws by @yuto-trd in #1992
  • fix(engine): throw ObjectDisposedException from FormattedText measuring members after Dispose by @yuto-trd in #1999
  • fix(editor): harden HistoryMutationPlaybackGuard.Dispose and SceneSettings Apply feedback by @yuto-trd in #2002
  • build(deps): bump actions/cache from 5 to 6 by @dependabot[bot] in #2003
  • fix(ffmpeg-ipc): harden IpcFrameProvider/IpcSampleProvider (leak guard, size validation, prefetch, EOF clamp) by @yuto-trd in #2012
  • refactor!: make IFrameProvider/ISampleProvider IDisposable and guard IPC providers post-dispose by @yuto-trd in #2013
  • refactor(ffmpeg): extract seek/prefetch decisions as pure predicates + tests by @yuto-trd in #2014
  • test(ffmpeg-ipc): fix Windows hang in IpcConnection multiplexed tests (drain outbound request) by @yuto-trd in #2016
  • docs: clarify Nuke-only publish for the FFmpeg worker; mark matrix collapse done by @yuto-trd in #2015
  • fix(engine): dispose uncommitted scaled text handles in FormattedText.GetScaledTextCache by @yuto-trd in #2000
  • refactor!: remove ProjectService/EditorService/ExtensionProvider singletons by @yuto-trd in #1982
  • test: introduce headless E2E test suites (domain, controls, shell) by @yuto-trd in #2017
  • feat: add /beutl-loop autonomous board loop (loop engineering) by @yuto-trd in #2018

Full Changelog: v2.0.0-preview.3...v2.0.0-preview.4