From 0f94a1f983833f9a6e4ab5cb0cd4e66f78e4f7b9 Mon Sep 17 00:00:00 2001 From: Valentin Klein Date: Fri, 6 Nov 2026 17:18:52 +0100 Subject: [PATCH] Skip the startup update check when started for an agent (#3097) * Skip the startup update check when started for an agent An app started with --control or EFFECTCRAFT_CONTROL_PORT still checked for updates at start, and the modal "newer version available" prompt blocked agent runs until a person dismissed it. Agent launches already skip crash recovery and the Home screen; now they skip the startup update check too. Help > Check for Updates is unaffected (it goes through updates_ui::check / check_requested, independent of the startup flag). Documents what a control-port launch skips in docs/control-protocol.md and the main.rs module doc, with a unit test for the startup decision. Co-Authored-By: Claude Opus 5.5 * Control protocol docs: a window-start failure still shows a blocking message box Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5.5 --- apps/effectcraft/src/main.rs | 25 +++++++++++++++++++++++-- docs/control-protocol.md | 7 +++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/apps/effectcraft/src/main.rs b/apps/effectcraft/src/main.rs index a70e03fcd..5350addbe 100644 --- a/apps/effectcraft/src/main.rs +++ b/apps/effectcraft/src/main.rs @@ -8,7 +8,9 @@ //! `--demo` opens the demo project instead (also Help ▸ Open Demo Project). //! //! `--control ` (or `EFFECTCRAFT_CONTROL_PORT`) starts a localhost JSON-lines control server; -//! see `effectcraft_ui_egui::control` for the methods. +//! see `effectcraft_ui_egui::control` for the methods. An app started for an agent opens without +//! taking keyboard focus and skips crash recovery, the Home screen (unless `--home`) and the +//! startup update check. #![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)] #![cfg_attr(all(target_os = "windows", not(debug_assertions)), windows_subsystem = "windows")] @@ -112,6 +114,13 @@ fn parse_args(args: impl IntoIterator, env_port: Result) -> bool { + control_port.is_none() +} + /// A control-channel port from 1 to 65535 (0 would listen on a port nobody is told); `name` is /// the flag or variable it came from. fn control_port(name: &str, value: Option<&str>) -> Result { @@ -310,7 +319,7 @@ fn main() -> eframe::Result { // reported in a toast and forgotten). let _ = session.execute("window.restoreScriptPanels", json!({})); let mut app = EffectcraftApp::new(session); - app.set_startup_update_check(true); + app.set_startup_update_check(startup_update_check(control_port)); app.set_gpu_failure_bridge(gpu_failures); app.ui.start_screen = show_home; if let Some(n) = notice { @@ -666,6 +675,18 @@ mod tests { assert_eq!(parse_env(&[], Ok("9000".into())).unwrap().map(|a| a.control_port), Some(Some(9000))); } + /// An app started for an agent (`--control` or `EFFECTCRAFT_CONTROL_PORT`) doesn't check for + /// updates at start, so no modal update prompt blocks the run; a normal launch still does. + #[test] + fn agent_runs_skip_the_startup_update_check() { + let port = |args: &[&str], env| parse_env(args, env).unwrap().unwrap_or_default().control_port; + assert!(super::startup_update_check(port(&[], Err(VarError::NotPresent)))); + assert!(super::startup_update_check(port(&[], Ok(String::new())))); + assert!(!super::startup_update_check(port(&["--control", "9877"], Err(VarError::NotPresent)))); + assert!(!super::startup_update_check(port(&["--control=9877"], Err(VarError::NotPresent)))); + assert!(!super::startup_update_check(port(&[], Ok("9877".into())))); + } + /// A missing, non-numeric or zero `--control` value stops the launch instead of starting /// without a control server, and the argument after `--control` isn't reinterpreted (#997). #[test] diff --git a/docs/control-protocol.md b/docs/control-protocol.md index 93bf2979a..9f3d69ea5 100644 --- a/docs/control-protocol.md +++ b/docs/control-protocol.md @@ -9,6 +9,13 @@ effectcraft --control 9877 # or EFFECTCRAFT_CONTROL_PORT=9877 The port must be a number from 1 to 65535, and `--control` overrides the variable. A bad port or an unknown option prints an error and the app exits with status 1 before it opens a window. +An app started with a control port is meant to be driven by an agent, so a normal launch does not +wait for a person: the window opens without taking keyboard focus, and the app skips crash recovery, +the Home screen (unless `--home` is given) and the startup update check. Help ▸ Check for Updates +still works. One exception: when the window cannot start at all, the app writes the error to +standard error and the session log and then shows it in a message box, and it exits only after +someone closes that box. + - **Transport:** TCP on `127.0.0.1` only, one JSON object per line in each direction. Connections are persistent; requests on one connection are answered in order. - **Request:** `{"id": 1, "method": "engine.execute", "params": {...}}` (`id` is echoed back, `params`