139 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 3ac283eee4 Review fixes for the landed batch
- Cryptomatte (#1183): planes shorter than the image read as empty instead of panicking.
- layer.addMarker (#1180): a comp marker no longer replaces one at the same time.
- Desktop (#1005): ignore macOS's -psn_ argument instead of refusing to launch.
- Doc comments put back on their own items (#1153, #1037).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 04:47:52 -04:00
Brandon Thomas f096470dec Merge pull request #1153 from fabian-co/fix/intel-metal-indirect-validation 2026-10-13 04:33:47 -04:00
Brandon Thomas 4574fb62bc Merge pull request #792 from vangel76/gap-object-matte
# Conflicts:
#	crates/ui-egui/src/i18n/ui.rs
#	docs/gaps.md
#	docs/target-app-parity.md
2026-10-13 04:30:49 -04:00
fabian-coandClaude Opus 5.5 41f7736959 macOS: open the window on Intel Metal by skipping indirect-call validation
wgpu validates indirect draw and dispatch arguments with a compute shader it
compiles when the device is created. Metal on an Intel Iris Pro (MacBookPro11,3,
macOS 12.7.6) fails to compile it ("Compiler encountered an internal error" in
MTLCompilerService), the device is lost, and the window never opens.

EffectCraft draws and dispatches nothing indirectly, so leave the check out of the
instance flags. WGPU_VALIDATION_INDIRECT_CALL=1 turns it back on. VectorCraft
does the same (storytold/vectorcraft#651).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-12 17:45:45 -05:00
vangel76andClaude Sonnet 5.5 925760c9c8 Web disk cache: handle the Matte kind (mattes/ folder)
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-12 19:08:21 +02:00
RealtaNuaandClaude Opus 5.5 649ba2e8cf Desktop: an unknown option or a bad --control port stops the launch (#997)
The desktop app imported any argument it didn't know as a file (writing it to Recent Footage)
and dropped a missing or non-numeric --control value, starting without a control server.
parse_args now returns an error for an unknown option, a --control value that isn't a port from
1 to 65535, or a bad EFFECTCRAFT_CONTROL_PORT (checked only when --control isn't given); main
prints it and exits with status 1 before anything starts. --control=<port> works, and -- ends
the options so a file named -x can still be opened.

Tests: parse_args unit tests, and tests/args.rs runs the binary with its own settings folder
and checks the exit, the message and that nothing was written.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-12 17:40:15 +07:00
Brandon Thomas 6ace9f7b0e Merge pull request #923 from itrycodinganditsbad/rotating-log
Desktop: write log records to standard error and a rotating log file
2026-10-12 04:20:56 -04:00
Fabio LussiandClaude Opus 5.5 16d9d7d30b Desktop: write log records to standard error and a rotating log file
A launch from the Dock, the Start menu or a launcher has no terminal, and
without RUST_LOG nothing reached standard error anyway, so start-up and
GPU warnings were lost unless Help > Enable Logging was already on.

The logger now writes EffectCraft's info records and everyone's warnings
to standard error and to Logs/effectcraft.log in the settings folder.
Each launch keeps the previous two runs' logs; the file is capped at
16 MiB. RUST_LOG still overrides the filter. Help > Reveal Logging File
shows this run's log unless Enable Logging is on.

Ported from storytold/pdfcraft#239.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 22:37:27 +02:00
pravdomilandClaude Opus 5.5 04e087ae58 Window: remember the window's size and position between launches
The window opened at a fixed 1680 × 1020 wherever the system put it. Its size, position
and maximized state are now saved to window.json in the config directory (when they change,
and on exit) and restored on the next launch, moved onto a monitor that is still connected.
The first launch fits the window to its screen. Agent-driven runs (--control) restore the
saved window but don't overwrite it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-11 15:54:29 +02:00
skylar taylor-barrick 83ae6218ef UI.9: retain shared docking across upstream workspace changes 2026-10-10 19:25:49 -06:00
ClaudeandDennis M. Francis cb37c2511c App: a lost graphics device tells the user why the window closes and where the recovery copy is (#591)
Ported from #673: a native error dialog names the auto-saved recovery copy before the window
closes; agent runs through the control channel skip it. The UI calls Hooks::device_lost once.

Co-Authored-By: Dennis M. Francis <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 23:36:52 +00:00
skylar taylor-barrick 3dba472943 UI.9: share docking transactions and preserve viewer lifecycle
Preserve legacy selection repair, modifier routing, viewer lifecycle and workspace persistence through the shared docking integration. Qualify the complete workspace gate by refreshing the 18 stale Audio Spectrum hashes for the existing linear renderer, with an independent synthetic-tone regression.
2026-10-10 17:14:12 -06:00
Claude 8fb4281632 MCP: --automation-read-root / --automation-write-root confine the agent's file access (#500)
`effectcraft-cli mcp` had no way to keep an agent's file access to a folder;
the flags were unknown options. Both now take a folder (repeatable, as in
PhotoCraft): with either given, files are read only under a read or write root
and written only under a write root (none: no writes). Defaults are unchanged.

automation::confine::Confinement checks every engine command the backend runs
(execute_command, command_run, open/save_project, each engine.batch step), in
both headless and bridge mode, before it runs: the file parameters of the
commands that read or write files must be absolute paths inside the roots
(symbolic links resolved through the longest existing ancestor, `..` refused),
as must any other absolute path in a command's parameters. Commands that write
where they aren't told are checked against the target they would write: Save /
Increment and Save the open project's file, renderQueue.render every queued
output (renderQueue.list). Scripts, Execute File, Reveal in Finder, Open Recent
by index, `$N` file-path references in a batch, render_frame/screenshot paths
outside a write root and the bridge's UI-driving tools are refused while
confined. docs/mcp.md describes it.

Test: a confined headless server opens and saves inside its roots and is refused
outside them, for a relative path, `..`, a batch step, a `$N` path, Save to a
read-only root's project, the Render Queue's default output there, a symbolic
link out of the write root, and scripts; the unconfined server still writes
anywhere.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 22:54:57 +00:00
Claude aaf23aa5f8 macOS: File menu dialogs open as sheets, so a drag over the window can't abort the app (#511)
The file dialogs were blocking rfd::FileDialog calls made inside eframe's frame,
that is inside winit's event handler. On macOS the dialog runs a nested modal
event loop there; a file dragged over the window while it was open reached
winit's handler again, which refuses re-entry with a panic across the
Objective-C boundary, aborting the app (Import with Cmd+I, then a drag).

Hooks gains file_dialog_async: a host that sets it shows a command's file dialog
(Import, Open, Save As, Save Frame As, presets, guides, templates, Collect Files,
Relink...) without blocking, and the command runs with the answer on a later
frame (menus::dialog_answered, drained at the start of each frame); a cancelled
dialog runs nothing. The macOS app implements it with rfd::AsyncFileDialog, a
sheet on the window answered when it closes, outside the frame. Other platforms
keep the blocking dialogs (winit queues their re-entrant events), as do the few
panel buttons that pick a file in place (Settings paths, shortcut import/export,
effect file pickers).

Test: with a non-blocking hook, Save As and Save Frame As return at once without
the blocking dialog, the save happens when the answer arrives from another
thread, and a cancelled dialog writes nothing. The macOS sheet itself needs a
manual check (Cmd+I, drag a file over the window, pick or cancel).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 22:54:56 +00:00
Claude ff56c5ad24 Audio: the short preview buffer is Linux-only and within the device's range (#614 follow-up)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 18:50:32 +00:00
Claude a3cc4d04b0 Merge pull request #614 from vbasky/fix/554-linux-audio-preview 2026-10-10 18:49:52 +00:00
Vikram Bhaskaran 139ff9a4e3 Start Linux audio preview after the first mixed samples, on a short device buffer.
Pulse and PipeWire were opening a large default period and playing silence until the feeder caught up, so the picture ran while the sound started late. The stream now waits for queued samples and requests about 10 ms of buffering.
2026-10-11 03:50:22 +11:00
Claude 4de3354806 Merge pull request #589 from JeremyYao/fix/amd-vulkan-launch-guard
The two test-only conflicts keep main's versions, which already carry the
same fixes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 16:29:06 +00:00
Jeremy YaoandClaude Fable 5.1 2a404f6226 MCP: the auto-save recovery tests look for the JSON-quoted path
automation autosave_is_durable_before_reply_and_queries_do_not_rotate
and the CLI's mcp_autosave_survives_kill_and_restart_without_touching_
desktop_settings asserted that the initialize instructions contain the
previous session's auto-save path as raw text. The instructions embed
the auto-save info as JSON, so on Windows the path's backslashes are
escaped and the raw match can never succeed (both failed on every
Windows run; the server's reply is right). They now look for the path
as serde_json prints it, which also matches on Linux and macOS.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-10 09:37:00 -04:00
Jeremy YaoandClaude Fable 5.1 d86c4aff52 Startup: a launch that stops as its window is shown switches the next to OpenGL
On an ASUS G513QY (Radeon RX 6800M, Adrenalin 26.9.2, Windows 11) every
launch died with STATUS_ACCESS_VIOLATION inside amdvlk64.dll, on a
driver worker thread, a moment after the first frame: eframe shows the
window it created hidden, the resulting resize re-creates the swapchain,
and the driver crashes there (same offset on two driver versions, with
the OBS/Steam/Epic Vulkan layers disabled, and with FIFO, immediate and
latency-1 presentation). DirectX 12 and OpenGL open the window fine.

A crash in a driver can't be caught, and the launch guard (#243) removed
its marker at the first frame, so this looked like a successful launch
every time and Window Graphics never switched. The marker now stays
until the window has kept drawing for SETTLE (3 s) or the app quits
normally before that; frame_drawn returns the time left and the app
asks for a repaint then, so an idle window settles too. The notice,
the Settings note and docs/preferences.md describe the new rule.

Verified on that machine with a scratch settings folder: launch 1
(Vulkan) crashed and left the marker, launch 2 switched to OpenGL with
the notice and closed with exit code 0, launch 3 stayed on OpenGL
without the notice.

Tests: effectcraft launch_guard
a_launch_that_stops_after_its_first_frame_switches_the_next_to_opengl
(a first frame then drop: the next launch gets GL and the notice; a
normal quit in that time leaves no marker), and the existing test now
asserts that the first frames don't settle a launch (marker present at
SETTLE/2, gone at SETTLE).

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-10 09:36:59 -04:00
Claude 00e9e37c0a UI: the drop hint and drop errors go through the interface catalog; the Wayland notice points to the README (#447 follow-up)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 12:55:10 +00:00
Claude 63acbb1eb0 Merge pull request #447 from David-T-Campos/fix/footage-drag-drop
# Conflicts:
#	apps/effectcraft/src/main.rs
2026-10-10 12:54:44 +00:00
Claude ce743af717 Appearance: zbus follows eframe's version instead of an exact pin (#519 follow-up)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 12:54:31 +00:00
Claude d8c1711f52 Merge pull request #519 from luniiya/feat/system-appearance 2026-10-10 12:53:19 +00:00
Claude 8c2b464a4d Merge pull request #582 from LloydNicholson/macos-project-documents 2026-10-10 12:51:16 +00:00
Claude 681919fe92 Merge pull request #478 from mjohnson7cd/fix-webm-bitrate-440 2026-10-10 12:51:16 +00:00
Claude b7b47a0e10 Merge pull request #443 from Aavirash/fix/shape-drag-preview
# Conflicts:
#	crates/ui-egui/src/frames.rs
#	crates/ui-egui/src/panels/viewer.rs
2026-10-10 12:50:43 +00:00
Claude 0df89c84ec Merge pull request #579 from KattKnight/windows-test-fixes 2026-10-10 12:49:56 +00:00
Claude a12242c806 Format the merged community fixes (#561-#566 follow-up)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QiAJeFttZp83Fh7YuzAR5f
2026-10-10 12:49:52 +00:00
Claude f27c834196 Merge pull request #451 from sanyamsingh001/fix/cli-template-rendering 2026-10-10 12:49:17 +00:00
lloydandClaude Opus 5.5 f041aa7782 macOS: projects open from Finder; .pcraft is PhotoCraft's again
The app bundle exported ai.storyteller.effectcraft.document with the
`.pcraft` extension, PhotoCraft's document format. Installing EffectCraft
took `.pcraft` over, and since EffectCraft declared no document types,
neither app was offered for PhotoCraft documents in Finder. EffectCraft's
own projects (.ecproj, .ecprojx) had no file type at all.

- Info.plist: the exported type now tags .ecproj and .ecprojx ("EffectCraft
  Project", conforming to public.data and public.content rather than
  public.image), and CFBundleDocumentTypes makes EffectCraft their owner.
- Finder double-click, Open With, Dock drops and `open -a EffectCraft
  x.ecproj` send a kAEOpenDocuments Apple event that winit 0.30 doesn't
  handle. Register it with the audited fmv-macos-events crate that
  PhotoCraft and PdfCraft use (it keeps the unsafe Objective-C interop out
  of this workspace). Opened paths go through the dropped-file handling, so
  a project opens after the unsaved-changes prompt and media is imported. A
  quit event closes the window.
- The event that launches the app arrives before the UI draws: the first
  frames skip the panels until the fonts are installed, which dropped it.
  The paths wait for EffectcraftApp::is_ready().

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 14:22:22 +02:00
KattandClaude Opus 5.5 a650e6c21d Tests: four failures on Windows (autosave paths, GPU viewer adapter, audio preview race)
- automation / cli autosave restart tests: the MCP instructions embed the
  auto-save state as JSON, so a Windows path's backslashes are escaped there;
  look for the JSON form of the path.
- ui_gpu: egui_kittest prefers a CPU adapter, which on Windows is WARP on
  DirectX 12, where FXC fails to compile the compositor's `pointwise` kernel
  ("compilation aborted unexpectedly"), so the viewer stayed on the CPU and
  the test failed before comparing anything. Build the harness on the adapter
  the headless compositor picked (falling back to egui_kittest's choice).
- ui_audio_scrub (#103 test): with a fixed 2 s comp, a machine with many
  render threads cached the whole preview before the first step, so the sound
  rightly started at once and no silent frame was counted (3 of 24 runs
  failed with 8 copies in parallel). Size the comp to four times the frames
  playback requests per step, so caching takes at least four steps (0 of 24).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-10 16:36:52 +05:30
Aavirash a2554c404c Tests: the CLI render-out test compares canonical temp paths
macOS's /var is a symlink to /private/var: the CLI resolves its working
directory through current_dir(), which is canonical, so the recorded
output path was /private/var/... while the test expected /var/....
Canonicalise the test's temp directory so the comparison holds on macOS.
2026-10-10 12:13:21 +02:00
Nigel Ihza Firdausy da131fcd57 fix(app): open .ecprojx project copies passed on the command line (#528) 2026-10-10 15:51:14 +07:00
Luniiya fe27c375e3 feat: standardise system appearance modes with PhotoCraft 2026-10-10 02:15:26 +02:00
mjohnson7cdandClaude Opus 5.5 c195e6c40b fix: CLI --bitrate now applies to VP9 WebM (#440)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 18:50:13 -04:00
sanyamsingh001andCodex 4751a462dc #332: render Essential Graphics templates from CLI values
Co-authored-by: Codex <[email protected]>
2026-10-10 02:48:06 +10:00
David Campos 95c7cf1f05 ui: import native file drops with drop-target hint (main.rs)
Add Wayland drop notice for unsupported file drops
2026-10-09 20:37:19 +04:00
bflatasticandClaude Opus 5.5 9da33c157e Plug-ins: ScriptUI Panels folder scripts dock as panels and reopen, as in After Effects
EffectCraft's extension points compared with After Effects' (public
user guide and Scripting Guide) are now in docs/plugins.md, which
becomes "Plug-ins and extensions": scripts, ScriptUI panels and effect
plug-ins, with a short guide and an example panel for writing your own.

ScriptUI panels already came from `Scripts/ScriptUI Panels/` in the
settings folder, were listed at the bottom of the Window menu and
docked as tabs. What was missing: After Effects reopens the panels
that were open when it quit. Now the open panels are remembered in
`scriptui_panels.json` in the settings folder (a panel is added when
it opens and dropped when its tab or its script closes it; quitting
leaves the list), and `window.restoreScriptPanels` opens them again;
the desktop and web apps run it at start-up. A panel whose script is
gone or fails is reported and forgotten, and the others still open.
Where a panel was docked isn't kept, as workspace layouts aren't saved
between launches.

Gaps recorded in plugins.md and gaps.md G8: the Startup and Shutdown
script folders, keyboard shortcuts for scripts, ExtendScript's
`#include` / `#target` directives and `.jsxbin`.

Test: open_panels_open_again_at_the_next_launch (fails before: no
restore command), a_panel_dropped_in_the_folder_is_listed_and_opens_as_a_panel
(script), panels_open_at_quit_dock_again_at_launch (UI: the restored
panel docks with its controls; closing the tab forgets it).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 21:03:12 +07:00
bflatasticandClaude Opus 5.5 50c9549529 Import: image sequences with a Sequence option, ranges, folders and missing frames (#297)
Image sequences were found only by the desktop media prober: one picked
numbered still brought its whole run, with no way to import just that
frame, picking every frame made one sequence item per frame, the browser
couldn't make sequences at all, and a gap in the numbering closed up
silently.

The engine now groups numbered stills itself (engine/src/sequence.rs):
one picked file brings its run from its folder, several picked files of
one run import as that range, a picked or dropped folder imports its
files with each run as a sequence, and Force Alphabetical Order takes
every image of that type in the folder by name. `file.import` takes
`sequence` (default on), `alphabetical` and `frameRate`; Replace Footage,
Reload, proxies and render outputs probe the same way. The media layer
probes one file; the browser lists its file table for the run and
registers every frame with its media pool.

File > Import > File... asks, like After Effects' "PNG Sequence"
checkbox, whether picked numbered stills import as a sequence, with
Force Alphabetical Order and the frame rate. Sequences are named
`shot_[0001-0250].png`.

Interpret Footage gains Missing Frames (Show Placeholder, colour bars as
in After Effects, the new default; Hold Previous Frame; Skip) and Start
Frame (the frame number at the footage's first frame: trims or pads the
head). Saved projects keep Skip, so their sequences play as before.

Form notes keep a readable width and the form fits its rows, so OK stays
in view. docs/footage.md explains importing footage and sequences.

Test: tests_sequence (engine: run, picked range, every frame, Sequence
off, folder, alphabetical, Interpret Footage Missing Frames / Start
Frame, Replace Footage and Reload), project sequence unit tests,
sequence_gaps_show_placeholders_hold_or_close_up (media),
import_dialog_offers_the_image_sequence_option and
dropped_frames_import_as_one_sequence_with_sequence_interpretation (UI).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 18:00:07 +07:00
bflatasticandClaude Opus 5.5 be926adb92 Render Queue: output files end in their format's extension once (#293)
Renders on macOS came out as `Comp 1.mov.ecproj`, and an image
sequence's every frame as `Comp 1_00001.png.ecproj`; another output
was `Comp 2.mov.mov`.

Cause: the save dialogs for anything but a project went through the
project dialog hook, which filters to `.ecproj`; macOS's save panel
appends the allowed extension to any other name. 0.4.0's Render Queue
Choose File… used it (#192 moved Output To to its own dialog since),
and Save Frame As, Save Current Preview, Export Lottie, Save a Copy As
XML, Collect Files, Watch Folder and the Premiere export form's Browse
still did. Nothing then fixed the name: Output To kept `.ecproj` (no
format claims it), and changing the format replaced only the last
extension (`Comp 2.mov.ecproj` → `Comp 2.mov.mov`). `[compName]` of a
comp named `Comp 2.mov` also doubled it.

Fix: `Hooks::save_dialog` asks the dialog for the default name's own
extension (`pick_save_file`), the project dialog only for projects or
on hosts without another (the web); the desktop dialog has no filter
for a name without an extension (folders). `OutputFormat::with_extension`
makes an output path end in the format's extension exactly once
(project extensions and repeats of the format's dropped, a missing one
added; `logo.png.mov` kept), used by Output To, format changes and
`resolve_output`, so existing projects and templates render to the
right name too. Output To picks the file type from the extension
before a stray `.ecproj`.

Test: output_names_end_in_the_format_extension_once (project),
output_to_ends_in_the_format_extension_once (engine) and
save_dialogs_offer_the_file_extension (ui); the engine and ui tests
fail with the fix reverted.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 16:51:12 +07:00
Brandon ThomasandClaude Opus 5.5 11848da0a1 App: only a held lock means another launch is starting (#283 follow-up)
A filesystem without lock support returned an error from try_lock, which
read as 'held' and disabled crash detection for good.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 00:04:47 -04:00
Brandon Thomas 5d5da086c8 Merge pull request #283 from prekabreki/fix/launch-guard-concurrent-and-gl-stuck
App: a second copy opening, or OpenGL that fails, no longer strands Window Graphics
2026-10-08 23:51:22 -04:00
Brandon Thomas 6c838325fa Merge pull request #280 from jonassneu/fix/mcp-autosave
MCP: preserve unsaved work across server restarts (#258)

# Conflicts:
#	apps/effectcraft-cli/tests/cli.rs
#	contributors/people.toml
2026-10-08 23:51:21 -04:00
Oldrich333andClaude Sonnet 5.5 a560830b64 CLI: render --out is relative to the working directory (#300)
`effectcraft-cli render --out proj/out/d.mp4 --project proj/x.ecproj` wrote
`proj/proj/out/d.mp4`: the Render Queue resolves a relative output against its own base, while
`--project` and every other CLI path are relative to the working directory. The CLI now makes
`--out` absolute against the working directory before queueing it, so the file lands where the
shell user expects; an absolute path is unchanged, and `rendered[].output` in the JSON result is
the absolute path. Render Queue outputs set inside a project (and `render --queue`) resolve as
before: tokens expanded, then `export.defaultOutputFolder`, the project's folder, the working
directory.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-08 20:32:51 +00:00
prekabrekiandClaude Opus 5.5 384c8cc094 App: a second copy opening, or OpenGL that fails, no longer strands Window Graphics
Two copies opened close together made the second take the first's
launch-pending marker for a crash and switch Window Graphics to OpenGL.
Where OpenGL can't open a window (NVIDIA on X11: "gl not compatible with
provided surface"), every later launch then failed, with no way to reach
the setting.

The marker is now locked while its launch runs, so a locked marker is a
launch still opening, not a crash. And a window that fails to open on
OpenGL puts Window Graphics back to Automatic.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 15:03:19 +02:00
jonassneu 9d9f8ecbb4 Fix #258: preserve unsaved headless MCP work with opt-in checkpoints 2026-10-08 14:38:24 +02:00
bflatasticandClaude Opus 5.5 4eb69e7577 Render: render.backend says why it renders on the CPU; mcp --gpu documented (#262)
get_project / render.backend reported "gpuAcceleration": true with
"active": "cpu" and no reason, which read as a broken GPU. The
headless MCP server only attaches the GPU compositor when started with
--gpu, which docs/agents.md didn't mention, and a failed --gpu said
only "no usable GPU adapter" (the adapter's error went to a log no
one sees). The session now keeps the host's reason there is no GPU
compositor (accel_note): the CLI's "headless: renders on the CPU
unless started with --gpu", or the desktop app's compositor setup or
retirement error. The status reports it as `why` whenever it renders
on the CPU (or that the project's renderer is Software Only). --gpu
failures include the adapter's error (Gpu::try_headless).
docs/agents.md documents `mcp --gpu`.

Test: render_backend_says_why_it_renders_on_the_cpu (engine).
Checked with effectcraft-cli mcp and mcp --gpu.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 18:09:01 +07:00
bflatasticandClaude Opus 5.5 d554724aa4 App: a launch whose window never drew makes the next use OpenGL (#243)
On some older Intel integrated GPUs (UHD 600, UHD with 2020 drivers)
the graphics driver crashes EffectCraft as its window's DirectX 12 or
Vulkan device is created (exit code 0xC0000005): the process
disappears with no message, and only WGPU_BACKEND=gl helped. A driver
crash can't be caught, so each launch now leaves a marker in the
settings folder until its window draws. A launch that finds the
previous one's marker switches the new Settings ▸ Startup & Repair ▸
Window Graphics (Automatic / OpenGL) to OpenGL and says so in the
status bar. A window that fails to open says the next launch will try
OpenGL. WGPU_BACKEND still wins; macOS has no OpenGL backend, so it
never switches there.

Tests: a_launch_that_never_drew_switches_the_next_to_opengl (app),
window_graphics_is_validated (engine). Checked end to end with a
leftover marker: the app opened on OpenGL with the notice and cleared
the marker.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 13:57:21 +07:00
bflatasticandClaude Opus 5.5 468ed0b297 Logging: RUST_LOG prints to stderr, and start-up logs its milestones (#234)
The logger kept warnings in memory and wrote to a file only after Help
▸ Enable Logging, and it ignored RUST_LOG. An app that never opens its
window (macOS 27 on Apple Silicon, #234) therefore left no trace. Now
RUST_LOG (a level, or env_logger-style `target=level` directives)
also prints what it lets through to stderr, including eframe, winit
and wgpu. The desktop app logs its start-up milestones: opening the
window, the graphics adapter, the app created, the first frame drawn,
the window being asked to close, and the window closed.

Test: rust_log_filters_by_level_and_target (engine logging). Checked
by running the app with RUST_LOG=info and quitting it over the control
channel.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 13:32:16 +07:00